1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   rpng2 - progressive-model PNG display program                rpng2-win.c
4893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   This program decodes and displays PNG files progressively, as if it were
6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   a web browser (though the front end is only set up to read from files).
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   It supports gamma correction, user-specified background colors, and user-
8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   specified background patterns (for transparent images).  This version is
9893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for 32-bit Windows; it may compile under 16-bit Windows with a little
10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   tweaking (or maybe not).  Thanks to Adam Costello and Pieter S. van der
11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   Meulen for the "diamond" and "radial waves" patterns, respectively.
12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   to do (someday, maybe):
14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - handle quoted command-line args (especially filenames with spaces)
15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - finish resizable checkerboard-gradient (sizes 4-128?)
16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - use %.1023s to simplify truncation of title-bar string?
17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - have minimum window width:  oh well
18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------
20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   Changelog:
22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.01:  initial public release
23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.02:  fixed cut-and-paste error in usage screen (oops...)
24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.03:  modified to allow abbreviated options
25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.04:  removed bogus extra argument from usage fprintf() [Glenn R-P?];
26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              fixed command-line parsing bug
27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.10:  enabled "message window"/console (thanks to David Geldreich)
28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.20:  added runtime MMX-enabling/disabling and new -mmx* options
29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.21:  made minor tweak to usage screen to fit within 25-line console
30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.22:  added AMD64/EM64T support (__x86_64__)
31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.00:  dual-licensed (added GNU GPL)
32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.01:  fixed 64-bit typo in readpng2.c
33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.02:  fixed improper display of usage screen on PNG error(s); fixed
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              unexpected-EOF and file-read-error cases
35ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    - 2.03:  removed runtime MMX-enabling/disabling and obsolete -mmx* options
3606f1087a94f1e48298e89d77ccc51a0ced871958Matt Sarett    - 2.04:
379b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett             (GR-P)
38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.
42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This software is provided "as is," without warranty of any kind,
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      express or implied.  In no event shall the author or contributors
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      be held liable for any damages arising in any way from the use of
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      this software.
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      The contents of this file are DUAL-LICENSED.  You may modify and/or
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      redistribute this software according to the terms of one of the
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      following two licenses (at your option):
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      LICENSE 1 ("BSD-like with advertising clause"):
54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Permission is granted to anyone to use this software for any purpose,
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      including commercial applications, and to alter it and redistribute
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      it freely, subject to the following restrictions:
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      1. Redistributions of source code must retain the above copyright
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         notice, disclaimer, and this list of conditions.
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      2. Redistributions in binary form must reproduce the above copyright
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         notice, disclaimer, and this list of conditions in the documenta-
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         tion and/or other materials provided with the distribution.
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      3. All advertising materials mentioning features or use of this
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         software must display the following acknowledgment:
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            This product includes software developed by Greg Roelofs
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            and contributors for the book, "PNG: The Definitive Guide,"
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            published by O'Reilly and Associates.
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      LICENSE 2 (GNU GPL v2 or later):
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This program is free software; you can redistribute it and/or modify
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      it under the terms of the GNU General Public License as published by
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      the Free Software Foundation; either version 2 of the License, or
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (at your option) any later version.
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This program is distributed in the hope that it will be useful,
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      but WITHOUT ANY WARRANTY; without even the implied warranty of
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      GNU General Public License for more details.
83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      You should have received a copy of the GNU General Public License
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      along with this program; if not, write to the Free Software Foundation,
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PROGNAME  "rpng2-win"
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define LONGNAME  "Progressive PNG Viewer for Windows"
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define VERSION   "2.02 of 16 March 2008"
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdio.h>
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdlib.h>
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <string.h>
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <setjmp.h>    /* for jmpbuf declaration in readpng2.h */
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <time.h>
99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <math.h>      /* only for PvdM background code */
100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <windows.h>
101ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifdef __CYGWIN__
102ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik/* getch replacement. Turns out, we don't really need this,
103ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * but leave it here if we ever enable any of the uses of
104ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * _getch in the main code
105ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik */
106ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#include <unistd.h>
107ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#include <termio.h>
108ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#include <sys/ioctl.h>
109ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craikint repl_getch( void )
110ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik{
111ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  char ch;
112ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  int fd = fileno(stdin);
113ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  struct termio old_tty, new_tty;
114ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik
115ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  ioctl(fd, TCGETA, &old_tty);
116ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  new_tty = old_tty;
117ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  new_tty.c_lflag &= ~(ICANON | ECHO | ISIG);
118ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  ioctl(fd, TCSETA, &new_tty);
119ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  fread(&ch, 1, sizeof(ch), stdin);
120ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  ioctl(fd, TCSETA, &old_tty);
121ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik
122ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  return ch;
123ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik}
124ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#define _getch repl_getch
125ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#else
126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <conio.h>     /* only for _getch() */
127ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* all for PvdM background code: */
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef PI
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  define PI             3.141592653589793238
132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PI_2             (PI*0.5)
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define INV_PI_360       (360.0 / PI)
135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define MAX(a,b)         (a>b?a:b)
136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define MIN(a,b)         (a<b?a:b)
137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define CLIP(a,min,max)  MAX(min,MIN((a),max))
138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define ABS(a)           ((a)<0?-(a):(a))
139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define CLIP8P(c)        MAX(0,(MIN((c),255)))   /* 8-bit pos. integer (uch) */
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define ROUNDF(f)        ((int)(f + 0.5))
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb1_max   bg_freq
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb1_min   bg_gray
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb2_max   bg_bsat
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb2_min   bg_brot
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* #define DEBUG */     /* this enables the Trace() macros */
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "readpng2.h"   /* typedefs, common macros, readpng2 prototypes */
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* could just include png.h, but this macro is the only thing we need
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (name and typedefs changed to local versions); note that side effects
154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * only happen with alpha (which could easily be avoided with
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "ush acopy = (alpha);") */
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define alpha_composite(composite, fg, alpha, bg) {               \
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ush temp = ((ush)(fg)*(ush)(alpha) +                          \
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define INBUFSIZE 4096   /* with pseudo-timing on (1 sec delay/block), this
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  block size corresponds roughly to a download
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  speed 10% faster than theoretical 33.6K maximum
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  (assuming 8 data bits, 1 stop bit and no other
168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  overhead) */
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* local prototypes */
171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void       rpng2_win_init(void);
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int        rpng2_win_create_window(void);
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int        rpng2_win_load_bg_image(void);
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void       rpng2_win_display_row(ulg row);
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void       rpng2_win_finish_display(void);
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void       rpng2_win_cleanup(void);
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectLRESULT CALLBACK  rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM);
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char titlebar[1024];
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *progname = PROGNAME;
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *appname = LONGNAME;
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *filename;
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic FILE *infile;
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic mainprog_info rpng2_info;
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch inbuf[INBUFSIZE];
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int incount;
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int pat = 6;         /* must be less than num_bgpat */
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int bg_image = 0;
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int bgscale = 16;
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg bg_rowbytes;
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *bg_data;
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic struct rgb_color {
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r, g, b;
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} rgb[] = {
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {  0,   0,   0},    /*  0:  black */
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255, 255, 255},    /*  1:  white */
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {173, 132,  57},    /*  2:  tan */
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 64, 132,   0},    /*  3:  medium green */
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {189, 117,   1},    /*  4:  gold */
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {253, 249,   1},    /*  5:  yellow */
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {  0,   0, 255},    /*  6:  blue */
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {  0,   0, 120},    /*  7:  medium blue */
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255,   0, 255},    /*  8:  magenta */
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 64,   0,  64},    /*  9:  dark magenta */
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255,   0,   0},    /* 10:  red */
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 64,   0,   0},    /* 11:  dark red */
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255, 127,   0},    /* 12:  orange */
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {192,  96,   0},    /* 13:  darker orange */
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 24,  60,   0},    /* 14:  dark green-yellow */
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 85, 125, 200}     /* 15:  ice blue */
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project};
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* not used for now, but should be for error-checking:
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    This whole struct is a fairly cheesy way to keep the number of
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    command-line options to a minimum.  The radial-waves background
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    type is a particularly poor fit to the integer elements of the
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    struct...but a few macros and a little fixed-point math will do
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wonders for ya.
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    type bits:
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       F E D C B A 9 8 7 6 5 4 3 2 1 0
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | | | | |
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | | +-+-+-- 0 = sharp-edged checkerboard
232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | |         1 = soft diamonds
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | |         2 = radial waves
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | |       3-7 = undefined
235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | +-- gradient #2 inverted?
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             +-- alternating columns inverted?
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic struct background_pattern {
239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ush type;
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rgb1_max, rgb1_min;     /* or bg_freq, bg_gray */
241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rgb2_max, rgb2_min;     /* or bg_bsat, bg_brot (both scaled by 10)*/
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} bg[] = {
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,   2,0,  1,15},        /* checkered:  tan/black vs. white/ice blue */
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+24,  2,0,  1,0},         /* checkered:  tan/black vs. white/black */
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,   4,5,  0,2},         /* checkered:  gold/yellow vs. black/tan */
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,   4,5,  0,6},         /* checkered:  gold/yellow vs. black/blue */
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0,     7,0,  8,9},         /* checkered:  deep blue/black vs. magenta */
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,  13,0,  5,14},        /* checkered:  orange/black vs. yellow */
249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,  12,0, 10,11},        /* checkered:  orange/black vs. red */
250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,     7,0,  8,0},         /* diamonds:  deep blue/black vs. magenta */
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,    12,0, 11,0},         /* diamonds:  orange vs. dark red */
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,    10,0,  7,0},         /* diamonds:  red vs. medium blue */
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,     4,0,  5,0},         /* diamonds:  gold vs. yellow */
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,     3,0,  0,0},         /* diamonds:  medium green vs. black */
255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2,    16, 100,  20,   0},  /* radial:  ~hard radial color-beams */
256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2,    18, 100,  10,   2},  /* radial:  soft, curved radial color-beams */
257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2,    16, 256, 100, 250},  /* radial:  very tight spiral */
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2, 10000, 256,  11,   0}   /* radial:  dipole-moire' (almost fractal) */
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project};
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Windows-specific global variables (could go in struct, but messy...) */
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg wimage_rowbytes;
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *dib;
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *wimage_data;
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic BITMAPINFOHEADER *bmih;
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic HWND global_hwnd;
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic HINSTANCE global_hInst;
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int global_showmode;
272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *args[1024];                 /* arbitrary limit, but should suffice */
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char **argv = args;
280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *p, *q, *bgstr = NULL;
281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int argc = 0;
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rc, alen, flen;
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int error = 0;
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int timing = FALSE;
285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int have_bg = FALSE;
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double LUT_exponent;              /* just the lookup table */
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double CRT_exponent = 2.2;        /* just the monitor */
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double default_display_exponent;  /* whole display system */
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    MSG msg;
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* First initialize a few things, just to be sure--memset takes care of
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * default background color (black), booleans (FALSE), pointers (NULL),
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * etc. */
295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    global_hInst = hInst;
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    global_showmode = showmode;
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    filename = (char *)NULL;
299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    memset(&rpng2_info, 0, sizeof(mainprog_info));
300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
301ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Next reenable console output, which normally goes to the bit bucket
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * for windowed apps.  Closing the console window will terminate the
304851c67770f9cebece9c79e914a54c348f539a512Matt Sarett     * app.  Thanks to David.Geldreich@realviz.com for supplying the magical
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * incantation. */
306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    AllocConsole();
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    freopen("CONOUT$", "a", stderr);
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    freopen("CONOUT$", "a", stdout);
310ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Set the default value for our display-system exponent, i.e., the
313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * product of the CRT exponent and the exponent corresponding to
314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the frame-buffer's lookup table (LUT), if any.  This is not an
315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * ones), but it should cover 99% of the current possibilities.  And
317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * yes, these ifdefs are completely wasted in a Windows program... */
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(NeXT)
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* third-party utilities can modify the default LUT exponent */
321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0 / 2.2;
322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (some_next_function_that_returns_gamma(&next_gamma))
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        LUT_exponent = 1.0 / next_gamma;
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(sgi)
327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0 / 1.7;
328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* there doesn't seem to be any documented function to
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * get the "gamma" value, so we do it the hard way */
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    infile = fopen("/etc/config/system.glGammaVal", "r");
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (infile) {
332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double sgi_gamma;
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fgets(tmpline, 80, infile);
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fclose(infile);
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sgi_gamma = atof(tmpline);
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (sgi_gamma > 0.0)
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            LUT_exponent = 1.0 / sgi_gamma;
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(Macintosh)
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.8 / 2.61;
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (some_mac_function_that_returns_gamma(&mac_gamma))
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        LUT_exponent = mac_gamma / 2.61;
345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */
348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    default_display_exponent = LUT_exponent * CRT_exponent;
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* If the user has set the SCREEN_GAMMA environment variable as suggested
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * (somewhat imprecisely) in the libpng documentation, use that; otherwise
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * use the default value we just calculated.  Either way, the user may
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * override this via a command-line option. */
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((p = getenv("SCREEN_GAMMA")) != NULL)
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.display_exponent = atof(p);
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.display_exponent = default_display_exponent;
363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Windows really hates command lines, so we have to set up our own argv.
366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * Note that we do NOT bother with quoted arguments here, so don't use
367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * filenames with spaces in 'em! */
368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    argv[argc++] = PROGNAME;
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    p = cmd;
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (;;) {
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (*p == ' ')
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            while (*++p == ' ')
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ;
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* now p points at the first non-space after some spaces */
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (*p == '\0')
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;    /* nothing after the spaces:  done */
378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        argv[argc++] = q = p;
379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        while (*q && *q != ' ')
380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++q;
381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* now q points at a space or the end of the string */
382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (*q == '\0')
383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;    /* last argv already terminated; quit */
384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        *q = '\0';    /* change space to terminator */
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        p = q + 1;
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    argv[argc] = NULL;   /* terminate the argv array itself */
388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Now parse the command line for options and the PNG filename. */
391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (*++argv && !error) {
393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (!strncmp(*argv, "-gamma", 2)) {
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                rpng2_info.display_exponent = atof(*argv);
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (rpng2_info.display_exponent <= 0.0)
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-bgcolor", 4)) {
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                bgstr = *argv;
406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (strlen(bgstr) != 7 || bgstr[0] != '#')
407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                else {
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    have_bg = TRUE;
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_image = FALSE;
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-bgpat", 4)) {
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pat = atoi(*argv) - 1;
418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (pat < 0 || pat >= num_bgpat)
419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                else {
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_image = TRUE;
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    have_bg = FALSE;
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-timing", 2)) {
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            timing = TRUE;
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else {
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (**argv != '-') {
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                filename = *argv;
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (argv[1])   /* shouldn't be any more args after filename */
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else
433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;   /* not expecting any other options */
434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!filename)
438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ++error;
439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* print usage screen if any errors up to this point */
442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
444ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int ch;
446ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "\n%s %s:  %s\n\n", PROGNAME, VERSION, appname);
449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_version_info();
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "\n"
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "Usage:  %s [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing]\n"
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "        %*s file.png\n\n"
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    exp \ttransfer-function exponent (``gamma'') of the display\n"
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  system in floating-point format (e.g., ``%.1f''); equal\n"
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  to the product of the lookup-table exponent (varies)\n"
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    bg  \tdesired background color in 7-character hex RGB format\n"
458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\n"
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  used with transparent images; overrides -bgpat option\n"
460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    pat \tdesired background pattern number (1-%d); used with\n"
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  transparent images; overrides -bgcolor option\n"
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    -timing\tenables delay for every block read, to simulate modem\n"
463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  download of image (~36 Kbps)\n"
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
465ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "Press Q or Esc to quit this usage screen. ",
467ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#else
468ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik          ,
469ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PROGNAME,
471ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \
472ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    !(defined(__CYGWIN__) || defined(__MINGW32__))
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)strlen(PROGNAME), " ",
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat);
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
477ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        do
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ch = _getch();
480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        while (ch != 'q' && ch != 'Q' && ch != 0x1B);
481ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(1);
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!(infile = fopen(filename, "rb"))) {
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  can't open PNG file [%s]\n", filename);
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ++error;
489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        incount = fread(inbuf, 1, INBUFSIZE, infile);
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, PROGNAME
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              ":  [%s] is not a PNG file: incorrect signature\n",
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              filename);
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++error;
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if ((rc = readpng2_init(&rpng2_info)) != 0) {
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (rc) {
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 2:
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      ":  [%s] has bad IHDR (libpng longjmp)\n", filename);
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 4:
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME ":  insufficient memory\n");
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                default:
506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME
507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      ":  unknown readpng2_init() error\n");
508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++error;
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (error)
513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fclose(infile);
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
518ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int ch;
520ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  aborting.\n");
523ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        do
525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ch = _getch();
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        while (ch != 'q' && ch != 'Q' && ch != 0x1B);
527ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(2);
529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "\n%s %s:  %s\n", PROGNAME, VERSION, appname);
531ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr,
533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\n   [console window:  closing this window will terminate %s]\n\n",
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PROGNAME);
535ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* set the title-bar string, but make sure buffer doesn't overflow */
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    alen = strlen(appname);
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    flen = strlen(filename);
544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (alen + flen + 3 > 1023)
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sprintf(titlebar, "%s:  ...%s", appname, filename+(alen+flen+6-1023));
546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sprintf(titlebar, "%s:  %s", appname, filename);
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* set some final rpng2_info variables before entering main data loop */
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_bg) {
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        unsigned r, g, b;   /* this approach quiets compiler warnings */
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.bg_red   = (uch)r;
557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.bg_green = (uch)g;
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.bg_blue  = (uch)b;
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.need_bgcolor = TRUE;
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.state = kPreInit;
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.mainprog_init = rpng2_win_init;
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.mainprog_display_row = rpng2_win_display_row;
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.mainprog_finish_display = rpng2_win_finish_display;
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* OK, this is the fun part:  call readpng2_decode_data() at the start of
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the loop to deal with our first buffer of data (read in above to verify
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * that the file is a PNG image), then loop through the file and continue
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * calling the same routine to handle each chunk of data.  It in turn
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * passes the data to libpng, which will invoke one or more of our call-
573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * backs as decoded data become available.  We optionally call Sleep() for
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * one second per iteration to simulate downloading the image via an analog
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * modem. */
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (;;) {
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "about to call readpng2_decode_data()\n"))
579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (readpng2_decode_data(&rpng2_info, inbuf, incount))
580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++error;
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "done with readpng2_decode_data()\n"))
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {
584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (rpng2_info.state == kDone) {
585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                Trace((stderr, "done decoding PNG image\n"))
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else if (ferror(infile)) {
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                fprintf(stderr, PROGNAME
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  ":  error while reading PNG image file\n");
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                exit(3);
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else if (feof(infile)) {
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                fprintf(stderr, PROGNAME ":  end of file reached "
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  "(unexpectedly) while reading PNG image file\n");
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                exit(3);
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else /* if (error) */ {
595ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik                /* will print error message below */
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (timing)
601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            Sleep(1000L);
602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        incount = fread(inbuf, 1, INBUFSIZE, infile);
604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* clean up PNG stuff and report any decoding errors */
608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fclose(infile);
610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "about to call readpng2_cleanup()\n"))
611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    readpng2_cleanup(&rpng2_info);
612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  libpng error while decoding PNG image\n");
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(3);
616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* wait for the user to tell us when to quit */
620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (GetMessage(&msg, NULL, 0, 0)) {
622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        TranslateMessage(&msg);
623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        DispatchMessage(&msg);
624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* we're done:  clean up all image and Windows resources and go away */
628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "about to call rpng2_win_cleanup()\n"))
630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_win_cleanup();
631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return msg.wParam;
633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* this function is called by readpng2_info_callback() in readpng2.c, which
640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in turn is called by libpng after all of the pre-IDAT chunks have been
641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * read and processed--i.e., we now have enough info to finish initializing */
642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_win_init()
644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i;
646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg rowbytes = rpng2_info.rowbytes;
647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning rpng2_win_init()\n"))
649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "  rowbytes = %d\n", rpng2_info.rowbytes))
650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "  width  = %ld\n", rpng2_info.width))
651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "  height = %ld\n", rpng2_info.height))
652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!rpng2_info.image_data) {
655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_cleanup(&rpng2_info);
656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return;
657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));
660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!rpng2_info.row_pointers) {
661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(rpng2_info.image_data);
662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.image_data = NULL;
663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_cleanup(&rpng2_info);
664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return;
665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i = 0;  i < rpng2_info.height;  ++i)
668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;
669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Do the basic Windows initialization stuff, make the window, and fill it
672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    with the user-specified, file-specified or default background color.
673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_win_create_window()) {
676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_cleanup(&rpng2_info);
677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return;
678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.state = kWindowInit;
681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng2_win_create_window()
688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_red   = rpng2_info.bg_red;
690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_green = rpng2_info.bg_green;
691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_blue  = rpng2_info.bg_blue;
692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *dest;
693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int extra_width, extra_height;
694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i, j;
695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    WNDCLASSEX wndclass;
696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    RECT rect;
697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Allocate memory for the display-specific version of the image (round up
701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    to multiple of 4 for Windows DIB).
702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wimage_rowbytes = ((3*rpng2_info.width + 3L) >> 2) << 2;
705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                              wimage_rowbytes*rpng2_info.height)))
708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 4;   /* fail */
710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Initialize the DIB.  Negative height means to use top-down BMP ordering
714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (must be uncompressed, but that's what we want).  Bit count of 1, 4 or 8
715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values
716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    directly => wimage_data begins immediately after BMP header.
717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    memset(dib, 0, sizeof(BITMAPINFOHEADER));
720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bmih = (BITMAPINFOHEADER *)dib;
721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bmih->biSize = sizeof(BITMAPINFOHEADER);
722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bmih->biWidth = rpng2_info.width;
723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bmih->biHeight = -((long)rpng2_info.height);
724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bmih->biPlanes = 1;
725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bmih->biBitCount = 24;
726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bmih->biCompression = 0;
727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wimage_data = dib + sizeof(BITMAPINFOHEADER);
728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Fill window with the specified background color (default is black), but
731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defer loading faked "background image" until window is displayed (may be
732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    slow to compute).  Data are in BGR order.
733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (bg_image) {   /* just fill with black for now */
736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        memset(wimage_data, 0, wimage_rowbytes*rpng2_info.height);
737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (j = 0;  j < rpng2_info.height;  ++j) {
739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = wimage_data + j*wimage_rowbytes;
740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = rpng2_info.width;  i > 0;  --i) {
741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_blue;
742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_green;
743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_red;
744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Set the window parameters.
750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    memset(&wndclass, 0, sizeof(wndclass));
753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.cbSize = sizeof(wndclass);
755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.style = CS_HREDRAW | CS_VREDRAW;
756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.lpfnWndProc = rpng2_win_wndproc;
757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.hInstance = global_hInst;
758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.lpszMenuName = NULL;
762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.lpszClassName = progname;
763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    RegisterClassEx(&wndclass);
766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Finally, create the window.
769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    extra_width  = 2*(GetSystemMetrics(SM_CXBORDER) +
772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      GetSystemMetrics(SM_CXDLGFRAME));
773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +
774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      GetSystemMetrics(SM_CYDLGFRAME)) +
775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      GetSystemMetrics(SM_CYCAPTION);
776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,
778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      CW_USEDEFAULT, CW_USEDEFAULT, rpng2_info.width+extra_width,
779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      rpng2_info.height+extra_height, NULL, NULL, global_hInst, NULL);
780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ShowWindow(global_hwnd, global_showmode);
782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    UpdateWindow(global_hwnd);
783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Now compute the background image and display it.  If it fails (memory
786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    allocation), revert to a plain background color.
787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (bg_image) {
790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        static const char *msg = "Computing background image...";
791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int x, y, len = strlen(msg);
792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        HDC hdc = GetDC(global_hwnd);
793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        TEXTMETRIC tm;
794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        GetTextMetrics(hdc, &tm);
796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        x = (rpng2_info.width - len*tm.tmAveCharWidth)/2;
797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        y = (rpng2_info.height - tm.tmHeight)/2;
798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        SetBkMode(hdc, TRANSPARENT);
799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* this can still begin out of bounds even if x is positive (???): */
801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len);
802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ReleaseDC(global_hwnd, hdc);
803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_win_load_bg_image();   /* resets bg_image if fails */
805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!bg_image) {
808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (j = 0;  j < rpng2_info.height;  ++j) {
809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = wimage_data + j*wimage_rowbytes;
810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = rpng2_info.width;  i > 0;  --i) {
811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_blue;
812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_green;
813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_red;
814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rect.left = 0L;
819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rect.top = 0L;
820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rect.right = (LONG)rpng2_info.width;       /* possibly off by one? */
821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rect.bottom = (LONG)rpng2_info.height;     /* possibly off by one? */
822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    InvalidateRect(global_hwnd, &rect, FALSE);
823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    UpdateWindow(global_hwnd);                 /* similar to XFlush() */
824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng2_win_create_window() */
828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng2_win_load_bg_image()
834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *src, *dest;
836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r1, r2, g1, g2, b1, b2;
837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int k, hmax, max;
839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int xidx, yidx, yidx_max = (bgscale-1);
840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int even_odd_vert, even_odd_horiz, even_odd;
841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int invert_gradient2 = (bg[pat].type & 0x08);
842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int invert_column;
843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i, row;
844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Allocate buffer for fake background image to be used with transparent
847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    images; if this fails, revert to plain background color.
848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bg_rowbytes = 3 * rpng2_info.width;
851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);
852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!bg_data) {
853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME
854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          ":  unable to allocate memory for background image\n");
855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_image = 0;
856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 1;
857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Vertical gradients (ramps) in NxN squares, alternating direction and
861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    colors (N == bgscale).
862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((bg[pat].type & 0x07) == 0) {
865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch r1_min  = rgb[bg[pat].rgb1_min].r;
866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch g1_min  = rgb[bg[pat].rgb1_min].g;
867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch b1_min  = rgb[bg[pat].rgb1_min].b;
868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch r2_min  = rgb[bg[pat].rgb2_min].r;
869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch g2_min  = rgb[bg[pat].rgb2_min].g;
870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch b2_min  = rgb[bg[pat].rgb2_min].b;
871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            yidx = row % bgscale;
880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            even_odd_vert = (row / bgscale) & 1;
881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r1 = r1_min + (r1_diff * yidx) / yidx_max;
883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g1 = g1_min + (g1_diff * yidx) / yidx_max;
884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b1 = b1_min + (b1_diff * yidx) / yidx_max;
885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r2 = r2_min + (r2_diff * yidx) / yidx_max;
890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g2 = g2_min + (g2_diff * yidx) / yidx_max;
891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b2 = b2_min + (b2_diff * yidx) / yidx_max;
892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = bg_data + row*bg_rowbytes;
897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                even_odd_horiz = (i / bgscale) & 1;
899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                even_odd = even_odd_vert ^ even_odd_horiz;
900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                invert_column =
901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (even_odd_horiz && (bg[pat].type & 0x10));
902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (even_odd == 0) {         /* gradient #1 */
903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (invert_column) {
904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r1_inv;
905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g1_inv;
906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b1_inv;
907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r1;
909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g1;
910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b1;
911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {                     /* gradient #2 */
913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if ((invert_column && invert_gradient2) ||
914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (!invert_column && !invert_gradient2))
915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    {
916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r2;        /* not inverted or */
917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g2;        /*  doubly inverted */
918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b2;
919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r2_inv;
921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g2_inv;    /* singly inverted */
922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b2_inv;
923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Soft gradient-diamonds with scale = bgscale.  Code contributed by Adam
930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    M. Costello.
931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if ((bg[pat].type & 0x07) == 1) {
934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hmax = (bgscale-1)/2;   /* half the max weight of a color */
936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        max = 2*hmax;           /* the max weight of a color */
937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        r1 = rgb[bg[pat].rgb1_max].r;
939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g1 = rgb[bg[pat].rgb1_max].g;
940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        b1 = rgb[bg[pat].rgb1_max].b;
941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        r2 = rgb[bg[pat].rgb2_max].r;
942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g2 = rgb[bg[pat].rgb2_max].g;
943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        b2 = rgb[bg[pat].rgb2_max].b;
944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            yidx = row % bgscale;
947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (yidx > hmax)
948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                yidx = bgscale-1 - yidx;
949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = bg_data + row*bg_rowbytes;
950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                xidx = i % bgscale;
952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (xidx > hmax)
953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    xidx = bgscale-1 - xidx;
954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                k = xidx + yidx;
955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*r1 + (max-k)*r2) / max;
956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*g1 + (max-k)*g2) / max;
957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*b1 + (max-k)*b2) / max;
958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    soids will equal bgscale?].  This one is slow but very cool.  Code con-
964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    tributed by Pieter S. van der Meulen (originally in Smalltalk).
965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if ((bg[pat].type & 0x07) == 2) {
968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch ch;
969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int ii, x, y, hw, hh, grayspot;
970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double freq, rotate, saturate, gray, intensity;
971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double angle=0.0, aoffset=0.0, maxDist, dist;
972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "%s:  computing radial background...",
975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PROGNAME);
976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hh = rpng2_info.height / 2;
979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hw = rpng2_info.width / 2;
980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* variables for radial waves:
982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]
983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   freq:  number of color beams originating from the center
984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   grayspot:  size of the graying center area (anti-alias)
985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   rotate:  rotation of the beams as a function of radius
986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   saturate:  saturation of beams' shape azimuthally
987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         */
988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        angle = CLIP(angle, 0.0, 360.0);
989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        freq = MAX((double)bg[pat].bg_freq, 0.0);
991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        saturate = (double)bg[pat].bg_bsat * 0.1;
992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rotate = (double)bg[pat].bg_brot * 0.1;
993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        gray = 0.0;
994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        intensity = 0.0;
995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        maxDist = (double)((hw*hw) + (hh*hh));
996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            y = row - hh;
999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = bg_data + row*bg_rowbytes;
1000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
1001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                x = i - hw;
1002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                angle = (x == 0)? PI_2 : atan((double)y / (double)x);
1003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
1004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                gray = MIN(1.0, gray);
1005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                dist = (double)((x*x) + (y*y)) / maxDist;
1006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                intensity = cos((angle+(rotate*dist*PI)) * freq) *
1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray * saturate;
1008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
1009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                hue = (angle + PI) * INV_PI_360 + aoffset;
1010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s = MIN(MAX(s,0.0), 1.0);
1012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                v = MIN(MAX(intensity,0.0), 1.0);
1013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (s == 0.0) {
1015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ch = (uch)(v * 255.0);
1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
1017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
1018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
1019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {
1020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if ((hue < 0.0) || (hue >= 360.0))
1021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        hue -= (((int)(hue / 360.0)) * 360.0);
1022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    hue /= 60.0;
1023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ii = (int)hue;
1024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    f = hue - (double)ii;
1025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    p = (1.0 - s) * v;
1026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    q = (1.0 - (s * f)) * v;
1027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    t = (1.0 - (s * (1.0 - f))) * v;
1028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if      (ii == 0) { red = v; green = t; blue = p; }
1029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 1) { red = q; green = v; blue = p; }
1030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 2) { red = p; green = v; blue = t; }
1031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 3) { red = p; green = q; blue = v; }
1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 4) { red = t; green = p; blue = v; }
1033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 5) { red = v; green = p; blue = q; }
1034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(red * 255.0);
1035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(green * 255.0);
1036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(blue * 255.0);
1037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "done.\n");
1041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
1042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Blast background image to display buffer before beginning PNG decode;
1046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    calling function will handle invalidation and UpdateWindow() call.
1047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (row = 0;  row < rpng2_info.height;  ++row) {
1050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        src = bg_data + row*bg_rowbytes;
1051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        dest = wimage_data + row*wimage_rowbytes;
1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = rpng2_info.width;  i > 0;  --i) {
1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r1 = *src++;
1054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g1 = *src++;
1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b1 = *src++;
1056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dest++ = b1;
1057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dest++ = g1;   /* note reverse order */
1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dest++ = r1;
1059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
1063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng2_win_load_bg_image() */
1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_win_display_row(ulg row)
1071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_red   = rpng2_info.bg_red;
1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_green = rpng2_info.bg_green;
1074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_blue  = rpng2_info.bg_blue;
1075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *src, *src2=NULL, *dest;
1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r, g, b, a;
1077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i;
1078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    static int rows=0;
1079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    static ulg firstrow;
1080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rows and firstrow simply track how many rows (and which ones) have not
1083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    yet been displayed; alternatively, we could call InvalidateRect() for
1084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    every row and not bother with the records-keeping.
1085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning rpng2_win_display_row()\n"))
1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rows == 0)
1090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        firstrow = row;   /* first row not yet displayed */
1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ++rows;   /* count of rows received but not yet displayed */
1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Aside from the use of the rpng2_info struct and the lack of an outer
1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    loop (over rows), this routine is identical to rpng_win_display_image()
1097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    in the non-progressive version of the program.
1098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    src = rpng2_info.image_data + row*rpng2_info.rowbytes;
1101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (bg_image)
1102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        src2 = bg_data + row*bg_rowbytes;
1103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    dest = wimage_data + row*wimage_rowbytes;
1104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_info.channels == 3) {
1106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = rpng2_info.width;  i > 0;  --i) {
1107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r = *src++;
1108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g = *src++;
1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b = *src++;
1110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dest++ = b;
1111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dest++ = g;   /* note reverse order */
1112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dest++ = r;
1113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* if (rpng2_info.channels == 4) */ {
1115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = rpng2_info.width;  i > 0;  --i) {
1116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r = *src++;
1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g = *src++;
1118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b = *src++;
1119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            a = *src++;
1120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (bg_image) {
1121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                bg_red   = *src2++;
1122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                bg_green = *src2++;
1123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                bg_blue  = *src2++;
1124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (a == 255) {
1126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = b;
1127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = g;
1128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = r;
1129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else if (a == 0) {
1130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_blue;
1131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_green;
1132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = bg_red;
1133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else {
1134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                /* this macro (copied from png.h) composites the
1135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 * foreground and background values and puts the
1136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 * result into the first argument; there are no
1137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 * side effects with the first argument */
1138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                alpha_composite(*dest++, b, a, bg_blue);
1139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                alpha_composite(*dest++, g, a, bg_green);
1140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                alpha_composite(*dest++, r, a, bg_red);
1141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Display after every 16 rows or when on last row.  (Region may include
1147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    previously displayed lines due to interlacing--i.e., not contiguous.)
1148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((rows & 0xf) == 0 || row == rpng2_info.height-1) {
1151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        RECT rect;
1152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rect.left = 0L;
1154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rect.top = (LONG)firstrow;
1155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rect.right = (LONG)rpng2_info.width;       /* possibly off by one? */
1156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rect.bottom = (LONG)row + 1L;              /* possibly off by one? */
1157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        InvalidateRect(global_hwnd, &rect, FALSE);
1158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        UpdateWindow(global_hwnd);                 /* similar to XFlush() */
1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rows = 0;
1160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng2_win_display_row() */
1163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_win_finish_display()
1169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning rpng2_win_finish_display()\n"))
1171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* last row has already been displayed by rpng2_win_display_row(), so
1173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * we have nothing to do here except set a flag and let the user know
1174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * that the image is done */
1175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.state = kDone;
1177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    printf(
1178ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#ifndef __CYGWIN__
1179ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      "Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\n"
1180ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#else
1181ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      "Done.  Press mouse button 1 (within image window) to quit.\n"
1182ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
1183ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    );
1184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fflush(stdout);
1185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_win_cleanup()
1192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (bg_image && bg_data) {
1194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(bg_data);
1195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_data = NULL;
1196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_info.image_data) {
1199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(rpng2_info.image_data);
1200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.image_data = NULL;
1201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_info.row_pointers) {
1204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(rpng2_info.row_pointers);
1205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.row_pointers = NULL;
1206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (dib) {
1209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(dib);
1210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        dib = NULL;
1211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectLRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
1219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    HDC         hdc;
1221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    PAINTSTRUCT ps;
1222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rc;
1223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    switch (iMsg) {
1225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case WM_CREATE:
1226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* one-time processing here, if any */
1227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 0;
1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case WM_PAINT:
1230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            hdc = BeginPaint(hwnd, &ps);
1231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rc = StretchDIBits(hdc, 0, 0, rpng2_info.width, rpng2_info.height,
1232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    0, 0, rpng2_info.width, rpng2_info.height,
1233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    wimage_data, (BITMAPINFO *)bmih,
1234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    0, SRCCOPY);
1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            EndPaint(hwnd, &ps);
1236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 0;
1237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* wait for the user to tell us when to quit */
1239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case WM_CHAR:
1240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (wP) {       /* only need one, so ignore repeat count */
1241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 'q':
1242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 'Q':
1243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 0x1B:      /* Esc key */
1244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    PostQuitMessage(0);
1245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 0;
1247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case WM_LBUTTONDOWN:    /* another way of quitting */
1249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case WM_DESTROY:
1250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            PostQuitMessage(0);
1251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 0;
1252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return DefWindowProc(hwnd, iMsg, wP, lP);
1255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1256