diff --git a/src/tools/translation/pnginfo/Jamfile b/src/tools/translation/pnginfo/Jamfile new file mode 100644 index 0000000000..80ea902204 --- /dev/null +++ b/src/tools/translation/pnginfo/Jamfile @@ -0,0 +1,7 @@ +SubDir OBOS_TOP src tools translation pnginfo ; + +UseLibraryHeaders zlib ; +UseLibraryHeaders png ; + +BinCommand pnginfo : pnginfo.cpp : be libpng.a libz.a ; + diff --git a/src/tools/translation/pnginfo/pnginfo.cpp b/src/tools/translation/pnginfo/pnginfo.cpp new file mode 100644 index 0000000000..4b37b8017e --- /dev/null +++ b/src/tools/translation/pnginfo/pnginfo.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include + + /* 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(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(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(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(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(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; +} +