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