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