Initial check in for pnginfo, command line program for displaying info about PNG image files

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7271 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Matthew Wilber
2004-04-21 00:05:21 +00:00
parent 822757438d
commit 1c47da1361
2 changed files with 245 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
SubDir OBOS_TOP src tools translation pnginfo ;
UseLibraryHeaders zlib ;
UseLibraryHeaders png ;
BinCommand pnginfo : pnginfo.cpp : be libpng.a libz.a ;
+238
View File
@@ -0,0 +1,238 @@
/*****************************************************************************/
// pnginfo
// Written by Michael Wilber, OBOS Translation Kit Team
//
// Version:
//
// pnginfo is a command line program for displaying text information about
// PNG images.
//
// This application and all source files used in its construction, except
// where noted, are licensed under the MIT License, and have been written
// and are:
//
// Copyright (c) 2004 OpenBeOS Project
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <png.h>
#include <ByteOrder.h>
#include <File.h>
#include <TranslatorFormats.h>
#include <StorageDefs.h>
/* The png_jmpbuf() macro, used in error handling, became available in
* libpng version 1.0.6. If you want to be able to run your code with older
* versions of libpng, you must define the macro yourself (but only if it
* is not already defined by libpng!).
*/
#ifndef png_jmpbuf
# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
#endif
//// libpng Callback functions!
BPositionIO *
get_pio(png_structp ppng)
{
BPositionIO *pio = NULL;
pio = static_cast<BPositionIO *>(png_get_io_ptr(ppng));
return pio;
}
void
pngcb_read_data(png_structp ppng, png_bytep pdata, png_size_t length)
{
BPositionIO *pio = get_pio(ppng);
pio->Read(pdata, static_cast<size_t>(length));
}
void
pngcb_write_data(png_structp ppng, png_bytep pdata, png_size_t length)
{
BPositionIO *pio = get_pio(ppng);
pio->Write(pdata, static_cast<size_t>(length));
}
void
pngcb_flush_data(png_structp ppng)
{
// I don't think I really need to do anything here
}
//// End: libpng Callback functions
void
PrintPNGInfo(const char *path)
{
printf("\n\n--- %s ---\n", path);
BFile *pfile;
pfile = new BFile(path, B_READ_ONLY);
if (!pfile || pfile->InitCheck() != B_OK) {
printf("Error: unable to open the file\n");
return;
}
BPositionIO *pio = static_cast<BPositionIO *>(pfile);
const int32 kSigSize = 8;
uint8 buf[kSigSize];
if (pio->Read(buf, kSigSize) != kSigSize) {
printf("Error: unable to read PNG signature\n");
return;
}
if (!png_check_sig(buf, kSigSize)) {
// if first 8 bytes of stream don't match PNG signature bail
printf("File doesn't begin with PNG signature\n");
return;
}
// use libpng to get info about the file
png_structp ppng = NULL;
png_infop pinfo = NULL;
while (ppng == NULL) {
// create PNG read pointer with default error handling routines
ppng = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!ppng)
break;
// alocate / init memory for image information
pinfo = png_create_info_struct(ppng);
if (!pinfo)
break;
// set error handling
if (setjmp(png_jmpbuf(ppng)))
// When an error occurs in libpng, it uses
// the longjmp function to continue execution
// from this point
break;
// set read callback function
png_set_read_fn(ppng, static_cast<void *>(pio), pngcb_read_data);
// Read in PNG image info
png_set_sig_bytes(ppng, 8);
png_read_info(ppng, pinfo);
png_uint_32 width, height;
int bit_depth, color_type, interlace_type, compression_type, filter_type;
png_get_IHDR(ppng, pinfo, &width, &height, &bit_depth, &color_type,
&interlace_type, &compression_type, &filter_type);
printf(" width: %u\n", width);
printf(" height: %u\n", height);
printf(" row bytes: %u\n", pinfo->rowbytes);
printf("bit depth (bits/channel): %d\n", bit_depth);
printf(" channels: %d\n", pinfo->channels);
printf("pixel depth (bits/pixel): %d\n", pinfo->pixel_depth);
printf(" color type: ");
const char *desc = NULL;
switch (color_type) {
case PNG_COLOR_TYPE_GRAY:
desc = "Grayscale";
break;
case PNG_COLOR_TYPE_PALETTE:
desc = "Palette";
break;
case PNG_COLOR_TYPE_RGB:
desc = "RGB";
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
desc = "RGB + Alpha";
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
desc = "Grayscale + Alpha";
break;
default:
desc = "Unknown";
break;
}
printf("%s (%d)\n", desc, color_type);
printf(" interlacing: ");
switch (interlace_type) {
case PNG_INTERLACE_NONE:
desc = "None";
break;
case PNG_INTERLACE_ADAM7:
desc = "Adam7";
break;
default:
desc = "Unknown";
break;
}
printf("%s (%d)\n", desc, interlace_type);
printf(" compression type: ");
switch (compression_type) {
case PNG_COMPRESSION_TYPE_DEFAULT:
desc = "Default: Deflate method 8, 32K window";
break;
default:
desc = "Unknown";
break;
}
printf("%s (%d)\n", desc, compression_type);
printf(" filter type: ");
switch (filter_type) {
case PNG_FILTER_TYPE_DEFAULT:
desc = "Single row per-byte";
break;
case PNG_INTRAPIXEL_DIFFERENCING:
desc = "Intrapixel Differencing [for MNG files]";
break;
default:
desc = "Unknown";
break;
}
printf("%s (%d)\n", desc, filter_type);
}
if (ppng) {
// free PNG handle / info structures
if (!pinfo)
png_destroy_read_struct(&ppng, png_infopp_NULL, png_infopp_NULL);
else
png_destroy_read_struct(&ppng, &pinfo, png_infopp_NULL);
}
delete pfile;
pfile = NULL;
}
int
main(int argc, char **argv)
{
if (argc == 1) {
printf("\npnginfo - reports information about PNG images\n");
printf("\nUsage:\n");
printf("pnginfo [options] filename.png\n\n");
}
else {
int32 first = 1;
for (int32 i = first; i < argc; i++)
PrintPNGInfo(argv[i]);
}
printf("\n");
return 0;
}