rpng-win.c revision 671242f350d172e106580348e24bab66b0d7e6a5
2271N/A/*--------------------------------------------------------------------------- 2271N/A This program decodes and displays PNG images, with gamma correction and 2271N/A optionally with a user-specified background color (in case the image has 2271N/A transparency). It is very nearly the most basic PNG viewer possible. 2271N/A This version is for 32-bit Windows; it may compile under 16-bit Windows 2271N/A with a little tweaking (or maybe not). 2271N/A - handle quoted command-line args (especially filenames with spaces) 2271N/A - have minimum window width: oh well 2271N/A - use %.1023s to simplify truncation of title-bar string? 2271N/A --------------------------------------------------------------------------- 2271N/A - 1.00: initial public release 4070N/A match; switched to png_jmpbuf() macro 4070N/A - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed 2271N/A - 1.10: enabled "message window"/console (thanks to David Geldreich) 2271N/A --------------------------------------------------------------------------- 2271N/A Copyright (c) 1998-2001 Greg Roelofs. All rights reserved. 2271N/A This software is provided "as is," without warranty of any kind, 2271N/A express or implied. In no event shall the author or contributors 2271N/A be held liable for any damages arising in any way from the use of 4070N/A Permission is granted to anyone to use this software for any purpose, 2271N/A including commercial applications, and to alter it and redistribute 2271N/A it freely, subject to the following restrictions: 3661N/A 1. Redistributions of source code must retain the above copyright 3996N/A notice, disclaimer, and this list of conditions. 3996N/A 2. Redistributions in binary form must reproduce the above copyright 3996N/A notice, disclaimer, and this list of conditions in the documenta- 2271N/A tion and/or other materials provided with the distribution. 4070N/A 3. All advertising materials mentioning features or use of this 4070N/A software must display the following acknowledgment: 2271N/A This product includes software developed by Greg Roelofs 2271N/A and contributors for the book, "PNG: The Definitive Guide," 2271N/A published by O'Reilly and Associates. 2271N/A ---------------------------------------------------------------------------*/ #
include <
conio.h>
/* only for _getch() *//* #define DEBUG : this enables the Trace() macros */ #
include "readpng.h" /* typedefs, common macros, readpng prototypes *//* could just include png.h, but this macro is the only thing we need * (name and typedefs changed to local versions); note that side effects * only happen with alpha (which could easily be avoided with * "ush acopy = (alpha);") */ /* Windows-specific variables */ char *
args[
1024];
/* arbitrary limit, but should suffice */ /* First reenable console output, which normally goes to the bit bucket * for windowed apps. Closing the console window will terminate the * app. Thanks to David.Geldreich@realviz.com for supplying the magical /* Next set the default value for our display-system exponent, i.e., * the product of the CRT exponent and the exponent corresponding to * the frame-buffer's lookup table (LUT), if any. This is not an * exhaustive list of LUT values (e.g., OpenStep has a lot of weird * ones), but it should cover 99% of the current possibilities. And * yes, these ifdefs are completely wasted in a Windows program... */ if (some_next_function_that_returns_gamma(&next_gamma)) LUT_exponent = 1.0 / next_gamma; /* there doesn't seem to be any documented function to get the * "gamma" value, so we do it the hard way */ if (some_mac_function_that_returns_gamma(&mac_gamma)) LUT_exponent = mac_gamma / 2.61; /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ /* If the user has set the SCREEN_GAMMA environment variable as suggested * (somewhat imprecisely) in the libpng documentation, use that; otherwise * use the default value we just calculated. Either way, the user may * override this via a command-line option. */ /* Windows really hates command lines, so we have to set up our own argv. * Note that we do NOT bother with quoted arguments here, so don't use * filenames with spaces in 'em! */ /* now p points at the first non-space after some spaces */ break;
/* nothing after the spaces: done */ /* now q points at a space or the end of the string */ break;
/* last argv already terminated; quit */ *q =
'\0';
/* change space to terminator */ /* Now parse the command line for options and the PNG filename. */ if (
argv[
1])
/* shouldn't be any more args after filename */ ++
error;
/* not expecting any other options */ ": [%s] is not a PNG file: incorrect signature\n",
": [%s] has bad IHDR (libpng longjmp)\n",
": unknown readpng_init() error\n");
"Usage: %s [-gamma exp] [-bgcolor bg] file.png\n" " exp \ttransfer-function exponent (``gamma'') of the display\n" "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" "\t\t to the product of the lookup-table exponent (varies)\n" "\t\t and the CRT exponent (usually 2.2); must be positive\n" " bg \tdesired background color in 7-character hex RGB format\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t used with transparent images\n" "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" "Press Q or Esc to quit this usage screen.\n" while (
ch !=
'q' &&
ch !=
'Q' &&
ch !=
0x1B);
"\n [console window: closing this window will terminate %s]\n\n",
/* set the title-bar string, but make sure buffer doesn't overflow */ /* if the user didn't specify a background color on the command line, * check for one in the PNG file--if not, the initialized values of 0 * (black) will be used */ ": libpng error while checking for background color\n");
/* do the basic Windows initialization stuff, make the window and fill it * with the background color */ /* decode the image, all at once */ /* done with PNG file, so clean up to minimize memory usage (but do NOT /* display image (composite with background if requested) */ Trace((
stderr,
"done with rpng_win_display_image()\n"))
/* wait for the user to tell us when to quit */ "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
/* OK, we're done: clean up all image and Windows resources and go away */ /*--------------------------------------------------------------------------- Allocate memory for the display-specific version of the image (round up to multiple of 4 for Windows DIB). ---------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- Initialize the DIB. Negative height means to use top-down BMP ordering (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values directly => wimage_data begins immediately after BMP header. ---------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- Fill in background color (black by default); data are in BGR order. ---------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- Set the window parameters. ---------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- Finally, create the window. ---------------------------------------------------------------------------*/ }
/* end function rpng_win_create_window() */ Trace((
stderr,
"beginning display loop (image_channels == %d)\n",
Trace((
stderr,
"(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n",
/*--------------------------------------------------------------------------- Blast image data to buffer. This whole routine takes place before the message loop begins, so there's no real point in any pseudo-progressive ---------------------------------------------------------------------------*/ *
dest++ = g;
/* note reverse order */ }
else /* if (image_channels == 4) */ {
/* this macro (copied from png.h) composites the * foreground and background values and puts the * result into the first argument; there are no * side effects with the first argument */ /* display after every 16 lines */ if (((
row+
1) &
0xf) == 0) {
last param determines whether or not background is wiped before paint InvalidateRect(global_hwnd, NULL, TRUE); UpdateWindow(global_hwnd); /* one-time processing here, if any */ /* wait for the user to tell us when to quit */ switch (
wP) {
/* only need one, so ignore repeat count */