1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   rpng2 - progressive-model PNG display program                  rpng2-x.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 the X Window System (tested by the author under Unix and by Martin
10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   Zinser under OpenVMS; may work under OS/2 with a little tweaking).
11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond"
13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   and "radial waves" patterns, respectively.
14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   to do (someday, maybe):
16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - fix expose/redraw code:  don't draw entire row if only part exposed
17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 8-bit (colormapped) X support
18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - finish resizable checkerboard-gradient (sizes 4-128?)
19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - use %.1023s to simplify truncation of title-bar string?
20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------
22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   Changelog:
24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.01:  initial public release
25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.02:  modified to allow abbreviated options; fixed char/uchar mismatch
26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.10:  added support for non-default visuals; fixed X pixel-conversion
27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.11:  added -usleep option for demos; fixed command-line parsing bug
28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.12:  added -pause option for demos and testing
29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.20:  added runtime MMX-enabling/disabling and new -mmx* options
30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.21:  fixed some small X memory leaks (thanks to Fran�ois Petitjean)
31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.22:  fixed XFreeGC() crash bug (thanks to Patrick Welche)
32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.23:  added -bgpat 0 mode (std white/gray checkerboard, 8x8 squares)
33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.30:  added -loop option for -bgpat (ifdef FEATURE_LOOP); fixed bpp =
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              24; added support for X resources (thanks to Gerhard Niklasch)
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.31:  added code to skip unused chunks (thanks to Glenn Randers-Pehrson)
36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 1.32:  added AMD64/EM64T support (__x86_64__); added basic expose/redraw
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              handling
38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.00:  dual-licensed (added GNU GPL)
39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.01:  fixed 64-bit typo in readpng2.c; fixed -pause usage description
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    - 2.02:  fixed improper display of usage screen on PNG error(s); fixed
41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              unexpected-EOF and file-read-error cases; fixed Trace() cut-and-
42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              paste bugs
43ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    - 2.03:  deleted runtime MMX-enabling/disabling and obsolete -mmx* options
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This software is provided "as is," without warranty of any kind,
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      express or implied.  In no event shall the author or contributors
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      be held liable for any damages arising in any way from the use of
52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      this software.
53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      The contents of this file are DUAL-LICENSED.  You may modify and/or
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      redistribute this software according to the terms of one of the
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      following two licenses (at your option):
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      LICENSE 1 ("BSD-like with advertising clause"):
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Permission is granted to anyone to use this software for any purpose,
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      including commercial applications, and to alter it and redistribute
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      it freely, subject to the following restrictions:
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      1. Redistributions of source code must retain the above copyright
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         notice, disclaimer, and this list of conditions.
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      2. Redistributions in binary form must reproduce the above copyright
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         notice, disclaimer, and this list of conditions in the documenta-
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         tion and/or other materials provided with the distribution.
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      3. All advertising materials mentioning features or use of this
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         software must display the following acknowledgment:
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            This product includes software developed by Greg Roelofs
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            and contributors for the book, "PNG: The Definitive Guide,"
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            published by O'Reilly and Associates.
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      LICENSE 2 (GNU GPL v2 or later):
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This program is free software; you can redistribute it and/or modify
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      it under the terms of the GNU General Public License as published by
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      the Free Software Foundation; either version 2 of the License, or
83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (at your option) any later version.
84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      This program is distributed in the hope that it will be useful,
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      but WITHOUT ANY WARRANTY; without even the implied warranty of
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      GNU General Public License for more details.
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      You should have received a copy of the GNU General Public License
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      along with this program; if not, write to the Free Software Foundation,
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PROGNAME  "rpng2-x"
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define LONGNAME  "Progressive PNG Viewer for X"
98ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#define VERSION   "2.03 of 25 February 2010"
99ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#define RESNAME   "rpng2"       /* our X resource application name */
100ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#define RESCLASS  "Rpng"       /* our X resource class name */
101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdio.h>
103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdlib.h>
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <ctype.h>
105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <string.h>
106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <setjmp.h>       /* for jmpbuf declaration in readpng2.h */
107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <time.h>
108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <math.h>         /* only for PvdM background code */
109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/Xlib.h>
110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/Xutil.h>
111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/Xos.h>
112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <X11/keysym.h>   /* defines XK_* macros */
113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef VMS
115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  include <unistd.h>
116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* all for PvdM background code: */
119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef PI
120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  define PI             3.141592653589793238
121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PI_2             (PI*0.5)
123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define INV_PI_360       (360.0 / PI)
124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define MAX(a,b)         (a>b?a:b)
125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define MIN(a,b)         (a<b?a:b)
126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define CLIP(a,min,max)  MAX(min,MIN((a),max))
127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define ABS(a)           ((a)<0?-(a):(a))
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define CLIP8P(c)        MAX(0,(MIN((c),255)))   /* 8-bit pos. integer (uch) */
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define ROUNDF(f)        ((int)(f + 0.5))
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define QUIT(e,k) ((e.type == ButtonPress && e.xbutton.button == Button1) ||  \
132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (e.type == KeyPress &&   /*  v--- or 1 for shifted keys */  \
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape)))
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
135ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#define NO_24BIT_MASKS /* undef case not fully written--only for redisplay() */
136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb1_max   bg_freq
138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb1_min   bg_gray
139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb2_max   bg_bsat
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define rgb2_min   bg_brot
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* #define DEBUG */     /* this enables the Trace() macros */
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "readpng2.h"   /* typedefs, common macros, readpng2 prototypes */
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* could just include png.h, but this macro is the only thing we need
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (name and typedefs changed to local versions); note that side effects
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * only happen with alpha (which could easily be avoided with
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "ush acopy = (alpha);") */
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define alpha_composite(composite, fg, alpha, bg) {               \
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ush temp = ((ush)(fg)*(ush)(alpha) +                          \
154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128);  \
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (composite) = (uch)((temp + (temp >> 8)) >> 8);               \
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define INBUFSIZE 4096   /* with pseudo-timing on (1 sec delay/block), this
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  block size corresponds roughly to a download
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  speed 10% faster than theoretical 33.6K maximum
162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  (assuming 8 data bits, 1 stop bit and no other
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          *  overhead) */
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* local prototypes */
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_init (void);
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int  rpng2_x_create_window (void);
168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int  rpng2_x_load_bg_image (void);
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_display_row (ulg row);
170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_finish_display (void);
171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_redisplay_image (ulg startcol, ulg startrow,
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                     ulg width, ulg height);
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef FEATURE_LOOP
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_reload_bg_image (void);
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int  is_number (char *p);
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_cleanup (void);
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int  rpng2_x_msb (ulg u32val);
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char titlebar[1024], *window_name = titlebar;
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *appname = LONGNAME;
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *icon_name = PROGNAME;
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *res_name = RESNAME;
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *res_class = RESCLASS;
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *filename;
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic FILE *infile;
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic mainprog_info rpng2_info;
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch inbuf[INBUFSIZE];
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int incount;
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int pat = 6;        /* must be less than num_bgpat */
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int bg_image = 0;
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int bgscale, bgscale_default = 16;
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg bg_rowbytes;
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic uch *bg_data;
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint pause_after_pass = FALSE;
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint demo_timing = FALSE;
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectulg usleep_duration = 0L;
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic struct rgb_color {
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r, g, b;
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} rgb[] = {
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {  0,   0,   0},    /*  0:  black */
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255, 255, 255},    /*  1:  white */
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {173, 132,  57},    /*  2:  tan */
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 64, 132,   0},    /*  3:  medium green */
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {189, 117,   1},    /*  4:  gold */
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {253, 249,   1},    /*  5:  yellow */
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {  0,   0, 255},    /*  6:  blue */
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {  0,   0, 120},    /*  7:  medium blue */
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255,   0, 255},    /*  8:  magenta */
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 64,   0,  64},    /*  9:  dark magenta */
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255,   0,   0},    /* 10:  red */
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 64,   0,   0},    /* 11:  dark red */
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {255, 127,   0},    /* 12:  orange */
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {192,  96,   0},    /* 13:  darker orange */
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 24,  60,   0},    /* 14:  dark green-yellow */
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    { 85, 125, 200},    /* 15:  ice blue */
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {192, 192, 192}     /* 16:  Netscape/Mosaic gray */
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project};
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* not used for now, but should be for error-checking:
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    This whole struct is a fairly cheesy way to keep the number of
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    command-line options to a minimum.  The radial-waves background
232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    type is a particularly poor fit to the integer elements of the
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    struct...but a few macros and a little fixed-point math will do
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wonders for ya.
235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    type bits:
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       F E D C B A 9 8 7 6 5 4 3 2 1 0
238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | | | | |
239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | | +-+-+-- 0 = sharp-edged checkerboard
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | |         1 = soft diamonds
241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | |         2 = radial waves
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | |       3-7 = undefined
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | +-- gradient #2 inverted?
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             +-- alternating columns inverted?
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic struct background_pattern {
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ush type;
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rgb1_max, rgb1_min;     /* or bg_freq, bg_gray */
249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rgb2_max, rgb2_min;     /* or bg_bsat, bg_brot (both scaled by 10)*/
250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} bg[] = {
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0,     1,1, 16,16},        /* checkered:  white vs. light gray (basic) */
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,   2,0,  1,15},        /* checkered:  tan/black vs. white/ice blue */
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+24,  2,0,  1,0},         /* checkered:  tan/black vs. white/black */
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,   4,5,  0,2},         /* checkered:  gold/yellow vs. black/tan */
255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,   4,5,  0,6},         /* checkered:  gold/yellow vs. black/blue */
256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0,     7,0,  8,9},         /* checkered:  deep blue/black vs. magenta */
257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,  13,0,  5,14},        /* checkered:  orange/black vs. yellow */
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {0+8,  12,0, 10,11},        /* checkered:  orange/black vs. red */
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,     7,0,  8,0},         /* diamonds:  deep blue/black vs. magenta */
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,    12,0, 11,0},         /* diamonds:  orange vs. dark red */
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,    10,0,  7,0},         /* diamonds:  red vs. medium blue */
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,     4,0,  5,0},         /* diamonds:  gold vs. yellow */
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {1,     3,0,  0,0},         /* diamonds:  medium green vs. black */
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2,    16, 100,  20,   0},  /* radial:  ~hard radial color-beams */
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2,    18, 100,  10,   2},  /* radial:  soft, curved radial color-beams */
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2,    16, 256, 100, 250},  /* radial:  very tight spiral */
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {2, 10000, 256,  11,   0}   /* radial:  dipole-moire' (almost fractal) */
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project};
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* X-specific variables */
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic char *displayname;
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic XImage *ximage;
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Display *display;
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int depth;
277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Visual *visual;
278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic XVisualInfo *visual_list;
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int RShift, GShift, BShift;
280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic ulg RMask, GMask, BMask;
281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Window window;
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic GC gc;
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic Colormap colormap;
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_nondefault_visual = FALSE;
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_colormap = FALSE;
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_window = FALSE;
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int have_gc = FALSE;
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint main(int argc, char **argv)
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef sgi
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char tmpline[80];
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *p, *bgstr = NULL;
299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int rc, alen, flen;
300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int error = 0;
301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int timing = FALSE;
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int have_bg = FALSE;
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef FEATURE_LOOP
304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int loop = FALSE;
305ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    long loop_interval = -1;            /* seconds (100,000 max) */
306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double LUT_exponent;                /* just the lookup table */
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double CRT_exponent = 2.2;          /* just the monitor */
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double default_display_exponent;    /* whole display system */
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XEvent e;
311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    KeySym k;
312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* First initialize a few things, just to be sure--memset takes care of
315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * default background color (black), booleans (FALSE), pointers (NULL),
316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * etc. */
317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    displayname = (char *)NULL;
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    filename = (char *)NULL;
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    memset(&rpng2_info, 0, sizeof(mainprog_info));
321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Set the default value for our display-system exponent, i.e., the
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * product of the CRT exponent and the exponent corresponding to
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the frame-buffer's lookup table (LUT), if any.  This is not an
326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * ones), but it should cover 99% of the current possibilities. */
328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(NeXT)
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* third-party utilities can modify the default LUT exponent */
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0 / 2.2;
332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (some_next_function_that_returns_gamma(&next_gamma))
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        LUT_exponent = 1.0 / next_gamma;
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(sgi)
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0 / 1.7;
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* there doesn't seem to be any documented function to
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * get the "gamma" value, so we do it the hard way */
340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    infile = fopen("/etc/config/system.glGammaVal", "r");
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (infile) {
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double sgi_gamma;
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fgets(tmpline, 80, infile);
345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fclose(infile);
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sgi_gamma = atof(tmpline);
347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (sgi_gamma > 0.0)
348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            LUT_exponent = 1.0 / sgi_gamma;
349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#elif defined(Macintosh)
351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.8 / 2.61;
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (some_mac_function_that_returns_gamma(&mac_gamma))
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        LUT_exponent = mac_gamma / 2.61;
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    LUT_exponent = 1.0;   /* assume no LUT:  most PCs */
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    default_display_exponent = LUT_exponent * CRT_exponent;
362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* If the user has set the SCREEN_GAMMA environment variable as suggested
365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * (somewhat imprecisely) in the libpng documentation, use that; otherwise
366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * use the default value we just calculated.  Either way, the user may
367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * override this via a command-line option. */
368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((p = getenv("SCREEN_GAMMA")) != NULL)
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.display_exponent = atof(p);
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.display_exponent = default_display_exponent;
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Now parse the command line for options and the PNG filename. */
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (*++argv && !error) {
378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (!strncmp(*argv, "-display", 2)) {
379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                displayname = *argv;
383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-gamma", 2)) {
384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                rpng2_info.display_exponent = atof(*argv);
388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (rpng2_info.display_exponent <= 0.0)
389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-bgcolor", 4)) {
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                bgstr = *argv;
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (strlen(bgstr) != 7 || bgstr[0] != '#')
397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                else {
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    have_bg = TRUE;
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_image = FALSE;
401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-bgpat", 4)) {
404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pat = atoi(*argv);
408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (pat >= 0 && pat < num_bgpat) {
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_image = TRUE;
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    have_bg = FALSE;
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-usleep", 2)) {
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!*++argv)
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                usleep_duration = (ulg)atol(*argv);
419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                demo_timing = TRUE;
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-pause", 2)) {
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pause_after_pass = TRUE;
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-timing", 2)) {
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            timing = TRUE;
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef FEATURE_LOOP
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (!strncmp(*argv, "-loop", 2)) {
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            loop = TRUE;
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!argv[1] || !is_number(argv[1]))
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                loop_interval = 2;
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else {
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++argv;
432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                loop_interval = atol(*argv);
433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (loop_interval < 0)
434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    loop_interval = 2;
435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                else if (loop_interval > 100000)   /* bit more than one day */
436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    loop_interval = 100000;
437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else {
440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (**argv != '-') {
441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                filename = *argv;
442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (argv[1])   /* shouldn't be any more args after filename */
443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++error;
444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else
445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;   /* not expecting any other options */
446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!filename)
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ++error;
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* print usage screen if any errors up to this point */
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "\n%s %s:  %s\n\n", PROGNAME, VERSION, appname);
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_version_info();
458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "\n"
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "Usage:  %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef FEATURE_LOOP
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "        %*s [-usleep dur | -timing] [-pause] [-loop [sec]] file.png\n\n"
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "        %*s [-usleep dur | -timing] [-pause] file.png\n\n"
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    exp \ttransfer-function exponent (``gamma'') of the display\n"
467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  system in floating-point format (e.g., ``%.1f''); equal\n"
468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  to the product of the lookup-table exponent (varies)\n"
469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    bg  \tdesired background color in 7-character hex RGB format\n"
471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\n"
472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  used with transparent images; overrides -bgpat\n"
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    pat \tdesired background pattern number (0-%d); used with\n"
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  transparent images; overrides -bgcolor\n"
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef FEATURE_LOOP
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    -loop\tloops through background images after initial display\n"
477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  is complete (depends on -bgpat)\n"
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    sec \tseconds to display each background image (default = 2)\n"
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    dur \tduration in microseconds to wait after displaying each\n"
481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  row (for demo purposes)\n"
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    -timing\tenables delay for every block read, to simulate modem\n"
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\t\t  download of image (~36 Kbps)\n"
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "    -pause\tpauses after displaying each pass until mouse clicked\n"
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "is displayed) to quit.\n"
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "\n", PROGNAME,
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat-1);
489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(1);
490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!(infile = fopen(filename, "rb"))) {
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  can't open PNG file [%s]\n", filename);
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ++error;
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        incount = fread(inbuf, 1, INBUFSIZE, infile);
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, PROGNAME
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              ":  [%s] is not a PNG file: incorrect signature\n",
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              filename);
502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++error;
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if ((rc = readpng2_init(&rpng2_info)) != 0) {
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (rc) {
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 2:
506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME
507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      ":  [%s] has bad IHDR (libpng longjmp)\n", filename);
508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                case 4:
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME ":  insufficient memory\n");
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                default:
513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, PROGNAME
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      ":  unknown readpng2_init() error\n");
515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++error;
518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else {
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            Trace((stderr, "about to call XOpenDisplay()\n"))
520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            display = XOpenDisplay(displayname);
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!display) {
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                readpng2_cleanup(&rpng2_info);
523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                fprintf(stderr, PROGNAME ":  can't open X display [%s]\n",
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  displayname? displayname : "default");
525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++error;
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (error)
529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fclose(infile);
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  aborting.\n");
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(2);
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* set the title-bar string, but make sure buffer doesn't overflow */
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    alen = strlen(appname);
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    flen = strlen(filename);
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (alen + flen + 3 > 1023)
544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sprintf(titlebar, "%s:  ...%s", appname, filename+(alen+flen+6-1023));
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sprintf(titlebar, "%s:  %s", appname, filename);
547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* set some final rpng2_info variables before entering main data loop */
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_bg) {
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        unsigned r, g, b;   /* this approach quiets compiler warnings */
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.bg_red   = (uch)r;
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.bg_green = (uch)g;
557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.bg_blue  = (uch)b;
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.need_bgcolor = TRUE;
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.state = kPreInit;
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.mainprog_init = rpng2_x_init;
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.mainprog_display_row = rpng2_x_display_row;
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.mainprog_finish_display = rpng2_x_finish_display;
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* OK, this is the fun part:  call readpng2_decode_data() at the start of
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the loop to deal with our first buffer of data (read in above to verify
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * that the file is a PNG image), then loop through the file and continue
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * calling the same routine to handle each chunk of data.  It in turn
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * passes the data to libpng, which will invoke one or more of our call-
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * backs as decoded data become available.  We optionally call sleep() for
573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * one second per iteration to simulate downloading the image via an analog
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * modem. */
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (;;) {
577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "about to call readpng2_decode_data()\n"))
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (readpng2_decode_data(&rpng2_info, inbuf, incount))
579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ++error;
580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "done with readpng2_decode_data()\n"))
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (rpng2_info.state == kDone) {
584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                Trace((stderr, "done decoding PNG image\n"))
585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else if (ferror(infile)) {
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                fprintf(stderr, PROGNAME
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  ":  error while reading PNG image file\n");
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                exit(3);
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else if (feof(infile)) {
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                fprintf(stderr, PROGNAME ":  end of file reached "
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  "(unexpectedly) while reading PNG image file\n");
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                exit(3);
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else /* if (error) */ {
594ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik                /* will print error message below */
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (timing)
600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sleep(1);
601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        incount = fread(inbuf, 1, INBUFSIZE, infile);
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* clean up PNG stuff and report any decoding errors */
607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fclose(infile);
609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "about to call readpng2_cleanup()\n"))
610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    readpng2_cleanup(&rpng2_info);
611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (error) {
613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  libpng error while decoding PNG image\n");
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(3);
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef FEATURE_LOOP
619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (loop && bg_image) {
621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "entering -loop loop (FEATURE_LOOP)\n"))
622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (;;) {
623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int i, use_sleep;
624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            struct timeval now, then;
625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* get current time and add loop_interval to get target time */
627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (gettimeofday(&then, NULL) == 0) {
628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                then.tv_sec += loop_interval;
629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                use_sleep = FALSE;
630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else
631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                use_sleep = TRUE;
632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* do quick check for a quit event but don't wait for it */
634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* GRR BUG:  should also check for Expose events and redraw... */
635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e))
636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (QUIT(e,k))
637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    break;
638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* generate next background image */
640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (++pat >= num_bgpat)
641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pat = 0;
642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rpng2_x_reload_bg_image();
643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* wait for timeout, using whatever means are available */
645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (use_sleep || gettimeofday(&now, NULL) != 0) {
646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = loop_interval;  i > 0;  --i) {
647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    sleep(1);
648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* GRR BUG:  also need to check for Expose (and redraw!) */
649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask,
650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        &e) && QUIT(e,k))
651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        break;
652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else {
654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                /* Y2038 BUG! */
655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (now.tv_sec < then.tv_sec ||
656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    (now.tv_sec == then.tv_sec && now.tv_usec < then.tv_usec))
657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                {
658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    int quit = FALSE;
659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    long seconds_to_go = then.tv_sec - now.tv_sec;
660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    long usleep_usec;
661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* basically chew up most of remaining loop-interval with
663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *  calls to sleep(1) interleaved with checks for quit
664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *  events, but also recalc time-to-go periodically; when
665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *  done, clean up any remaining time with usleep() call
666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *  (could also use SIGALRM, but signals are a pain...) */
667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    while (seconds_to_go-- > 1) {
668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        int seconds_done = 0;
669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        for (i = seconds_to_go;  i > 0 && !quit;  --i) {
671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            sleep(1);
672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            /* GRR BUG:  need to check for Expose and redraw */
673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            if (XCheckMaskEvent(display, KeyPressMask |
674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                ButtonPressMask, &e) && QUIT(e,k))
675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                quit = TRUE;
676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            if (++seconds_done > 1000)
677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                break;   /* time to redo seconds_to_go meas. */
678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (quit)
680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            break;
681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* OK, more than 1000 seconds since last check:
683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         *  correct the time-to-go measurement for drift */
684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (gettimeofday(&now, NULL) == 0) {
685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            if (now.tv_sec >= then.tv_sec)
686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                break;
687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            seconds_to_go = then.tv_sec - now.tv_sec;
688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        } else
689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ++seconds_to_go;  /* restore what we subtracted */
690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (quit)
692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        break;   /* breaks outer do-loop, skips redisplay */
693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* since difference between "now" and "then" is already
695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *  eaten up to within a couple of seconds, don't need to
696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *  worry about overflow--but might have overshot (neg.) */
697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (gettimeofday(&now, NULL) == 0) {
698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        usleep_usec = 1000000L*(then.tv_sec - now.tv_sec) +
699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          then.tv_usec - now.tv_usec;
700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (usleep_usec > 0)
701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            usleep((ulg)usleep_usec);
702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* composite image against new background and display (note that
707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             *  we do not take into account the time spent doing this...) */
708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rpng2_x_redisplay_image (0, 0, rpng2_info.width, rpng2_info.height);
709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* FALL THROUGH and do the normal thing */
712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* FEATURE_LOOP */
714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* wait for the user to tell us when to quit */
716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_info.state >= kWindowInit) {
718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "entering final wait-for-quit-event loop\n"))
719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        do {
720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            XNextEvent(display, &e);
721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (e.type == Expose) {
722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XExposeEvent *ex = (XExposeEvent *)&e;
723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                rpng2_x_redisplay_image (ex->x, ex->y, ex->width, ex->height);
724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } while (!QUIT(e,k));
726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  init callback never called:  probable "
728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "libpng error while decoding PNG metadata\n");
729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(4);
730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* we're done:  clean up all image and X resources and go away */
734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "about to call rpng2_x_cleanup()\n"))
736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_x_cleanup();
737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* this function is called by readpng2_info_callback() in readpng2.c, which
746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in turn is called by libpng after all of the pre-IDAT chunks have been
747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * read and processed--i.e., we now have enough info to finish initializing */
748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_init(void)
750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i;
752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg rowbytes = rpng2_info.rowbytes;
753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning rpng2_x_init()\n"))
755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "  rowbytes = %d\n", rpng2_info.rowbytes))
756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "  width  = %ld\n", rpng2_info.width))
757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "  height = %ld\n", rpng2_info.height))
758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!rpng2_info.image_data) {
761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_cleanup(&rpng2_info);
762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return;
763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));
766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!rpng2_info.row_pointers) {
767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(rpng2_info.image_data);
768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.image_data = NULL;
769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_cleanup(&rpng2_info);
770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return;
771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i = 0;  i < rpng2_info.height;  ++i)
774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;
775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* do the basic X initialization stuff, make the window, and fill it with
778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the user-specified, file-specified or default background color or
779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * pattern */
780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_x_create_window()) {
782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* GRR TEMPORARY HACK:  this is fundamentally no different from cases
784ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik         * above; libpng should call our error handler to longjmp() back to us
785ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik         * when png_ptr goes away.  If we/it segfault instead, seems like a
786ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik         * libpng bug... */
787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* we're here via libpng callback, so if window fails, clean and bail */
789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        readpng2_cleanup(&rpng2_info);
790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_x_cleanup();
791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(2);
792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.state = kWindowInit;
795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng2_x_create_window(void)
802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg bg_red   = rpng2_info.bg_red;
804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg bg_green = rpng2_info.bg_green;
805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg bg_blue  = rpng2_info.bg_blue;
806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg bg_pixel = 0L;
807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg attrmask;
808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int need_colormap = FALSE;
809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int screen, pad;
810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *xdata;
811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Window root;
812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XEvent e;
813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XGCValues gcvalues;
814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSetWindowAttributes attr;
815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XTextProperty windowName, *pWindowName = &windowName;
816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XTextProperty iconName, *pIconName = &iconName;
817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XVisualInfo visual_info;
818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSizeHints *size_hints;
819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XWMHints *wm_hints;
820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XClassHint *class_hints;
821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning rpng2_x_create_window()\n"))
824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    screen = DefaultScreen(display);
826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    depth = DisplayPlanes(display, screen);
827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    root = RootWindow(display, screen);
828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef DEBUG
830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSynchronize(display, True);
831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth != 16 && depth != 24 && depth != 32) {
834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int visuals_matched = 0;
835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "default depth is %d:  checking other visuals\n",
837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          depth))
838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* 24-bit first */
840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_info.screen = screen;
841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_info.depth = 24;
842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_list = XGetVisualInfo(display,
843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (visuals_matched == 0) {
845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR:  add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "default screen depth %d not supported, and no"
847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              " 24-bit visuals found\n", depth);
848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 2;
849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          visuals_matched))
852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual = visual_list[0].visual;
853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        depth = visual_list[0].depth;
854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        colormap_size = visual_list[0].colormap_size;
856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual_class = visual->class;
857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visualID = XVisualIDFromVisual(visual);
858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        have_nondefault_visual = TRUE;
860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        need_colormap = TRUE;
861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else {
862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        visual = visual_info.visual;
864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    RMask = visual->red_mask;
867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    GMask = visual->green_mask;
868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    BMask = visual->blue_mask;
869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR:  add/check 8-bit support */
871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 8 || need_colormap) {
872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        colormap = XCreateColormap(display, root, visual, AllocNone);
873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (!colormap) {
874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "XCreateColormap() failed\n");
875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return 2;
876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        have_colormap = TRUE;
878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (depth == 8)
879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bg_image = FALSE;   /* gradient just wastes palette entries */
880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 15 || depth == 16) {
882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        RShift = 15 - rpng2_x_msb(RMask);    /* these are right-shifts */
883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        GShift = 15 - rpng2_x_msb(GMask);
884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        BShift = 15 - rpng2_x_msb(BMask);
885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth > 16) {
886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        RShift = rpng2_x_msb(RMask) - 7;     /* these are left-shifts */
887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        GShift = rpng2_x_msb(GMask) - 7;
888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        BShift = rpng2_x_msb(BMask) - 7;
889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "rpng2 internal logic error:  negative X shift(s)!\n");
892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 2;
893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Finally, create the window.
897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    attr.backing_store = Always;
900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    attrmask = CWBackingStore | CWEventMask;
902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_nondefault_visual) {
903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attr.colormap = colormap;
904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attr.background_pixel = 0;
905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attr.border_pixel = 1;
906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    window = XCreateWindow(display, root, 0, 0, rpng2_info.width,
910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr);
911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (window == None) {
913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "XCreateWindow() failed\n");
914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 2;
915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else
916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        have_window = TRUE;
917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 8)
919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XSetWindowColormap(display, window, colormap);
920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!XStringListToTextProperty(&window_name, 1, pWindowName))
922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pWindowName = NULL;
923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!XStringListToTextProperty(&icon_name, 1, pIconName))
924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pIconName = NULL;
925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */
927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((size_hints = XAllocSizeHints()) != NULL) {
929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* window will not be resizable */
930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        size_hints->flags = PMinSize | PMaxSize;
931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        size_hints->min_width = size_hints->max_width = (int)rpng2_info.width;
932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        size_hints->min_height = size_hints->max_height =
933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)rpng2_info.height;
934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((wm_hints = XAllocWMHints()) != NULL) {
937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        wm_hints->initial_state = NormalState;
938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        wm_hints->input = True;
939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     /* wm_hints->icon_pixmap = icon_pixmap; */
940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        wm_hints->flags = StateHint | InputHint  /* | IconPixmapHint */ ;
941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((class_hints = XAllocClassHint()) != NULL) {
944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        class_hints->res_name = res_name;
945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        class_hints->res_class = res_class;
946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      size_hints, wm_hints, class_hints);
950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* various properties and hints no longer needed; free memory */
952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (pWindowName)
953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(pWindowName->value);
954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (pIconName)
955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(pIconName->value);
956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (size_hints)
957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFree(size_hints);
958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (wm_hints)
959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(wm_hints);
960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (class_hints)
961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       XFree(class_hints);
962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XMapWindow(display, window);
964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    gc = XCreateGC(display, window, 0, &gcvalues);
966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    have_gc = TRUE;
967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Allocate memory for the X- and display-specific version of the image.
970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 24 || depth == 32) {
973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        xdata = (uch *)malloc(4*rpng2_info.width*rpng2_info.height);
974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pad = 32;
975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth == 16) {
976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        xdata = (uch *)malloc(2*rpng2_info.width*rpng2_info.height);
977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pad = 16;
978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* depth == 8 */ {
979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        xdata = (uch *)malloc(rpng2_info.width*rpng2_info.height);
980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        pad = 8;
981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!xdata) {
984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  unable to allocate image memory\n");
985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 4;
986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (char *)xdata, rpng2_info.width, rpng2_info.height, pad, 0);
990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!ximage) {
992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME ":  XCreateImage() failed\n");
993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(xdata);
994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 3;
995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* to avoid testing the byte order every pixel (or doubling the size of
998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the drawing routine with a giant if-test), we arbitrarily set the byte
999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * order to MSBFirst and let Xlib worry about inverting things on little-
1000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the
1001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * most efficient approach (the giant if-test would be better), but in
1002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the interest of clarity, we'll take the easy way out... */
1003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ximage->byte_order = MSBFirst;
1005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Fill window with the specified background color (default is black) or
1008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    faked "background image" (but latter is disabled if 8-bit; gradients
1009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    just waste palette entries).
1010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (bg_image)
1013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_x_load_bg_image();    /* resets bg_image if fails */
1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!bg_image) {
1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (depth == 24 || depth == 32) {
1017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bg_pixel = (bg_red   << RShift) |
1018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                       (bg_green << GShift) |
1019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                       (bg_blue  << BShift);
1020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (depth == 16) {
1021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bg_pixel = (((bg_red   << 8) >> RShift) & RMask) |
1022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                       (((bg_green << 8) >> GShift) & GMask) |
1023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                       (((bg_blue  << 8) >> BShift) & BMask);
1024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else /* depth == 8 */ {
1025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* GRR:  add 8-bit support */
1027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XSetForeground(display, gc, bg_pixel);
1030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFillRectangle(display, window, gc, 0, 0, rpng2_info.width,
1031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          rpng2_info.height);
1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Wait for first Expose event to do any drawing, then flush and return.
1036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    do
1039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XNextEvent(display, &e);
1040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (e.type != Expose || e.xexpose.count);
1041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XFlush(display);
1043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
1045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng2_x_create_window() */
1047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng2_x_load_bg_image(void)
1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *src;
1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *dest;
1056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r1, r2, g1, g2, b1, b2;
1057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int k, hmax, max;
1059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int xidx, yidx, yidx_max;
1060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int even_odd_vert, even_odd_horiz, even_odd;
1061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int invert_gradient2 = (bg[pat].type & 0x08);
1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int invert_column;
1063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int ximage_rowbytes = ximage->bytes_per_line;
1064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i, row;
1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg pixel;
1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Allocate buffer for fake background image to be used with transparent
1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    images; if this fails, revert to plain background color.
1070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bg_rowbytes = 3 * rpng2_info.width;
1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);
1074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!bg_data) {
1075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, PROGNAME
1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          ":  unable to allocate memory for background image\n");
1077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_image = 0;
1078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 1;
1079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bgscale = (pat == 0)? 8 : bgscale_default;
1082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    yidx_max = bgscale - 1;
1083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Vertical gradients (ramps) in NxN squares, alternating direction and
1086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    colors (N == bgscale).
1087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((bg[pat].type & 0x07) == 0) {
1090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch r1_min  = rgb[bg[pat].rgb1_min].r;
1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch g1_min  = rgb[bg[pat].rgb1_min].g;
1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch b1_min  = rgb[bg[pat].rgb1_min].b;
1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch r2_min  = rgb[bg[pat].rgb2_min].r;
1094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch g2_min  = rgb[bg[pat].rgb2_min].g;
1095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch b2_min  = rgb[bg[pat].rgb2_min].b;
1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
1097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
1098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
1099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
1100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
1101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
1102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            yidx = (int)(row % bgscale);
1105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            even_odd_vert = (int)((row / bgscale) & 1);
1106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r1 = r1_min + (r1_diff * yidx) / yidx_max;
1108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g1 = g1_min + (g1_diff * yidx) / yidx_max;
1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b1 = b1_min + (b1_diff * yidx) / yidx_max;
1110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
1111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
1112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
1113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r2 = r2_min + (r2_diff * yidx) / yidx_max;
1115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g2 = g2_min + (g2_diff * yidx) / yidx_max;
1116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b2 = b2_min + (b2_diff * yidx) / yidx_max;
1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
1118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
1119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
1120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = (char *)bg_data + row*bg_rowbytes;
1122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
1123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                even_odd_horiz = (int)((i / bgscale) & 1);
1124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                even_odd = even_odd_vert ^ even_odd_horiz;
1125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                invert_column =
1126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (even_odd_horiz && (bg[pat].type & 0x10));
1127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (even_odd == 0) {        /* gradient #1 */
1128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (invert_column) {
1129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r1_inv;
1130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g1_inv;
1131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b1_inv;
1132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r1;
1134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g1;
1135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b1;
1136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {                    /* gradient #2 */
1138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if ((invert_column && invert_gradient2) ||
1139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (!invert_column && !invert_gradient2))
1140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    {
1141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r2;       /* not inverted or */
1142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g2;       /*  doubly inverted */
1143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b2;
1144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r2_inv;
1146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g2_inv;   /* singly inverted */
1147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b2_inv;
1148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Soft gradient-diamonds with scale = bgscale.  Code contributed by Adam
1155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    M. Costello.
1156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if ((bg[pat].type & 0x07) == 1) {
1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hmax = (bgscale-1)/2;   /* half the max weight of a color */
1161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        max = 2*hmax;           /* the max weight of a color */
1162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        r1 = rgb[bg[pat].rgb1_max].r;
1164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g1 = rgb[bg[pat].rgb1_max].g;
1165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        b1 = rgb[bg[pat].rgb1_max].b;
1166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        r2 = rgb[bg[pat].rgb2_max].r;
1167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g2 = rgb[bg[pat].rgb2_max].g;
1168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        b2 = rgb[bg[pat].rgb2_max].b;
1169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            yidx = (int)(row % bgscale);
1172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (yidx > hmax)
1173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                yidx = bgscale-1 - yidx;
1174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = (char *)bg_data + row*bg_rowbytes;
1175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
1176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                xidx = (int)(i % bgscale);
1177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (xidx > hmax)
1178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    xidx = bgscale-1 - xidx;
1179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                k = xidx + yidx;
1180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*r1 + (max-k)*r2) / max;
1181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*g1 + (max-k)*g2) / max;
1182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*b1 + (max-k)*b2) / max;
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    Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
1188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    soids will equal bgscale?].  This one is slow but very cool.  Code con-
1189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    tributed by Pieter S. van der Meulen (originally in Smalltalk).
1190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if ((bg[pat].type & 0x07) == 2) {
1193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch ch;
1194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int ii, x, y, hw, hh, grayspot;
1195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double freq, rotate, saturate, gray, intensity;
1196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double angle=0.0, aoffset=0.0, maxDist, dist;
1197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
1198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "%s:  computing radial background...",
1200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PROGNAME);
1201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
1202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hh = (int)(rpng2_info.height / 2);
1204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hw = (int)(rpng2_info.width / 2);
1205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* variables for radial waves:
1207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]
1208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   freq:  number of color beams originating from the center
1209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   grayspot:  size of the graying center area (anti-alias)
1210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   rotate:  rotation of the beams as a function of radius
1211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   saturate:  saturation of beams' shape azimuthally
1212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         */
1213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        angle = CLIP(angle, 0.0, 360.0);
1214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
1215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        freq = MAX((double)bg[pat].bg_freq, 0.0);
1216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        saturate = (double)bg[pat].bg_bsat * 0.1;
1217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rotate = (double)bg[pat].bg_brot * 0.1;
1218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        gray = 0.0;
1219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        intensity = 0.0;
1220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        maxDist = (double)((hw*hw) + (hh*hh));
1221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            y = (int)(row - hh);
1224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = (char *)bg_data + row*bg_rowbytes;
1225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
1226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                x = (int)(i - hw);
1227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                angle = (x == 0)? PI_2 : atan((double)y / (double)x);
1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                gray = MIN(1.0, gray);
1230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                dist = (double)((x*x) + (y*y)) / maxDist;
1231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                intensity = cos((angle+(rotate*dist*PI)) * freq) *
1232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray * saturate;
1233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
1234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                hue = (angle + PI) * INV_PI_360 + aoffset;
1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
1236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s = MIN(MAX(s,0.0), 1.0);
1237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                v = MIN(MAX(intensity,0.0), 1.0);
1238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (s == 0.0) {
1240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ch = (uch)(v * 255.0);
1241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
1242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
1243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
1244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {
1245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if ((hue < 0.0) || (hue >= 360.0))
1246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        hue -= (((int)(hue / 360.0)) * 360.0);
1247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    hue /= 60.0;
1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ii = (int)hue;
1249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    f = hue - (double)ii;
1250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    p = (1.0 - s) * v;
1251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    q = (1.0 - (s * f)) * v;
1252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    t = (1.0 - (s * (1.0 - f))) * v;
1253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if      (ii == 0) { red = v; green = t; blue = p; }
1254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 1) { red = q; green = v; blue = p; }
1255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 2) { red = p; green = v; blue = t; }
1256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 3) { red = p; green = q; blue = v; }
1257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 4) { red = t; green = p; blue = v; }
1258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 5) { red = v; green = p; blue = q; }
1259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(red * 255.0);
1260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(green * 255.0);
1261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(blue * 255.0);
1262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "done.\n");
1266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
1267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Blast background image to display buffer before beginning PNG decode.
1271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 24 || depth == 32) {
1274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ulg red, green, blue;
1275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int bpp = ximage->bits_per_pixel;
1276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src = bg_data + row*bg_rowbytes;
1279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = ximage->data + row*ximage_rowbytes;
1280ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            if (bpp == 32) {    /* slightly optimized version */
1281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = rpng2_info.width;  i > 0;  --i) {
1282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = *src++;
1283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = *src++;
1284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = *src++;
1285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red   << RShift) |
1286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (green << GShift) |
1287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (blue  << BShift);
1288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 24) & 0xff);
1290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
1291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else {
1295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = rpng2_info.width;  i > 0;  --i) {
1296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = *src++;
1297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = *src++;
1298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = *src++;
1299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red   << RShift) |
1300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (green << GShift) |
1301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (blue  << BShift);
1302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* GRR BUG?  this assumes bpp == 24 & bits are packed low */
1304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /*           (probably need to use RShift, RMask, etc.) */
1305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
1306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth == 16) {
1313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ush red, green, blue;
1314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src = bg_data + row*bg_rowbytes;
1317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = ximage->data + row*ximage_rowbytes;
1318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = rpng2_info.width;  i > 0;  --i) {
1319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                red   = ((ush)(*src) << 8);  ++src;
1320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                green = ((ush)(*src) << 8);  ++src;
1321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                blue  = ((ush)(*src) << 8);  ++src;
1322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pixel = ((red   >> RShift) & RMask) |
1323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((green >> GShift) & GMask) |
1324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((blue  >> BShift) & BMask);
1325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                /* recall that we set ximage->byte_order = MSBFirst above */
1326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (char)((pixel >>  8) & 0xff);
1327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (char)( pixel        & 0xff);
1328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* depth == 8 */ {
1332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* GRR:  add 8-bit support */
1334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width,
1338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      rpng2_info.height);
1339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
1341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng2_x_load_bg_image() */
1343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_display_row(ulg row)
1349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_red   = rpng2_info.bg_red;
1351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_green = rpng2_info.bg_green;
1352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_blue  = rpng2_info.bg_blue;
1353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *src, *src2=NULL;
1354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *dest;
1355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r, g, b, a;
1356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int ximage_rowbytes = ximage->bytes_per_line;
1357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i, pixel;
1358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    static int rows=0, prevpass=(-1);
1359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    static ulg firstrow;
1360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rows and firstrow simply track how many rows (and which ones) have not
1363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    yet been displayed; alternatively, we could call XPutImage() for every
1364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    row and not bother with the records-keeping.
1365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning rpng2_x_display_row()\n"))
1368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_info.pass != prevpass) {
1370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (pause_after_pass && rpng2_info.pass > 0) {
1371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            XEvent e;
1372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            KeySym k;
1373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr,
1375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "%s:  end of pass %d of 7; click in image window to continue\n",
1376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              PROGNAME, prevpass + 1);
1377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            do
1378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XNextEvent(display, &e);
1379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            while (!QUIT(e,k));
1380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "%s:  pass %d of 7\r", PROGNAME, rpng2_info.pass + 1);
1382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
1383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        prevpass = rpng2_info.pass;
1384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rows == 0)
1387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        firstrow = row;   /* first row that is not yet displayed */
1388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ++rows;   /* count of rows received but not yet displayed */
1390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Aside from the use of the rpng2_info struct, the lack of an outer loop
1393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (over rows) and moving the XPutImage() call outside the "if (depth)"
1394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    tests, this routine is identical to rpng_x_display_image() in the non-
1395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    progressive version of the program.
1396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 24 || depth == 32) {
1399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ulg red, green, blue;
1400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int bpp = ximage->bits_per_pixel;
1401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        src = rpng2_info.image_data + row*rpng2_info.rowbytes;
1403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (bg_image)
1404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src2 = bg_data + row*bg_rowbytes;
1405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        dest = ximage->data + row*ximage_rowbytes;
1406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (rpng2_info.channels == 3) {
1407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = rpng2_info.width;  i > 0;  --i) {
1408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                red   = *src++;
1409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                green = *src++;
1410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                blue  = *src++;
1411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pixel = (red   << RShift) |
1412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (green << GShift) |
1413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (blue  << BShift);
1414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                /* recall that we set ximage->byte_order = MSBFirst above */
1415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (bpp == 32) {
1416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 24) & 0xff);
1417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
1418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {
1421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* GRR BUG?  this assumes bpp == 24 & bits are packed low */
1422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /*           (probably need to use RShift, RMask, etc.) */
1423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
1424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else /* if (rpng2_info.channels == 4) */ {
1429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = rpng2_info.width;  i > 0;  --i) {
1430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                r = *src++;
1431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                g = *src++;
1432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                b = *src++;
1433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                a = *src++;
1434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (bg_image) {
1435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_red   = *src2++;
1436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_green = *src2++;
1437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_blue  = *src2++;
1438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (a == 255) {
1440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = r;
1441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = g;
1442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = b;
1443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else if (a == 0) {
1444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = bg_red;
1445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = bg_green;
1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = bg_blue;
1447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {
1448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* this macro (from png.h) composites the foreground
1449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     * and background values and puts the result into the
1450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     * first argument */
1451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    alpha_composite(red,   r, a, bg_red);
1452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    alpha_composite(green, g, a, bg_green);
1453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    alpha_composite(blue,  b, a, bg_blue);
1454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pixel = (red   << RShift) |
1456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (green << GShift) |
1457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (blue  << BShift);
1458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                /* recall that we set ximage->byte_order = MSBFirst above */
1459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (bpp == 32) {
1460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 24) & 0xff);
1461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
1462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {
1465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* GRR BUG?  this assumes bpp == 24 & bits are packed low */
1466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /*           (probably need to use RShift, RMask, etc.) */
1467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >> 16) & 0xff);
1468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth == 16) {
1475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ush red, green, blue;
1476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        src = rpng2_info.row_pointers[row];
1478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (bg_image)
1479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src2 = bg_data + row*bg_rowbytes;
1480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        dest = ximage->data + row*ximage_rowbytes;
1481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (rpng2_info.channels == 3) {
1482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = rpng2_info.width;  i > 0;  --i) {
1483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                red   = ((ush)(*src) << 8);
1484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++src;
1485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                green = ((ush)(*src) << 8);
1486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++src;
1487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                blue  = ((ush)(*src) << 8);
1488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                ++src;
1489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pixel = ((red   >> RShift) & RMask) |
1490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((green >> GShift) & GMask) |
1491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((blue  >> BShift) & BMask);
1492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                /* recall that we set ximage->byte_order = MSBFirst above */
1493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (char)((pixel >>  8) & 0xff);
1494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (char)( pixel        & 0xff);
1495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else /* if (rpng2_info.channels == 4) */ {
1497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = rpng2_info.width;  i > 0;  --i) {
1498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                r = *src++;
1499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                g = *src++;
1500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                b = *src++;
1501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                a = *src++;
1502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (bg_image) {
1503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_red   = *src2++;
1504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_green = *src2++;
1505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    bg_blue  = *src2++;
1506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (a == 255) {
1508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = ((ush)r << 8);
1509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = ((ush)g << 8);
1510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = ((ush)b << 8);
1511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else if (a == 0) {
1512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = ((ush)bg_red   << 8);
1513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = ((ush)bg_green << 8);
1514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = ((ush)bg_blue  << 8);
1515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {
1516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* this macro (from png.h) composites the foreground
1517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     * and background values and puts the result back into
1518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     * the first argument (== fg byte here:  safe) */
1519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    alpha_composite(r, r, a, bg_red);
1520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    alpha_composite(g, g, a, bg_green);
1521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    alpha_composite(b, b, a, bg_blue);
1522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = ((ush)r << 8);
1523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = ((ush)g << 8);
1524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = ((ush)b << 8);
1525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                pixel = ((red   >> RShift) & RMask) |
1527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((green >> GShift) & GMask) |
1528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((blue  >> BShift) & BMask);
1529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                /* recall that we set ximage->byte_order = MSBFirst above */
1530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (char)((pixel >>  8) & 0xff);
1531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (char)( pixel        & 0xff);
1532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* depth == 8 */ {
1536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* GRR:  add 8-bit support */
1538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Display after every 16 rows or when on one of last two rows.  (Region
1544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    may include previously displayed lines due to interlacing--i.e., not
1545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    contiguous.  Also, second-to-last row is final one in interlaced images
1546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    with odd number of rows.)  For demos, flush (and delay) after every 16th
1547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    row so "sparse" passes don't go twice as fast.
1548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) {
1551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
1552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)firstrow, rpng2_info.width, row - firstrow + 1);
1553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFlush(display);
1554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rows = 0;
1555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        usleep(usleep_duration);
1556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else
1557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) {
1558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
1559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)firstrow, rpng2_info.width, row - firstrow + 1);
1560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFlush(display);
1561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rows = 0;
1562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_finish_display(void)
1571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning rpng2_x_finish_display()\n"))
1573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* last row has already been displayed by rpng2_x_display_row(), so we
1575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * have nothing to do here except set a flag and let the user know that
1576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the image is done */
1577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    rpng2_info.state = kDone;
1579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    printf(
1580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      "Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\n");
1581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fflush(stdout);
1582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_redisplay_image(ulg startcol, ulg startrow,
1589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    ulg width, ulg height)
1590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_red   = rpng2_info.bg_red;
1592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_green = rpng2_info.bg_green;
1593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch bg_blue  = rpng2_info.bg_blue;
1594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch *src, *src2=NULL;
1595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *dest;
1596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r, g, b, a;
1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i, row, lastrow = 0;
1598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg pixel;
1599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int ximage_rowbytes = ximage->bytes_per_line;
1600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "beginning display loop (image_channels == %d)\n",
1603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      rpng2_info.channels))
1604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "   (width = %ld, rowbytes = %d, ximage_rowbytes = %d)\n",
1605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      rpng2_info.width, rpng2_info.rowbytes, ximage_rowbytes))
1606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "   (bpp = %d)\n", ximage->bits_per_pixel))
1607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "   (byte_order = %s)\n", ximage->byte_order == MSBFirst?
1608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
1609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Aside from the use of the rpng2_info struct and of src2 (for background
1612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    image), this routine is identical to rpng_x_display_image() in the non-
1613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    progressive version of the program--for the simple reason that redisplay
1614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    of the image against a new background happens after the image is fully
1615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    decoded and therefore is, by definition, non-progressive.
1616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (depth == 24 || depth == 32) {
1619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ulg red, green, blue;
1620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int bpp = ximage->bits_per_pixel;
1621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (lastrow = row = startrow;  row < startrow+height;  ++row) {
1623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src = rpng2_info.image_data + row*rpng2_info.rowbytes;
1624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (bg_image)
1625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                src2 = bg_data + row*bg_rowbytes;
1626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = ximage->data + row*ximage_rowbytes;
1627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (rpng2_info.channels == 3) {
1628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = rpng2_info.width;  i > 0;  --i) {
1629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = *src++;
1630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = *src++;
1631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = *src++;
1632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef NO_24BIT_MASKS
1633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red   << RShift) |
1634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (green << GShift) |
1635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (blue  << BShift);
1636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (bpp == 32) {
1638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 24) & 0xff);
1639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this assumes bpp == 24 & bits are packed low */
1644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* (probably need to use RShift, RMask, etc.) */
1645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;
1651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = (GShift < 0)? green << (-GShift) : green >> GShift;
1652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;
1653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);
1654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (bpp == 32) {
1656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 24) & 0xff);
1657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* GRR BUG */
1662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this assumes bpp == 24 & bits are packed low */
1663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* (probably need to use RShift/RMask/etc. here, too) */
1664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else /* if (rpng2_info.channels == 4) */ {
1672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = rpng2_info.width;  i > 0;  --i) {
1673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    r = *src++;
1674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    g = *src++;
1675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    b = *src++;
1676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    a = *src++;
1677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (bg_image) {
1678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        bg_red   = *src2++;
1679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        bg_green = *src2++;
1680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        bg_blue  = *src2++;
1681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (a == 255) {
1683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = r;
1684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = g;
1685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = b;
1686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else if (a == 0) {
1687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = bg_red;
1688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = bg_green;
1689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = bg_blue;
1690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this macro (from png.h) composites the foreground
1692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * and background values and puts the result into the
1693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * first argument */
1694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(red,   r, a, bg_red);
1695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(green, g, a, bg_green);
1696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(blue,  b, a, bg_blue);
1697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef NO_24BIT_MASKS
1699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red   << RShift) |
1700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (green << GShift) |
1701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            (blue  << BShift);
1702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (bpp == 32) {
1704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 24) & 0xff);
1705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this assumes bpp == 24 & bits are packed low */
1710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* (probably need to use RShift, RMask, etc.) */
1711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;
1717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = (GShift < 0)? green << (-GShift) : green >> GShift;
1718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;
1719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);
1720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (bpp == 32) {
1722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 24) & 0xff);
1723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* GRR BUG */
1728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this assumes bpp == 24 & bits are packed low */
1729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* (probably need to use RShift/RMask/etc. here, too) */
1730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >> 16) & 0xff);
1731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)((pixel >>  8) & 0xff);
1732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = (char)( pixel        & 0xff);
1733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* display after every 16 lines */
1738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (((row+1) & 0xf) == 0) {
1739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
1740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (int)lastrow, rpng2_info.width, 16);
1741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XFlush(display);
1742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                lastrow = row + 1;
1743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if (depth == 16) {
1747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ush red, green, blue;
1748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (lastrow = row = startrow;  row < startrow+height;  ++row) {
1750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            src = rpng2_info.row_pointers[row];
1751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (bg_image)
1752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                src2 = bg_data + row*bg_rowbytes;
1753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = ximage->data + row*ximage_rowbytes;
1754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (rpng2_info.channels == 3) {
1755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = rpng2_info.width;  i > 0;  --i) {
1756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    red   = ((ush)(*src) << 8);
1757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++src;
1758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    green = ((ush)(*src) << 8);
1759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++src;
1760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    blue  = ((ush)(*src) << 8);
1761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++src;
1762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = ((red   >> RShift) & RMask) |
1763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((green >> GShift) & GMask) |
1764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((blue  >> BShift) & BMask);
1765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            } else /* if (rpng2_info.channels == 4) */ {
1770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                for (i = rpng2_info.width;  i > 0;  --i) {
1771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    r = *src++;
1772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    g = *src++;
1773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    b = *src++;
1774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    a = *src++;
1775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (bg_image) {
1776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        bg_red   = *src2++;
1777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        bg_green = *src2++;
1778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        bg_blue  = *src2++;
1779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (a == 255) {
1781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = ((ush)r << 8);
1782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = ((ush)g << 8);
1783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = ((ush)b << 8);
1784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else if (a == 0) {
1785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = ((ush)bg_red   << 8);
1786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = ((ush)bg_green << 8);
1787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = ((ush)bg_blue  << 8);
1788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* this macro (from png.h) composites the foreground
1790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * and background values and puts the result back into
1791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         * the first argument (== fg byte here:  safe) */
1792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(r, r, a, bg_red);
1793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(g, g, a, bg_green);
1794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        alpha_composite(b, b, a, bg_blue);
1795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        red   = ((ush)r << 8);
1796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        green = ((ush)g << 8);
1797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        blue  = ((ush)b << 8);
1798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    pixel = ((red   >> RShift) & RMask) |
1800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((green >> GShift) & GMask) |
1801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            ((blue  >> BShift) & BMask);
1802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    /* recall that we set ximage->byte_order = MSBFirst above */
1803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)((pixel >>  8) & 0xff);
1804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (char)( pixel        & 0xff);
1805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* display after every 16 lines */
1808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (((row+1) & 0xf) == 0) {
1809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
1810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (int)lastrow, rpng2_info.width, 16);
1811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                XFlush(display);
1812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                lastrow = row + 1;
1813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else /* depth == 8 */ {
1817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* GRR:  add 8-bit support */
1819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Trace((stderr, "calling final XPutImage()\n"))
1823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (lastrow < startrow+height) {
1824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
1825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (int)lastrow, rpng2_info.width, rpng2_info.height-lastrow);
1826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFlush(display);
1827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
1828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng2_x_redisplay_image() */
1830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef FEATURE_LOOP
1836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_reload_bg_image(void)
1838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    char *dest;
1840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r1, r2, g1, g2, b1, b2;
1841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
1842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int k, hmax, max;
1843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int xidx, yidx, yidx_max;
1844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int even_odd_vert, even_odd_horiz, even_odd;
1845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int invert_gradient2 = (bg[pat].type & 0x08);
1846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int invert_column;
1847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ulg i, row;
1848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bgscale = (pat == 0)? 8 : bgscale_default;
1851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    yidx_max = bgscale - 1;
1852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Vertical gradients (ramps) in NxN squares, alternating direction and
1855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    colors (N == bgscale).
1856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((bg[pat].type & 0x07) == 0) {
1859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch r1_min  = rgb[bg[pat].rgb1_min].r;
1860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch g1_min  = rgb[bg[pat].rgb1_min].g;
1861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch b1_min  = rgb[bg[pat].rgb1_min].b;
1862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch r2_min  = rgb[bg[pat].rgb2_min].r;
1863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch g2_min  = rgb[bg[pat].rgb2_min].g;
1864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch b2_min  = rgb[bg[pat].rgb2_min].b;
1865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
1866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
1867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
1868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
1869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
1870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
1871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            yidx = (int)(row % bgscale);
1874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            even_odd_vert = (int)((row / bgscale) & 1);
1875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r1 = r1_min + (r1_diff * yidx) / yidx_max;
1877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g1 = g1_min + (g1_diff * yidx) / yidx_max;
1878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b1 = b1_min + (b1_diff * yidx) / yidx_max;
1879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
1880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
1881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
1882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r2 = r2_min + (r2_diff * yidx) / yidx_max;
1884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g2 = g2_min + (g2_diff * yidx) / yidx_max;
1885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b2 = b2_min + (b2_diff * yidx) / yidx_max;
1886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
1887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
1888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
1889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = (char *)bg_data + row*bg_rowbytes;
1891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
1892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                even_odd_horiz = (int)((i / bgscale) & 1);
1893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                even_odd = even_odd_vert ^ even_odd_horiz;
1894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                invert_column =
1895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (even_odd_horiz && (bg[pat].type & 0x10));
1896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (even_odd == 0) {        /* gradient #1 */
1897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if (invert_column) {
1898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r1_inv;
1899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g1_inv;
1900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b1_inv;
1901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r1;
1903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g1;
1904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b1;
1905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {                    /* gradient #2 */
1907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if ((invert_column && invert_gradient2) ||
1908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (!invert_column && !invert_gradient2))
1909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    {
1910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r2;       /* not inverted or */
1911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g2;       /*  doubly inverted */
1912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b2;
1913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    } else {
1914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = r2_inv;
1915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = g2_inv;   /* singly inverted */
1916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dest++ = b2_inv;
1917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    }
1918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
1919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Soft gradient-diamonds with scale = bgscale.  Code contributed by Adam
1924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    M. Costello.
1925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if ((bg[pat].type & 0x07) == 1) {
1928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hmax = (bgscale-1)/2;   /* half the max weight of a color */
1930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        max = 2*hmax;           /* the max weight of a color */
1931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        r1 = rgb[bg[pat].rgb1_max].r;
1933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g1 = rgb[bg[pat].rgb1_max].g;
1934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        b1 = rgb[bg[pat].rgb1_max].b;
1935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        r2 = rgb[bg[pat].rgb2_max].r;
1936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g2 = rgb[bg[pat].rgb2_max].g;
1937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        b2 = rgb[bg[pat].rgb2_max].b;
1938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            yidx = (int)(row % bgscale);
1941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (yidx > hmax)
1942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                yidx = bgscale-1 - yidx;
1943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = (char *)bg_data + row*bg_rowbytes;
1944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
1945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                xidx = (int)(i % bgscale);
1946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (xidx > hmax)
1947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    xidx = bgscale-1 - xidx;
1948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                k = xidx + yidx;
1949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*r1 + (max-k)*r2) / max;
1950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*g1 + (max-k)*g2) / max;
1951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                *dest++ = (k*b1 + (max-k)*b2) / max;
1952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
1954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
1956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
1957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    soids will equal bgscale?].  This one is slow but very cool.  Code con-
1958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    tributed by Pieter S. van der Meulen (originally in Smalltalk).
1959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------*/
1960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } else if ((bg[pat].type & 0x07) == 2) {
1962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        uch ch;
1963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int ii, x, y, hw, hh, grayspot;
1964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double freq, rotate, saturate, gray, intensity;
1965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double angle=0.0, aoffset=0.0, maxDist, dist;
1966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
1967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hh = (int)(rpng2_info.height / 2);
1969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        hw = (int)(rpng2_info.width / 2);
1970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* variables for radial waves:
1972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]
1973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   freq:  number of color beams originating from the center
1974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   grayspot:  size of the graying center area (anti-alias)
1975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   rotate:  rotation of the beams as a function of radius
1976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *   saturate:  saturation of beams' shape azimuthally
1977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         */
1978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        angle = CLIP(angle, 0.0, 360.0);
1979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
1980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        freq = MAX((double)bg[pat].bg_freq, 0.0);
1981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        saturate = (double)bg[pat].bg_bsat * 0.1;
1982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rotate = (double)bg[pat].bg_brot * 0.1;
1983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        gray = 0.0;
1984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        intensity = 0.0;
1985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        maxDist = (double)((hw*hw) + (hh*hh));
1986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (row = 0;  row < rpng2_info.height;  ++row) {
1988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            y = (int)(row - hh);
1989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dest = (char *)bg_data + row*bg_rowbytes;
1990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0;  i < rpng2_info.width;  ++i) {
1991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                x = (int)(i - hw);
1992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                angle = (x == 0)? PI_2 : atan((double)y / (double)x);
1993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
1994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                gray = MIN(1.0, gray);
1995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                dist = (double)((x*x) + (y*y)) / maxDist;
1996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                intensity = cos((angle+(rotate*dist*PI)) * freq) *
1997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray * saturate;
1998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
1999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                hue = (angle + PI) * INV_PI_360 + aoffset;
2000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
2001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s = MIN(MAX(s,0.0), 1.0);
2002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                v = MIN(MAX(intensity,0.0), 1.0);
2003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (s == 0.0) {
2005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ch = (uch)(v * 255.0);
2006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
2007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
2008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = ch;
2009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                } else {
2010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if ((hue < 0.0) || (hue >= 360.0))
2011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        hue -= (((int)(hue / 360.0)) * 360.0);
2012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    hue /= 60.0;
2013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ii = (int)hue;
2014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    f = hue - (double)ii;
2015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    p = (1.0 - s) * v;
2016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    q = (1.0 - (s * f)) * v;
2017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    t = (1.0 - (s * (1.0 - f))) * v;
2018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    if      (ii == 0) { red = v; green = t; blue = p; }
2019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 1) { red = q; green = v; blue = p; }
2020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 2) { red = p; green = v; blue = t; }
2021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 3) { red = p; green = q; blue = v; }
2022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 4) { red = t; green = p; blue = v; }
2023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    else if (ii == 5) { red = v; green = p; blue = q; }
2024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(red * 255.0);
2025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(green * 255.0);
2026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    *dest++ = (uch)(blue * 255.0);
2027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
2028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
2030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
2031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end function rpng2_x_reload_bg_image() */
2033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int is_number(char *p)
2039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    while (*p) {
2041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (!isdigit(*p))
2042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return FALSE;
2043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ++p;
2044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
2045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return TRUE;
2046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* FEATURE_LOOP */
2049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void rpng2_x_cleanup(void)
2055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (bg_image && bg_data) {
2057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(bg_data);
2058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        bg_data = NULL;
2059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
2060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_info.image_data) {
2062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(rpng2_info.image_data);
2063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.image_data = NULL;
2064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
2065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (rpng2_info.row_pointers) {
2067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        free(rpng2_info.row_pointers);
2068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        rpng2_info.row_pointers = NULL;
2069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
2070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (ximage) {
2072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (ximage->data) {
2073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            free(ximage->data);           /* we allocated it, so we free it */
2074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            ximage->data = (char *)NULL;  /*  instead of XDestroyImage() */
2075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
2076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XDestroyImage(ximage);
2077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        ximage = NULL;
2078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
2079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_gc)
2081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFreeGC(display, gc);
2082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_window)
2084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XDestroyWindow(display, window);
2085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_colormap)
2087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFreeColormap(display, colormap);
2088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (have_nondefault_visual)
2090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        XFree(visual_list);
2091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic int rpng2_x_msb(ulg u32val)
2098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int i;
2100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i = 31;  i >= 0;  --i) {
2102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (u32val & 0x80000000L)
2103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        u32val <<= 1;
2105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
2106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return i;
2107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2108