1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rpng - simple PNG display program rpng-win.c 4893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This program decodes and displays PNG images, with gamma correction and 6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project optionally with a user-specified background color (in case the image has 7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project transparency). It is very nearly the most basic PNG viewer possible. 8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This version is for 32-bit Windows; it may compile under 16-bit Windows 9893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project with a little tweaking (or maybe not). 10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project to do: 12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - handle quoted command-line args (especially filenames with spaces) 13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - have minimum window width: oh well 14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - use %.1023s to simplify truncation of title-bar string? 15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project --------------------------------------------------------------------------- 17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Changelog: 19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - 1.00: initial public release 20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - 1.01: modified to allow abbreviated options; fixed long/ulong mis- 21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project match; switched to png_jmpbuf() macro 22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed 23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project command-line parsing bug 24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - 1.10: enabled "message window"/console (thanks to David Geldreich) 25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - 2.00: dual-licensed (added GNU GPL) 26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project - 2.01: fixed improper display of usage screen on PNG error(s) 27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project --------------------------------------------------------------------------- 29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. 31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This software is provided "as is," without warranty of any kind, 33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project express or implied. In no event shall the author or contributors 34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project be held liable for any damages arising in any way from the use of 35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project this software. 36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project The contents of this file are DUAL-LICENSED. You may modify and/or 38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project redistribute this software according to the terms of one of the 39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project following two licenses (at your option): 40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LICENSE 1 ("BSD-like with advertising clause"): 43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Permission is granted to anyone to use this software for any purpose, 45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project including commercial applications, and to alter it and redistribute 46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project it freely, subject to the following restrictions: 47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1. Redistributions of source code must retain the above copyright 49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project notice, disclaimer, and this list of conditions. 50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2. Redistributions in binary form must reproduce the above copyright 51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project notice, disclaimer, and this list of conditions in the documenta- 52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project tion and/or other materials provided with the distribution. 53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3. All advertising materials mentioning features or use of this 54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project software must display the following acknowledgment: 55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This product includes software developed by Greg Roelofs 57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project and contributors for the book, "PNG: The Definitive Guide," 58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project published by O'Reilly and Associates. 59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LICENSE 2 (GNU GPL v2 or later): 62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This program is free software; you can redistribute it and/or modify 64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project it under the terms of the GNU General Public License as published by 65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project the Free Software Foundation; either version 2 of the License, or 66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (at your option) any later version. 67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This program is distributed in the hope that it will be useful, 69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project but WITHOUT ANY WARRANTY; without even the implied warranty of 70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project GNU General Public License for more details. 72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project You should have received a copy of the GNU General Public License 74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project along with this program; if not, write to the Free Software Foundation, 75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PROGNAME "rpng-win" 80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define LONGNAME "Simple PNG Viewer for Windows" 81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define VERSION "2.01 of 16 March 2008" 82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdio.h> 84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdlib.h> 85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <string.h> 86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <time.h> 87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <windows.h> 88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <conio.h> /* only for _getch() */ 89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* #define DEBUG : this enables the Trace() macros */ 91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "readpng.h" /* typedefs, common macros, readpng prototypes */ 93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* could just include png.h, but this macro is the only thing we need 96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (name and typedefs changed to local versions); note that side effects 97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * only happen with alpha (which could easily be avoided with 98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "ush acopy = (alpha);") */ 99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define alpha_composite(composite, fg, alpha, bg) { \ 101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ush temp = ((ush)(fg)*(ush)(alpha) + \ 102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ 103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (composite) = (uch)((temp + (temp >> 8)) >> 8); \ 104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* local prototypes */ 108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng_win_create_window(HINSTANCE hInst, int showmode); 109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng_win_display_image(void); 110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng_win_cleanup(void); 111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectLRESULT CALLBACK rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM); 112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char titlebar[1024]; 115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *progname = PROGNAME; 116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *appname = LONGNAME; 117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *filename; 118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic FILE *infile; 119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *bgstr; 121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch bg_red=0, bg_green=0, bg_blue=0; 122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic double display_exponent; 124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg image_width, image_height, image_rowbytes; 126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int image_channels; 127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *image_data; 128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Windows-specific variables */ 130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg wimage_rowbytes; 131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *dib; 132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *wimage_data; 133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic BITMAPINFOHEADER *bmih; 134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic HWND global_hwnd; 136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) 141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project char *args[1024]; /* arbitrary limit, but should suffice */ 143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project char *p, *q, **argv = args; 144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int argc = 0; 145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int rc, alen, flen; 146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int error = 0; 147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int have_bg = FALSE; 148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project double LUT_exponent; /* just the lookup table */ 149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project double CRT_exponent = 2.2; /* just the monitor */ 150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project double default_display_exponent; /* whole display system */ 151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project MSG msg; 152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project filename = (char *)NULL; 155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* First reenable console output, which normally goes to the bit bucket 158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * for windowed apps. Closing the console window will terminate the 159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * app. Thanks to David.Geldreich@realviz.com for supplying the magical 160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * incantation. */ 161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project AllocConsole(); 163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project freopen("CONOUT$", "a", stderr); 164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project freopen("CONOUT$", "a", stdout); 165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Next set the default value for our display-system exponent, i.e., 168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the product of the CRT exponent and the exponent corresponding to 169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the frame-buffer's lookup table (LUT), if any. This is not an 170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * exhaustive list of LUT values (e.g., OpenStep has a lot of weird 171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * ones), but it should cover 99% of the current possibilities. And 172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * yes, these ifdefs are completely wasted in a Windows program... */ 173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(NeXT) 175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LUT_exponent = 1.0 / 2.2; 176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* 177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (some_next_function_that_returns_gamma(&next_gamma)) 178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LUT_exponent = 1.0 / next_gamma; 179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(sgi) 181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LUT_exponent = 1.0 / 1.7; 182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* there doesn't seem to be any documented function to get the 183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "gamma" value, so we do it the hard way */ 184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project infile = fopen("/etc/config/system.glGammaVal", "r"); 185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (infile) { 186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project double sgi_gamma; 187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fgets(tmpline, 80, infile); 189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose(infile); 190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sgi_gamma = atof(tmpline); 191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (sgi_gamma > 0.0) 192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LUT_exponent = 1.0 / sgi_gamma; 193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(Macintosh) 195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LUT_exponent = 1.8 / 2.61; 196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* 197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (some_mac_function_that_returns_gamma(&mac_gamma)) 198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LUT_exponent = mac_gamma / 2.61; 199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LUT_exponent = 1.0; /* assume no LUT: most PCs */ 202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ 205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default_display_exponent = LUT_exponent * CRT_exponent; 206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* If the user has set the SCREEN_GAMMA environment variable as suggested 209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (somewhat imprecisely) in the libpng documentation, use that; otherwise 210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * use the default value we just calculated. Either way, the user may 211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * override this via a command-line option. */ 212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((p = getenv("SCREEN_GAMMA")) != NULL) 214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project display_exponent = atof(p); 215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project display_exponent = default_display_exponent; 217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Windows really hates command lines, so we have to set up our own argv. 220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * Note that we do NOT bother with quoted arguments here, so don't use 221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * filenames with spaces in 'em! */ 222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project argv[argc++] = PROGNAME; 224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = cmd; 225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (;;) { 226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*p == ' ') 227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (*++p == ' ') 228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ; 229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* now p points at the first non-space after some spaces */ 230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*p == '\0') 231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; /* nothing after the spaces: done */ 232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project argv[argc++] = q = p; 233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (*q && *q != ' ') 234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++q; 235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* now q points at a space or the end of the string */ 236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*q == '\0') 237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; /* last argv already terminated; quit */ 238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *q = '\0'; /* change space to terminator */ 239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = q + 1; 240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project argv[argc] = NULL; /* terminate the argv array itself */ 242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Now parse the command line for options and the PNG filename. */ 245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (*++argv && !error) { 247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!strncmp(*argv, "-gamma", 2)) { 248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!*++argv) 249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else { 251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project display_exponent = atof(*argv); 252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (display_exponent <= 0.0) 253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else if (!strncmp(*argv, "-bgcolor", 2)) { 256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!*++argv) 257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else { 259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bgstr = *argv; 260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (strlen(bgstr) != 7 || bgstr[0] != '#') 261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project have_bg = TRUE; 264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else { 266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (**argv != '-') { 267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project filename = *argv; 268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (argv[1]) /* shouldn't be any more args after filename */ 269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else 271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; /* not expecting any other options */ 272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!filename) 276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* print usage screen if any errors up to this point */ 280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (error) { 282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ch; 283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); 285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project readpng_version_info(); 286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, "\n" 287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Usage: %s [-gamma exp] [-bgcolor bg] file.png\n" 288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project " exp \ttransfer-function exponent (``gamma'') of the display\n" 289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" 290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\t\t to the product of the lookup-table exponent (varies)\n" 291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\t\t and the CRT exponent (usually 2.2); must be positive\n" 292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project " bg \tdesired background color in 7-character hex RGB format\n" 293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" 294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\t\t used with transparent images\n" 295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" 296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Press Q or Esc to quit this usage screen.\n" 297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\n", PROGNAME, default_display_exponent); 298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ch = _getch(); 300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (ch != 'q' && ch != 'Q' && ch != 0x1B); 301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project exit(1); 302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(infile = fopen(filename, "rb"))) { 306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); 307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else { 309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) { 310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (rc) { 311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME 313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ": [%s] is not a PNG file: incorrect signature\n", 314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project filename); 315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME 318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ": [%s] has bad IHDR (libpng longjmp)\n", filename); 319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME ": insufficient memory\n"); 322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME 325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ": unknown readpng_init() error\n"); 326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++error; 329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (error) 331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose(infile); 332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (error) { 336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ch; 337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME ": aborting.\n"); 339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ch = _getch(); 341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (ch != 'q' && ch != 'Q' && ch != 0x1B); 342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project exit(2); 343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else { 344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); 345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, 346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "\n [console window: closing this window will terminate %s]\n\n", 347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PROGNAME); 348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* set the title-bar string, but make sure buffer doesn't overflow */ 352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project alen = strlen(appname); 354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project flen = strlen(filename); 355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (alen + flen + 3 > 1023) 356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); 357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sprintf(titlebar, "%s: %s", appname, filename); 359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* if the user didn't specify a background color on the command line, 362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * check for one in the PNG file--if not, the initialized values of 0 363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (black) will be used */ 364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (have_bg) { 366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project unsigned r, g, b; /* this approach quiets compiler warnings */ 367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); 369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bg_red = (uch)r; 370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bg_green = (uch)g; 371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bg_blue = (uch)b; 372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) { 373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project readpng_cleanup(TRUE); 374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME 375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ": libpng error while checking for background color\n"); 376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project exit(2); 377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* do the basic Windows initialization stuff, make the window and fill it 381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * with the background color */ 382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (rpng_win_create_window(hInst, showmode)) 384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project exit(2); 385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* decode the image, all at once */ 388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Trace((stderr, "calling readpng_get_image()\n")) 390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project image_data = readpng_get_image(display_exponent, &image_channels, 391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project &image_rowbytes); 392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Trace((stderr, "done with readpng_get_image()\n")) 393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* done with PNG file, so clean up to minimize memory usage (but do NOT 396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * nuke image_data!) */ 397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project readpng_cleanup(FALSE); 399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose(infile); 400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!image_data) { 402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, PROGNAME ": unable to decode PNG image\n"); 403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project exit(3); 404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* display image (composite with background if requested) */ 408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Trace((stderr, "calling rpng_win_display_image()\n")) 410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (rpng_win_display_image()) { 411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free(image_data); 412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project exit(4); 413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Trace((stderr, "done with rpng_win_display_image()\n")) 415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* wait for the user to tell us when to quit */ 418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project printf( 420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); 421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fflush(stdout); 422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (GetMessage(&msg, NULL, 0, 0)) { 424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project TranslateMessage(&msg); 425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project DispatchMessage(&msg); 426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* OK, we're done: clean up all image and Windows resources and go away */ 430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rpng_win_cleanup(); 432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return msg.wParam; 434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng_win_create_window(HINSTANCE hInst, int showmode) 441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project uch *dest; 443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int extra_width, extra_height; 444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ulg i, j; 445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project WNDCLASSEX wndclass; 446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Allocate memory for the display-specific version of the image (round up 450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project to multiple of 4 for Windows DIB). 451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2; 454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + 456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wimage_rowbytes*image_height))) 457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 4; /* fail */ 459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Initialize the DIB. Negative height means to use top-down BMP ordering 463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values 465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project directly => wimage_data begins immediately after BMP header. 466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project memset(dib, 0, sizeof(BITMAPINFOHEADER)); 469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bmih = (BITMAPINFOHEADER *)dib; 470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bmih->biSize = sizeof(BITMAPINFOHEADER); 471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bmih->biWidth = image_width; 472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bmih->biHeight = -((long)image_height); 473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bmih->biPlanes = 1; 474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bmih->biBitCount = 24; 475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bmih->biCompression = 0; 476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wimage_data = dib + sizeof(BITMAPINFOHEADER); 477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Fill in background color (black by default); data are in BGR order. 480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = 0; j < image_height; ++j) { 483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dest = wimage_data + j*wimage_rowbytes; 484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = image_width; i > 0; --i) { 485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = bg_blue; 486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = bg_green; 487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = bg_red; 488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Set the window parameters. 493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project memset(&wndclass, 0, sizeof(wndclass)); 496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.cbSize = sizeof(wndclass); 498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.style = CS_HREDRAW | CS_VREDRAW; 499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.lpfnWndProc = rpng_win_wndproc; 500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.hInstance = hInst; 501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); 504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.lpszMenuName = NULL; 505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.lpszClassName = progname; 506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project RegisterClassEx(&wndclass); 509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Finally, create the window. 512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project extra_width = 2*(GetSystemMetrics(SM_CXBORDER) + 515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project GetSystemMetrics(SM_CXDLGFRAME)); 516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project extra_height = 2*(GetSystemMetrics(SM_CYBORDER) + 517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project GetSystemMetrics(SM_CYDLGFRAME)) + 518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project GetSystemMetrics(SM_CYCAPTION); 519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW, 521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width, 522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project image_height+extra_height, NULL, NULL, hInst, NULL); 523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ShowWindow(global_hwnd, showmode); 525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project UpdateWindow(global_hwnd); 526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng_win_create_window() */ 530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng_win_display_image() 536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project uch *src, *dest; 538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project uch r, g, b, a; 539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ulg i, row, lastrow; 540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project RECT rect; 541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Trace((stderr, "beginning display loop (image_channels == %d)\n", 544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project image_channels)) 545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Trace((stderr, "(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n", 546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project image_width, image_rowbytes, wimage_rowbytes)) 547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Blast image data to buffer. This whole routine takes place before the 551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project message loop begins, so there's no real point in any pseudo-progressive 552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project display... 553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (lastrow = row = 0; row < image_height; ++row) { 556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project src = image_data + row*image_rowbytes; 557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dest = wimage_data + row*wimage_rowbytes; 558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (image_channels == 3) { 559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = image_width; i > 0; --i) { 560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project r = *src++; 561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = *src++; 562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project b = *src++; 563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = b; 564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = g; /* note reverse order */ 565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = r; 566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else /* if (image_channels == 4) */ { 568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = image_width; i > 0; --i) { 569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project r = *src++; 570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project g = *src++; 571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project b = *src++; 572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project a = *src++; 573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (a == 255) { 574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = b; 575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = g; 576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = r; 577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else if (a == 0) { 578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = bg_blue; 579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = bg_green; 580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dest++ = bg_red; 581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } else { 582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* this macro (copied from png.h) composites the 583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * foreground and background values and puts the 584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * result into the first argument; there are no 585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * side effects with the first argument */ 586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project alpha_composite(*dest++, b, a, bg_blue); 587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project alpha_composite(*dest++, g, a, bg_green); 588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project alpha_composite(*dest++, r, a, bg_red); 589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* display after every 16 lines */ 593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (((row+1) & 0xf) == 0) { 594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.left = 0L; 595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.top = (LONG)lastrow; 596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.right = (LONG)image_width; /* possibly off by one? */ 597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.bottom = (LONG)lastrow + 16L; /* possibly off by one? */ 598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project InvalidateRect(global_hwnd, &rect, FALSE); 599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project UpdateWindow(global_hwnd); /* similar to XFlush() */ 600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project lastrow = row + 1; 601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Trace((stderr, "calling final image-flush routine\n")) 605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (lastrow < image_height) { 606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.left = 0L; 607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.top = (LONG)lastrow; 608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.right = (LONG)image_width; /* possibly off by one? */ 609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rect.bottom = (LONG)image_height; /* possibly off by one? */ 610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project InvalidateRect(global_hwnd, &rect, FALSE); 611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project UpdateWindow(global_hwnd); /* similar to XFlush() */ 612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* 615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project last param determines whether or not background is wiped before paint 616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project InvalidateRect(global_hwnd, NULL, TRUE); 617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project UpdateWindow(global_hwnd); 618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng_win_cleanup() 628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (image_data) { 630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free(image_data); 631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project image_data = NULL; 632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (dib) { 635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free(dib); 636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dib = NULL; 637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectLRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP) 645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project HDC hdc; 647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PAINTSTRUCT ps; 648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int rc; 649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (iMsg) { 651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case WM_CREATE: 652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* one-time processing here, if any */ 653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case WM_PAINT: 656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project hdc = BeginPaint(hwnd, &ps); 657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* dest */ 658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rc = StretchDIBits(hdc, 0, 0, image_width, image_height, 659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* source */ 660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 0, 0, image_width, image_height, 661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wimage_data, (BITMAPINFO *)bmih, 662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* iUsage: no clue */ 663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 0, SRCCOPY); 664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project EndPaint(hwnd, &ps); 665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* wait for the user to tell us when to quit */ 668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case WM_CHAR: 669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (wP) { /* only need one, so ignore repeat count */ 670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 'q': 671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 'Q': 672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 0x1B: /* Esc key */ 673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PostQuitMessage(0); 674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case WM_LBUTTONDOWN: /* another way of quitting */ 678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case WM_DESTROY: 679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PostQuitMessage(0); 680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return DefWindowProc(hwnd, iMsg, wP, lP); 684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 685