summaryrefslogtreecommitdiff
path: root/contrib/gregbook
diff options
context:
space:
mode:
authorGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2000-03-21 05:13:06 -0600
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2009-04-06 16:04:52 -0500
commit520a764cd79aea2d282cb4d2b9187f0aafb72404 (patch)
tree0ca2fa9bece8a4d4eeeda049bd37b3fda61c6ee3 /contrib/gregbook
parenta77ef625a6bb7d7808e0f084df2ca1d9d2627154 (diff)
downloadlibpng-520a764cd79aea2d282cb4d2b9187f0aafb72404.tar.gz
Imported from libpng-1.0.6.tarv1.0.6
Diffstat (limited to 'contrib/gregbook')
-rw-r--r--contrib/gregbook/LICENSE26
-rw-r--r--contrib/gregbook/Makefile.unx (renamed from contrib/gregbook/makefile.unx)47
-rw-r--r--contrib/gregbook/Makefile.w32 (renamed from contrib/gregbook/makefile.w32)8
-rw-r--r--contrib/gregbook/README231
-rw-r--r--contrib/gregbook/README.w3253
-rw-r--r--contrib/gregbook/makevms.com28
-rw-r--r--contrib/gregbook/readpng.c21
-rw-r--r--contrib/gregbook/readpng.h4
-rw-r--r--contrib/gregbook/readpng2.c27
-rw-r--r--contrib/gregbook/readpng2.h5
-rw-r--r--contrib/gregbook/rpng-win.c76
-rw-r--r--contrib/gregbook/rpng-x.c292
-rw-r--r--contrib/gregbook/rpng2-win.c191
-rw-r--r--contrib/gregbook/rpng2-x.c425
-rw-r--r--contrib/gregbook/toucan.pngbin0 -> 12901 bytes
-rw-r--r--contrib/gregbook/wpng.c98
-rw-r--r--contrib/gregbook/writepng.c18
-rw-r--r--contrib/gregbook/writepng.h2
18 files changed, 1030 insertions, 522 deletions
diff --git a/contrib/gregbook/LICENSE b/contrib/gregbook/LICENSE
new file mode 100644
index 000000000..5714772d6
--- /dev/null
+++ b/contrib/gregbook/LICENSE
@@ -0,0 +1,26 @@
+ ---------------------------------------------------------------------------
+
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
+
+ This software is provided "as is," without warranty of any kind,
+ express or implied. In no event shall the author or contributors
+ be held liable for any damages arising in any way from the use of
+ this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute
+ it freely, subject to the following restrictions:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, disclaimer, and this list of conditions.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, disclaimer, and this list of conditions in the documenta-
+ tion and/or other materials provided with the distribution.
+ 3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+
+ This product includes software developed by Greg Roelofs
+ and contributors for the book, "PNG: The Definitive Guide,"
+ published by O'Reilly and Associates.
+
+ ---------------------------------------------------------------------------
diff --git a/contrib/gregbook/makefile.unx b/contrib/gregbook/Makefile.unx
index 93d46d17f..ed2e4f403 100644
--- a/contrib/gregbook/makefile.unx
+++ b/contrib/gregbook/Makefile.unx
@@ -1,6 +1,6 @@
# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make.
# Greg Roelofs
-# Last modified: 16 February 1999
+# Last modified: 28 February 2000
#
# The programs built by this makefile are described in the book,
# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
@@ -9,11 +9,12 @@
#
# Invoke this makefile from a shell prompt in the usual way; for example:
#
-# make -f makefile.unx
+# make -f Makefile.unx
#
# This makefile assumes libpng and zlib have already been built or downloaded
# and are both installed in /usr/local/{include,lib} (as indicated by the
-# PNGPATH and ZPATH macros below). Edit as appropriate.
+# PNG* and Z* macros below). Edit as appropriate--choose only ONE each of
+# the PNGINC, PNGLIB, ZINC and ZLIB lines.
#
# This makefile builds statically linked executables (against libpng and zlib,
# that is), but that can be changed by uncommenting the appropriate PNGLIB and
@@ -22,30 +23,38 @@
# macros --------------------------------------------------------------------
-PNGPATH = /usr/local
-PNGINC = -I$(PNGPATH)/include
-#PNGLIB = -L$(PNGPATH)/lib -lpng
-PNGLIB = $(PNGPATH)/lib/libpng.a
-
-ZPATH = /usr/local
-ZINC = -I$(ZPATH)/include
-#ZLIB = -L$(ZPATH)/lib -lz
-ZLIB = $(ZPATH)/lib/libz.a
-
-#XPATH = /usr/X11
-XPATH = /usr/X11R6
-XINC = -I$(XPATH)/include
-XLIB = -L$(XPATH)/lib -lX11
+PNGINC = -I/usr/local/include
+#PNGLIB = -L/usr/local/lib -lpng # dynamically linked against libpng
+PNGLIB = /usr/local/lib/libpng.a # statically linked against libpng
+# or:
+#PNGINC = -I../..
+#PNGLIB = -L../.. -lpng
+#PNGLIB = ../../libpng.a
+
+ZINC = -I/usr/local/include
+#ZLIB = -L/usr/local/lib -lz # dynamically linked against zlib
+ZLIB = /usr/local/lib/libz.a # statically linked against zlib
+#ZINC = -I../zlib
+#ZLIB = -L../zlib -lz
+#ZLIB = ../../../zlib/libz.a
+
+#XINC = -I/usr/include/X11 # old-style, stock X distributions
+#XLIB = -L/usr/lib/X11 -lX11
+#XINC = -I/usr/openwin/include/X11 # Sun workstations (OpenWindows)
+#XLIB = -L/usr/openwin/lib -lX11
+XINC = -I/usr/X11R6/include # new X distributions (XFree86, etc.)
+XLIB = -L/usr/X11R6/lib -lX11
INCS = $(PNGINC) $(ZINC) $(XINC)
RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm
-WLIBS = $(PNGLIB) $(ZLIB) -lm
+WLIBS = $(PNGLIB) $(ZLIB)
CC = gcc
LD = gcc
RM = rm -f
CFLAGS = -O -Wall $(INCS)
-# [note that -Wall is a gcc-specific compilation flag ("all warnings on")]
+# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
+# [-ansi, -pedantic and -W can also be used]
LDFLAGS =
O = .o
E =
diff --git a/contrib/gregbook/makefile.w32 b/contrib/gregbook/Makefile.w32
index e520ae75c..2a840229e 100644
--- a/contrib/gregbook/makefile.w32
+++ b/contrib/gregbook/Makefile.w32
@@ -10,14 +10,14 @@
# Invoke this makefile from a DOS prompt window via:
#
# %devstudio%\vc\bin\vcvars32.bat
-# nmake -nologo -f makefile.w32
+# nmake -nologo -f Makefile.w32
#
# where %devstudio% is the installation directory for MSVC / DevStudio. If
# you get "environment out of space" errors, create a desktop shortcut with
# "c:\windows\command.com /e:4096" as the program command line and set the
# working directory to this directory. Then double-click to open the new
# DOS-prompt window with a bigger environment and retry the commands above.
-#
+#
# This makefile assumes libpng and zlib have already been built or downloaded
# and are in subdirectories at the same level as the current subdirectory
# (as indicated by the PNGPATH and ZPATH macros below). Edit as appropriate.
@@ -32,12 +32,12 @@
# macros --------------------------------------------------------------------
-PNGPATH = ../libpng
+PNGPATH = ../..
PNGINC = -I$(PNGPATH)
#PNGLIB = $(PNGPATH)/pngdll.lib
PNGLIB = $(PNGPATH)/libpng.lib
-ZPATH = ../zlib
+ZPATH = ../../../zlib
ZINC = -I$(ZPATH)
#ZLIB = $(ZPATH)/zlibdll.lib
ZLIB = $(ZPATH)/zlibstat.lib
diff --git a/contrib/gregbook/README b/contrib/gregbook/README
index fa3871a7d..a8bbc2874 100644
--- a/contrib/gregbook/README
+++ b/contrib/gregbook/README
@@ -1,52 +1,183 @@
-PNG: The Definitive Guide: Source Code
+ ===========================
+ PNG: The Definitive Guide
+ ===========================
-Chapters 13, 14 and 15 of PNG: The Definitive Guide discuss three
+ Source Code
+
+Chapters 13, 14 and 15 of "PNG: The Definitive Guide" discuss three free,
cross-platform demo programs that show how to use the libpng reference
-library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is a
-very simple example that that shows how a standard file-viewer might use
-libpng, while the second is designed to process streaming data and shows how
-a web browser might be written. wpng is a simple command-line program that
-reads binary PPM files (the ``raw'' RGB subset of NetPBM) and converts them
-to PNG.
-
-The source code for all three demo programs currently compiles only under
-Unix and 32-bit Windows. It has been tested with gcc 2.7.2.3 under Linux and
-Solaris and with Microsoft Visual C++ 5.0 under Windows 95. Brief
-instructions for compiling the programs are included at the top of the
-makefiles; makefile.unx is the Unix version, and makefile.w32 is (you
-guessed it!) the version for 32-bit Windows. libpng and zlib are required.
-
-----------------------------------------------------------------------------
-
-License
-
-The source code to the demo programs may be used and distributed freely
-(even if you didn't buy the book--but feel free to do so at any time),
-subject to the terms of the following BSD-like license:
-
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above
- copyright notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, disclaimer, and this list of conditions in
- the documentation and/or other materials provided with the
- distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive
- Guide," published by O'Reilly and Associates.
-
-----------------------------------------------------------
-http://www.cdrom.com/pub/png/book/sources.html
+library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is
+a very simple example that that shows how a standard file-viewer might use
+libpng, while the second is designed to process streaming data and shows
+how a web browser might be written. wpng is a simple command-line program
+that reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets
+of PBMPLUS/NetPBM) and converts them to PNG.
+
+The source code for all three demo programs currently compiles under
+Unix, OpenVMS, and 32-bit Windows. (Special thanks to Martin Zinser,
+zinser@decus.de, for making the necessary changes for OpenVMS and for
+providing an appropriate build script.) Build instructions can be
+found below.
+
+Files:
+
+ README this file
+ README.w32 additional Windows-specific information
+ LICENSE terms of distribution and reuse (BSD-like)
+
+ Makefile.unx Unix makefile
+ Makefile.w32 Windows (MSVC) makefile
+ makevms.com OpenVMS build script
+
+ rpng-win.c Windows front end for the basic viewer
+ rpng-x.c X Window System (Unix, OpenVMS) front end
+ readpng.c generic back end for the basic viewer
+ readpng.h header file for the basic viewer
+
+ rpng2-win.c Windows front end for the progressive viewer
+ rpng2-x.c X front end for the progressive viewer
+ readpng2.c generic back end for the progressive viewer
+ readpng2.h header file for the progressive viewer
+
+ wpng.c generic (text) front end for the converter
+ writepng.c generic back end for the converter
+ writepng.h header file for the converter
+
+ toucan.png transparent PNG for testing (by Stefan Schneider)
+
+Note that the programs are designed to be functional, but their primary
+purpose is to demonstrate how to use libpng to add PNG support to other
+programs. As such, their user interfaces are crude and definitely not
+intended for everyday use.
+
+Please see http://www.cdrom.com/pub/png/pngbook.html for further infor-
+mation and links to the latest version of the source code, and Chapters
+13-15 of the book for detailed discussion of the three programs.
+
+Greg Roelofs
+19 March 2000
+
+
+BUILD INSTRUCTIONS
+
+ - Prerequisites:
+
+ - zlib ftp://ftp.cdrom.com/pub/infozip/zlib/zlib.html
+ - libpng http://www.cdrom.com/pub/png/pngcode.html
+ - pngbook http://www.cdrom.com/pub/png/book/sources.html
+
+ The pngbook demo programs are explicitly designed to demonstrate proper
+ coding techniques for using the libpng reference library. As a result,
+ you need to download and build both zlib (on which libpng depends) and
+ libpng. A common build setup is to place the zlib, libpng and pngbook
+ subdirectory trees ("folders") in the same parent directory. Then the
+ libpng build can refer to files in ../zlib (or ..\zlib or [-.zlib]),
+ and similarly for the pngbook build.
+
+ Note that all three packages are designed to be built from a command
+ line by default; those who wish to use a graphical or other integrated
+ development environments are on their own.
+
+
+ - Unix:
+
+ Unpack the latest pngbook sources (which should correspond to this
+ README file) into a directory and change into that directory.
+
+ Copy Makefile.unx to Makefile and edit the PNG* and Z* variables
+ appropriately (possibly also the X* variables if necessary).
+
+ make
+
+ There is no "install" target, so copy the three executables somewhere
+ in your path or run them from the current directory. All three will
+ print a basic usage screen when run without any command-line arguments;
+ see the book for more details.
+
+
+ - Windows:
+
+ Unpack the latest pngbook sources (which should correspond to this
+ README file) into a folder, open a "DOS shell" or "command prompt"
+ or equivalent command-line window, and cd into the folder where you
+ unpacked the source code.
+
+ For MSVC, set up the necessary environment variables by invoking
+
+ %devstudio%\vc\bin\vcvars32.bat
+
+ where where %devstudio% is the installation directory for MSVC /
+ DevStudio. If you get "environment out of space" errors under 95/98,
+ create a desktop shortcut with "c:\windows\command.com /e:4096" as
+ the program command line and set the working directory to the pngbook
+ directory. Then double-click to open the new DOS-prompt window with
+ a bigger environment and retry the commands above.
+
+ Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables
+ appropriately (possibly also the "INC" and "LIB" variables if needed).
+ Note that the names of the dynamic and static libpng and zlib libraries
+ used in the makefile may change in later releases of the libraries.
+ Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work.
+ This makefile therefore builds statically linked executables, but if
+ the DLL problems ever get fixed, uncommenting the appropriate PNGLIB
+ and ZLIB lines will build dynamically linked executables instead.
+
+ Do the build by typing
+
+ nmake
+
+ The result should be three executables: rpng-win.exe, rpng2-win.exe,
+ and wpng.exe. Copy them somewhere in your PATH or run them from the
+ current folder. Unlike the Unix versions, the two windowed programs
+ (rpng and rpng2) do not display a usage screen when invoked without
+ command-line arguments; see README.w32 for brief help or the book for
+ details. Note that the programs use the Unix-style "-" character to
+ specify options, instead of the more common DOS/Windows "/" character.
+
+
+ - OpenVMS:
+
+ Unpack the pngbook sources into a subdirectory and change into that
+ subdirectory.
+
+ Edit makevms.com appropriately, specifically the zpath and pngpath
+ variables.
+
+ @makevms
+
+ To run the programs, they probably first need to be set up as "foreign
+ symbols," with "disk" and "dir" set appropriately:
+
+ $ rpng == "$disk:[dir]rpng-x.exe"
+ $ rpng2 == "$disk:[dir]rpng2-x.exe"
+ $ wpng == "$disk:[dir]wpng.exe"
+
+ All three will print a basic usage screen when run without any command-
+ line arguments; see the book for more details. Note that the options
+ style is Unix-like, i.e., preceded by "-" rather than "/".
+
+
+RUNNING THE PROGRAMS: (VERY) BRIEF INTRO
+
+ rpng is a simple PNG viewer that can display transparent PNGs with a
+ specified background color; for example,
+
+ rpng -bgcolor #ff0000 toucan.png
+
+ would display the image with a red background. rpng2 is a progressive
+ viewer that simulates a web browser in some respects; it can display
+ images against either a background color or a dynamically generated
+ background image. For example:
+
+ rpng2 -bgpat 16 toucan.png
+
+ wpng is a purely command-line image converter from binary PBMPLUS/NetPBM
+ format (.pgm or .ppm) to PNG; for example,
+
+ wpng -time < toucan.ppm > toucan.png
+
+ would convert the specified PPM file (using redirection) to PNG, auto-
+ matically setting the PNG modification-time chunk.
+
+ All options can be abbreviated to the shortest unique value; for example,
+ "-bgc" for -bgcolor (versus "-bgp" for -bgpat), or "-g" for -gamma.
diff --git a/contrib/gregbook/README.w32 b/contrib/gregbook/README.w32
new file mode 100644
index 000000000..736c00145
--- /dev/null
+++ b/contrib/gregbook/README.w32
@@ -0,0 +1,53 @@
+See the main README file for basic instructions on compiling and running
+the programs. See http://www.cdrom.com/pub/png/pngbook.html for further
+information and links to the source code, and Chapters 13-15 of the book
+for detailed discussion of the three programs.
+
+Since the two viewers, rpng and rpng2, are both designed to write infor-
+mation to the console (i.e., a DOS-window command line) while displaying
+the image in a graphical window--and since I haven't yet figured out how
+to do that under Windows--here are the usage screens for the two programs:
+
+
+rpng-win 1.02 of 19 March 2000: Simple PNG Viewer for Windows
+ Compiled with libpng 1.0.5; using libpng 1.0.5.
+ Compiled with zlib 1.1.3; using zlib 1.1.3.
+
+Usage: rpng-win [-gamma exp] [-bgcolor bg] file.png
+ exp transfer-function exponent (``gamma'') of the display
+ system in floating-point format (e.g., ``2.2''); equal
+ to the product of the lookup-table exponent (varies)
+ and the CRT exponent (usually 2.2); must be positive
+ bg desired background color in 7-character hex RGB format
+ (e.g., ``#ff7f00'' for orange: same as HTML colors);
+ used with transparent images
+
+Press Q, Esc or mouse button 1 after image is displayed to quit.
+
+
+rpng2-win 1.04 of 19 March 2000: Progressive PNG Viewer for Windows
+ Compiled with libpng 1.0.5; using libpng 1.0.5.
+ Compiled with zlib 1.1.3; using zlib 1.1.3.
+
+Usage: rpng2-win [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing] file.png
+
+ exp transfer-function exponent (``gamma'') of the display
+ system in floating-point format (e.g., ``2.2''); equal
+ to the product of the lookup-table exponent (varies)
+ and the CRT exponent (usually 2.2); must be positive
+ bg desired background color in 7-character hex RGB format
+ (e.g., ``#ff7f00'' for orange: same as HTML colors);
+ used with transparent images; overrides -bgpat
+ pat desired background pattern number (1-16); used with
+ transparent images; overrides -bgcolor
+ -timing enables delay for every block read, to simulate modem
+ download of image (~36 Kbps)
+
+Press Q, Esc or mouse button 1 after image is displayed to quit.
+
+
+The usage screen for the third (non-windowed) program, wpng, can be seen
+simply by invoking it without any parameters (``wpng'').
+
+Greg Roelofs
+19 March 2000
diff --git a/contrib/gregbook/makevms.com b/contrib/gregbook/makevms.com
index 2ee2eb694..b8cbfae37 100644
--- a/contrib/gregbook/makevms.com
+++ b/contrib/gregbook/makevms.com
@@ -1,11 +1,22 @@
$!------------------------------------------------------------------------------
-$! make Contrib programs of libpng under OpenVMS
+$! make "PNG: The Definitive Guide" demo programs (for X) under OpenVMS
$!
+$! Script created by Martin Zinser for libpng; modified by Greg Roelofs
+$! for standalone pngbook source distribution.
$!
-$! Look for the compiler used
$!
-$ zlibsrc = "[---.zlib]"
-$ ccopt="/include=(''zlibsrc',[--])"
+$! Set locations where zlib and libpng sources live.
+$!
+$ zpath = "[-.zlib]"
+$ pngpath = "[-.libpng]"
+$!
+$! USE THESE INSTEAD if building from libpng's [.contrib.gregbook] directory:
+$! zpath = "[---.zlib]"
+$! pngpath = "[--]"
+$!
+$! Look for the compiler used.
+$!
+$ ccopt="/include=(''zpath',''pngpath')"
$ if f$getsyi("HW_MODEL").ge.1024
$ then
$ ccopt = "/prefix=all"+ccopt
@@ -29,13 +40,16 @@ $ comp = "__decc__=1"
$ endif
$ endif
$ open/write lopt lib.opt
-$ write lopt "[--]libpng.olb/lib"
-$ write lopt "''zlibsrc'libz.olb/lib"
+$ write lopt "''pngpath'libpng.olb/lib"
+$ write lopt "''zpath'libz.olb/lib"
$ close lopt
$ open/write xopt x11.opt
$ write xopt "sys$library:decw$xlibshr.exe/share"
$ close xopt
-$ write sys$output "Compiling PNG contrib programs ..."
+$!
+$! Build 'em.
+$!
+$ write sys$output "Compiling PNG book programs ..."
$ CALL MAKE readpng.OBJ "cc ''CCOPT' readpng" -
readpng.c readpng.h
$ CALL MAKE readpng2.OBJ "cc ''CCOPT' readpng2" -
diff --git a/contrib/gregbook/readpng.c b/contrib/gregbook/readpng.c
index 546293f7d..dc948eecc 100644
--- a/contrib/gregbook/readpng.c
+++ b/contrib/gregbook/readpng.c
@@ -4,7 +4,7 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -32,8 +32,13 @@
#include <stdio.h>
#include <stdlib.h>
-#include "png.h" /* libpng header; includes zlib.h */
-#include "readpng.h" /* typedefs, common macros, public prototypes */
+#include "png.h" /* libpng header; includes zlib.h */
+#include "readpng.h" /* typedefs, common macros, public prototypes */
+
+/* future versions of libpng will provide this macro: */
+#ifndef png_jmpbuf
+# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#endif
static png_structp png_ptr = NULL;
@@ -44,7 +49,7 @@ int bit_depth, color_type;
uch *image_data = NULL;
-void readpng_version_info()
+void readpng_version_info(void)
{
fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
PNG_LIBPNG_VER_STRING, png_libpng_ver);
@@ -55,7 +60,7 @@ void readpng_version_info()
/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
-int readpng_init(FILE *infile, long *pWidth, long *pHeight)
+int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
{
uch sig[8];
@@ -89,7 +94,7 @@ int readpng_init(FILE *infile, long *pWidth, long *pHeight)
/* setjmp() must be called in every function that calls a PNG-reading
* libpng function */
- if (setjmp(png_jmp_env(png_ptr))) {
+ if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return 2;
}
@@ -130,7 +135,7 @@ int readpng_get_bgcolor(uch *red, uch *green, uch *blue)
/* setjmp() must be called in every function that calls a PNG-reading
* libpng function */
- if (setjmp(png_jmp_env(png_ptr))) {
+ if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return 2;
}
@@ -184,7 +189,7 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
/* setjmp() must be called in every function that calls a PNG-reading
* libpng function */
- if (setjmp(png_jmp_env(png_ptr))) {
+ if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
}
diff --git a/contrib/gregbook/readpng.h b/contrib/gregbook/readpng.h
index 31780c568..1c19aca99 100644
--- a/contrib/gregbook/readpng.h
+++ b/contrib/gregbook/readpng.h
@@ -4,7 +4,7 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -54,7 +54,7 @@ typedef unsigned long ulg;
void readpng_version_info(void);
-int readpng_init(FILE *infile, long *pWidth, long *pHeight);
+int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight);
int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue);
diff --git a/contrib/gregbook/readpng2.c b/contrib/gregbook/readpng2.c
index 19d1f18c2..8f70c834b 100644
--- a/contrib/gregbook/readpng2.c
+++ b/contrib/gregbook/readpng2.c
@@ -4,7 +4,7 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -30,10 +30,10 @@
---------------------------------------------------------------------------*/
-#include <stdlib.h> /* for exit() prototype */
+#include <stdlib.h> /* for exit() prototype */
-#include "png.h" /* libpng header; includes zlib.h and setjmp.h */
-#include "readpng2.h" /* typedefs, common macros, public prototypes */
+#include "png.h" /* libpng header; includes zlib.h and setjmp.h */
+#include "readpng2.h" /* typedefs, common macros, public prototypes */
/* local prototypes */
@@ -47,7 +47,7 @@ static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
-void readpng2_version_info()
+void readpng2_version_info(void)
{
fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
PNG_LIBPNG_VER_STRING, png_libpng_ver);
@@ -70,7 +70,7 @@ int readpng2_check_sig(uch *sig, int num)
int readpng2_init(mainprog_info *mainprog_ptr)
{
- png_structp png_ptr; /* note: temporary variables! */
+ png_structp png_ptr; /* note: temporary variables! */
png_infop info_ptr;
@@ -98,7 +98,7 @@ int readpng2_init(mainprog_info *mainprog_ptr)
* but compatible error handlers must either use longjmp() themselves
* (as in this program) or exit immediately, so here we are: */
- if (setjmp(png_jmp_env(mainprog_ptr))) {
+ if (setjmp(mainprog_ptr->jmpbuf)) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return 2;
}
@@ -136,7 +136,7 @@ int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length)
/* setjmp() must be called in every function that calls a PNG-reading
* libpng function */
- if (setjmp(png_jmp_env(mainprog_ptr))) {
+ if (setjmp(mainprog_ptr->jmpbuf)) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
mainprog_ptr->png_ptr = NULL;
mainprog_ptr->info_ptr = NULL;
@@ -176,7 +176,7 @@ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr)
mainprog_ptr = png_get_progressive_ptr(png_ptr);
- if (mainprog_ptr == NULL) { /* we be hosed */
+ if (mainprog_ptr == NULL) { /* we be hosed */
fprintf(stderr,
"readpng2 error: main struct not recoverable in info_callback.\n");
fflush(stderr);
@@ -283,7 +283,7 @@ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr)
png_read_update_info(png_ptr, info_ptr);
- mainprog_ptr->rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+ mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);
mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr);
@@ -323,6 +323,11 @@ static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
mainprog_ptr = png_get_progressive_ptr(png_ptr);
+ /* save the pass number for optional use by the front end */
+
+ mainprog_ptr->pass = pass;
+
+
/* have libpng either combine the new row data with the existing row data
* from previous passes (if interlaced) or else just copy the new row
* into the main program's image buffer */
@@ -408,7 +413,7 @@ static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
fflush(stderr);
mainprog_ptr = png_get_error_ptr(png_ptr);
- if (mainprog_ptr == NULL) { /* we are completely hosed now */
+ if (mainprog_ptr == NULL) { /* we are completely hosed now */
fprintf(stderr,
"readpng2 severe error: jmpbuf not recoverable; terminating.\n");
fflush(stderr);
diff --git a/contrib/gregbook/readpng2.h b/contrib/gregbook/readpng2.h
index 2ffd77635..cbc1fd8c9 100644
--- a/contrib/gregbook/readpng2.h
+++ b/contrib/gregbook/readpng2.h
@@ -4,7 +4,7 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -61,7 +61,8 @@ typedef struct _mainprog_info {
uch *image_data;
uch **row_pointers;
jmp_buf jmpbuf;
- int passes; /* not used */
+ int passes; /* not used */
+ int pass;
int rowbytes;
int channels;
int need_bgcolor;
diff --git a/contrib/gregbook/rpng-win.c b/contrib/gregbook/rpng-win.c
index a75e609fa..51e1974ed 100644
--- a/contrib/gregbook/rpng-win.c
+++ b/contrib/gregbook/rpng-win.c
@@ -16,7 +16,16 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Changelog:
+ - 1.00: initial public release
+ - 1.01: modified to allow abbreviated options; fixed long/ulong mis-
+ match; switched to png_jmpbuf() macro
+ - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed
+ command-line parsing bug
+
+ ---------------------------------------------------------------------------
+
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -43,7 +52,7 @@
#define PROGNAME "rpng-win"
#define LONGNAME "Simple PNG Viewer for Windows"
-#define VERSION "1.0 of 20 February 1999"
+#define VERSION "1.02 of 19 March 2000"
#include <stdio.h>
#include <stdlib.h>
@@ -53,7 +62,7 @@
/* #define DEBUG : this enables the Trace() macros */
-#include "readpng.h" /* typedefs, common macros, readpng prototypes */
+#include "readpng.h" /* typedefs, common macros, readpng prototypes */
/* could just include png.h, but this macro is the only thing we need
@@ -61,10 +70,10 @@
* only happen with alpha (which could easily be avoided with
* "ush acopy = (alpha);") */
-#define alpha_composite(composite, fg, alpha, bg) { \
- ush temp = ((ush)(fg)*(ush)(alpha) + \
- (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
- (composite) = (uch)((temp + (temp >> 8)) >> 8); \
+#define alpha_composite(composite, fg, alpha, bg) { \
+ ush temp = ((ush)(fg)*(ush)(alpha) + \
+ (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
+ (composite) = (uch)((temp + (temp >> 8)) >> 8); \
}
@@ -78,7 +87,7 @@ LRESULT CALLBACK rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM);
static char titlebar[1024], *window_name = titlebar;
static char *progname = PROGNAME;
static char *appname = LONGNAME;
-static char *icon_name = PROGNAME; /* GRR: not (yet) used */
+static char *icon_name = PROGNAME; /* GRR: not (yet) used */
static char *filename;
static FILE *infile;
@@ -104,15 +113,15 @@ static HWND global_hwnd;
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
{
- char *args[1024]; /* arbitrary limit, but should suffice */
+ char *args[1024]; /* arbitrary limit, but should suffice */
char *p, *q, **argv = args;
int argc = 0;
int rc, alen, flen;
int error = 0;
int have_bg = FALSE;
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
+ double LUT_exponent; /* just the lookup table */
+ double CRT_exponent = 2.2; /* just the monitor */
+ double default_display_exponent; /* whole display system */
MSG msg;
@@ -199,20 +208,24 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
/* Now parse the command line for options and the PNG filename. */
while (*++argv && !error) {
- if (!strcmp(*argv, "-gamma")) {
+ if (!strncmp(*argv, "-gamma", 2)) {
if (!*++argv)
++error;
- display_exponent = atof(*argv);
- if (display_exponent <= 0.0)
- ++error;
- } else if (!strcmp(*argv, "-bgcolor")) {
+ else {
+ display_exponent = atof(*argv);
+ if (display_exponent <= 0.0)
+ ++error;
+ }
+ } else if (!strncmp(*argv, "-bgcolor", 2)) {
if (!*++argv)
++error;
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
- else
- have_bg = TRUE;
+ else {
+ bgstr = *argv;
+ if (strlen(bgstr) != 7 || bgstr[0] != '#')
+ ++error;
+ else
+ have_bg = TRUE;
+ }
} else {
if (**argv != '-') {
filename = *argv;
@@ -255,6 +268,9 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
fclose(infile);
}
+
+ /* usage screen */
+
if (error) {
fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
readpng_version_info();
@@ -265,7 +281,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
"\t\t to the product of the lookup-table exponent (varies)\n"
"\t\t and the CRT exponent (usually 2.2); must be positive\n"
" bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7f00'' for orange: same as HTML colors);\n"
+ "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
"\t\t used with transparent images\n"
"\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
"\n", PROGNAME, default_display_exponent);
@@ -336,6 +352,10 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
/* wait for the user to tell us when to quit */
+ printf(
+ "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+ fflush(stdout);
+
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
@@ -371,7 +391,7 @@ static int rpng_win_create_window(HINSTANCE hInst, int showmode)
if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
wimage_rowbytes*image_height)))
{
- return 4; /* fail */
+ return 4; /* fail */
}
/*---------------------------------------------------------------------------
@@ -477,7 +497,7 @@ static int rpng_win_display_image()
g = *src++;
b = *src++;
*dest++ = b;
- *dest++ = g; /* note reverse order */
+ *dest++ = g; /* note reverse order */
*dest++ = r;
}
} else /* if (image_channels == 4) */ {
@@ -582,15 +602,15 @@ LRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
/* wait for the user to tell us when to quit */
case WM_CHAR:
- switch (wP) { /* only need one, so ignore repeat count */
+ switch (wP) { /* only need one, so ignore repeat count */
case 'q':
case 'Q':
- case 0x1B: /* Esc key */
+ case 0x1B: /* Esc key */
PostQuitMessage(0);
}
return 0;
- case WM_LBUTTONDOWN: /* another way of quitting */
+ case WM_LBUTTONDOWN: /* another way of quitting */
case WM_DESTROY:
PostQuitMessage(0);
return 0;
diff --git a/contrib/gregbook/rpng-x.c b/contrib/gregbook/rpng-x.c
index 5f0a8a1fb..aea975d95 100644
--- a/contrib/gregbook/rpng-x.c
+++ b/contrib/gregbook/rpng-x.c
@@ -5,8 +5,8 @@
This program decodes and displays PNG images, with gamma correction and
optionally with a user-specified background color (in case the image has
transparency). It is very nearly the most basic PNG viewer possible.
- This version is for the X Window System (tested under Unix, but may work
- under VMS or OS/2 with a little tweaking).
+ This version is for the X Window System (tested by author under Unix and
+ by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking).
to do:
- 8-bit support
@@ -14,7 +14,17 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Changelog:
+ - 1.01: initial public release
+ - 1.02: modified to allow abbreviated options; fixed long/ulong mis-
+ match; switched to png_jmpbuf() macro
+ - 1.10: added support for non-default visuals; fixed X pixel-conversion
+ - 1.11: added extra set of parentheses to png_jmpbuf() macro; fixed
+ command-line parsing bug
+
+ ---------------------------------------------------------------------------
+
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -41,7 +51,7 @@
#define PROGNAME "rpng-x"
#define LONGNAME "Simple PNG Viewer for X"
-#define VERSION "1.01 of 31 March 1999"
+#define VERSION "1.11 of 19 March 2000"
#include <stdio.h>
#include <stdlib.h>
@@ -54,7 +64,7 @@
/* #define DEBUG : this enables the Trace() macros */
-#include "readpng.h" /* typedefs, common macros, readpng prototypes */
+#include "readpng.h" /* typedefs, common macros, readpng prototypes */
/* could just include png.h, but this macro is the only thing we need
@@ -95,15 +105,16 @@ static uch *image_data;
static char *displayname;
static XImage *ximage;
static Display *display;
-static int bitmap_order;
static int depth;
static Visual *visual;
-static int RPixelShift, GPixelShift, BPixelShift;
-static ulg RedMask, GreenMask, BlueMask;
+static XVisualInfo *visual_list;
+static int RShift, GShift, BShift;
+static ulg RMask, GMask, BMask;
static Window window;
static GC gc;
static Colormap colormap;
+static int have_nondefault_visual = FALSE;
static int have_colormap = FALSE;
static int have_window = FALSE;
/*
@@ -123,9 +134,9 @@ int main(int argc, char **argv)
int rc, alen, flen;
int error = 0;
int have_bg = FALSE;
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
+ double LUT_exponent; /* just the lookup table */
+ double CRT_exponent = 2.2; /* just the monitor */
+ double default_display_exponent; /* whole display system */
XEvent e;
KeySym k;
@@ -188,24 +199,29 @@ int main(int argc, char **argv)
/* Now parse the command line for options and the PNG filename. */
while (*++argv && !error) {
- if (!strcmp(*argv, "-display")) {
+ if (!strncmp(*argv, "-display", 2)) {
if (!*++argv)
++error;
- displayname = *argv;
- } else if (!strcmp(*argv, "-gamma")) {
+ else
+ displayname = *argv;
+ } else if (!strncmp(*argv, "-gamma", 2)) {
if (!*++argv)
++error;
- display_exponent = atof(*argv);
- if (display_exponent <= 0.0)
- ++error;
- } else if (!strcmp(*argv, "-bgcolor")) {
+ else {
+ display_exponent = atof(*argv);
+ if (display_exponent <= 0.0)
+ ++error;
+ }
+ } else if (!strncmp(*argv, "-bgcolor", 2)) {
if (!*++argv)
++error;
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
- else
- have_bg = TRUE;
+ else {
+ bgstr = *argv;
+ if (strlen(bgstr) != 7 || bgstr[0] != '#')
+ ++error;
+ else
+ have_bg = TRUE;
+ }
} else {
if (**argv != '-') {
filename = *argv;
@@ -222,8 +238,7 @@ int main(int argc, char **argv)
fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
++error;
} else {
- if ((rc = readpng_init(infile, (long *)(&image_width),
- (long *)(&image_height))) != 0) {
+ if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
switch (rc) {
case 1:
fprintf(stderr, PROGNAME
@@ -257,21 +272,25 @@ int main(int argc, char **argv)
fclose(infile);
}
+
+ /* usage screen */
+
if (error) {
fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
readpng_version_info();
fprintf(stderr, "\n"
- "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n"
- " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
- " exp \ttransfer-function exponent (``gamma'') of the display\n"
- "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
- "\t\t to the product of the lookup-table exponent (varies)\n"
- "\t\t and the CRT exponent (usually 2.2); must be positive\n"
- " bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7f00'' for orange: same as HTML colors);\n"
- "\t\t used with transparent images\n"
- "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
- "\n", PROGNAME, default_display_exponent);
+ "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n"
+ " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
+ " exp \ttransfer-function exponent (``gamma'') of the display\n"
+ "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
+ "\t\t to the product of the lookup-table exponent (varies)\n"
+ "\t\t and the CRT exponent (usually 2.2); must be positive\n"
+ " bg \tdesired background color in 7-character hex RGB format\n"
+ "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
+ "\t\t used with transparent images\n"
+ "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
+ "is displayed) to quit.\n"
+ "\n", PROGNAME, default_display_exponent);
exit(1);
}
@@ -344,6 +363,10 @@ int main(int argc, char **argv)
/* wait for the user to tell us when to quit */
+ printf(
+ "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+ fflush(stdout);
+
do
XNextEvent(display, &e);
while (!(e.type == ButtonPress && e.xbutton.button == Button1) &&
@@ -362,11 +385,13 @@ int main(int argc, char **argv)
-static int rpng_x_create_window()
+static int rpng_x_create_window(void)
{
uch *xdata;
+ int need_colormap = FALSE;
int screen, pad;
ulg bg_pixel = 0L;
+ ulg attrmask;
Window root;
XEvent e;
XGCValues gcvalues;
@@ -378,11 +403,15 @@ static int rpng_x_create_window()
XWMHints *wm_hints;
- bitmap_order = BitmapBitOrder(display);
screen = DefaultScreen(display);
depth = DisplayPlanes(display, screen);
root = RootWindow(display, screen);
+#ifdef DEBUG
+ XSynchronize(display, True);
+#endif
+
+#if 0
/* GRR: add 8-bit support */
if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {
fprintf(stderr,
@@ -394,27 +423,73 @@ static int rpng_x_create_window()
XMatchVisualInfo(display, screen, depth,
(depth == 8)? PseudoColor : TrueColor, &visual_info);
visual = visual_info.visual;
+#else
+ if (depth != 16 && depth != 24 && depth != 32) {
+ int visuals_matched = 0;
+
+ Trace((stderr, "default depth is %d: checking other visuals\n",
+ depth))
+
+ /* 24-bit first */
+ visual_info.screen = screen;
+ visual_info.depth = 24;
+ visual_list = XGetVisualInfo(display,
+ VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
+ if (visuals_matched == 0) {
+/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
+ fprintf(stderr, "default screen depth %d not supported, and no"
+ " 24-bit visuals found\n", depth);
+ return 2;
+ }
+ Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
+ visuals_matched))
+ visual = visual_list[0].visual;
+ depth = visual_list[0].depth;
+/*
+ colormap_size = visual_list[0].colormap_size;
+ visual_class = visual->class;
+ visualID = XVisualIDFromVisual(visual);
+ */
+ have_nondefault_visual = TRUE;
+ need_colormap = TRUE;
+ } else {
+ XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
+ visual = visual_info.visual;
+ }
+#endif
- RedMask = visual->red_mask;
- GreenMask = visual->green_mask;
- BlueMask = visual->blue_mask;
+ RMask = visual->red_mask;
+ GMask = visual->green_mask;
+ BMask = visual->blue_mask;
/* GRR: add/check 8-bit support */
- if (depth == 8) {
+ if (depth == 8 || need_colormap) {
colormap = XCreateColormap(display, root, visual, AllocNone);
if (!colormap) {
fprintf(stderr, "XCreateColormap() failed\n");
return 2;
}
have_colormap = TRUE;
- } else if (depth == 16) {
- RPixelShift = 15 - rpng_x_msb(RedMask); /* these are right-shifts */
- GPixelShift = 15 - rpng_x_msb(GreenMask);
- BPixelShift = 15 - rpng_x_msb(BlueMask);
- } else /* if (depth > 16) */ {
- RPixelShift = rpng_x_msb(RedMask) - 7; /* these are left-shifts */
- GPixelShift = rpng_x_msb(GreenMask) - 7;
- BPixelShift = rpng_x_msb(BlueMask) - 7;
+ }
+ if (depth == 15 || depth == 16) {
+ RShift = 15 - rpng_x_msb(RMask); /* these are right-shifts */
+ GShift = 15 - rpng_x_msb(GMask);
+ BShift = 15 - rpng_x_msb(BMask);
+ } else if (depth > 16) {
+#define NO_24BIT_MASKS
+#ifdef NO_24BIT_MASKS
+ RShift = rpng_x_msb(RMask) - 7; /* these are left-shifts */
+ GShift = rpng_x_msb(GMask) - 7;
+ BShift = rpng_x_msb(BMask) - 7;
+#else
+ RShift = 7 - rpng_x_msb(RMask); /* these are right-shifts, too */
+ GShift = 7 - rpng_x_msb(GMask);
+ BShift = 7 - rpng_x_msb(BMask);
+#endif
+ }
+ if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
+ fprintf(stderr, "rpng internal logic error: negative X shift(s)!\n");
+ return 2;
}
/*---------------------------------------------------------------------------
@@ -423,9 +498,16 @@ static int rpng_x_create_window()
attr.backing_store = Always;
attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
+ attrmask = CWBackingStore | CWEventMask;
+ if (have_nondefault_visual) {
+ attr.colormap = colormap;
+ attr.background_pixel = 0;
+ attr.border_pixel = 1;
+ attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
+ }
- window = XCreateWindow(display, root, 0, 0, image_width, image_height,
- 0, depth, InputOutput, visual, CWBackingStore | CWEventMask, &attr);
+ window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0,
+ depth, InputOutput, visual, attrmask, &attr);
if (window == None) {
fprintf(stderr, "XCreateWindow() failed\n");
@@ -446,8 +528,8 @@ static int rpng_x_create_window()
if ((size_hints = XAllocSizeHints()) != NULL) {
/* window will not be resizable */
size_hints->flags = PMinSize | PMaxSize;
- size_hints->min_width = size_hints->max_width = image_width;
- size_hints->min_height = size_hints->max_height = image_height;
+ size_hints->min_width = size_hints->max_width = (int)image_width;
+ size_hints->min_height = size_hints->max_height = (int)image_height;
}
if ((wm_hints = XAllocWMHints()) != NULL) {
@@ -469,13 +551,13 @@ static int rpng_x_create_window()
---------------------------------------------------------------------------*/
if (depth == 24 || depth == 32) {
- bg_pixel = ((ulg)bg_red << RPixelShift) |
- ((ulg)bg_green << GPixelShift) |
- ((ulg)bg_blue << BPixelShift);
+ bg_pixel = ((ulg)bg_red << RShift) |
+ ((ulg)bg_green << GShift) |
+ ((ulg)bg_blue << BShift);
} else if (depth == 16) {
- bg_pixel = ((((ulg)bg_red << 8) >> RPixelShift) & RedMask) |
- ((((ulg)bg_green << 8) >> GPixelShift) & GreenMask) |
- ((((ulg)bg_blue << 8) >> BPixelShift) & BlueMask);
+ bg_pixel = ((((ulg)bg_red << 8) >> RShift) & RMask) |
+ ((((ulg)bg_green << 8) >> GShift) & GMask) |
+ ((((ulg)bg_blue << 8) >> BShift) & BMask);
} else /* depth == 8 */ {
/* GRR: add 8-bit support */
@@ -524,7 +606,7 @@ static int rpng_x_create_window()
return 3;
}
- /* to avoid testing the bitmap_order every pixel (or doubling the size of
+ /* to avoid testing the byte order every pixel (or doubling the size of
* the drawing routine with a giant if-test), we arbitrarily set the byte
* order to MSBFirst and let Xlib worry about inverting things on little-
* endian machines (like Linux/x86, old VAXen, etc.)--this is not the most
@@ -541,20 +623,24 @@ static int rpng_x_create_window()
-static int rpng_x_display_image()
+static int rpng_x_display_image(void)
{
uch *src;
char *dest;
uch r, g, b, a;
- int ximage_rowbytes = ximage->bytes_per_line;
ulg i, row, lastrow = 0;
ulg pixel;
+ int ximage_rowbytes = ximage->bytes_per_line;
+/* int bpp = ximage->bits_per_pixel; */
Trace((stderr, "beginning display loop (image_channels == %d)\n",
image_channels))
- Trace((stderr, "(width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
+ Trace((stderr, " (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
image_width, image_rowbytes, ximage_rowbytes))
+ Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel))
+ Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst?
+ "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
if (depth == 24 || depth == 32) {
ulg red, green, blue;
@@ -567,14 +653,27 @@ static int rpng_x_display_image()
red = *src++;
green = *src++;
blue = *src++;
- pixel = (red << RPixelShift) |
- (green << GPixelShift) |
- (blue << BPixelShift);
+#ifdef NO_24BIT_MASKS
+ pixel = (red << RShift) |
+ (green << GShift) |
+ (blue << BShift);
/* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = ((uch *)&pixel)[3];
- *dest++ = ((uch *)&pixel)[2];
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ /* GRR BUG: this assumes bpp == 32, but may be 24: */
+ *dest++ = (char)((pixel >> 24) & 0xff);
+ *dest++ = (char)((pixel >> 16) & 0xff);
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
+#else
+ red = (RShift < 0)? red << (-RShift) : red >> RShift;
+ green = (GShift < 0)? green << (-GShift) : green >> GShift;
+ blue = (BShift < 0)? blue << (-BShift) : blue >> BShift;
+ pixel = (red & RMask) | (green & GMask) | (blue & BMask);
+ /* recall that we set ximage->byte_order = MSBFirst above */
+ *dest++ = (char)((pixel >> 24) & 0xff);
+ *dest++ = (char)((pixel >> 16) & 0xff);
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
+#endif
}
} else /* if (image_channels == 4) */ {
for (i = image_width; i > 0; --i) {
@@ -598,20 +697,20 @@ static int rpng_x_display_image()
alpha_composite(green, g, a, bg_green);
alpha_composite(blue, b, a, bg_blue);
}
- pixel = (red << RPixelShift) |
- (green << GPixelShift) |
- (blue << BPixelShift);
+ pixel = (red << RShift) |
+ (green << GShift) |
+ (blue << BShift);
/* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = ((uch *)&pixel)[3];
- *dest++ = ((uch *)&pixel)[2];
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ *dest++ = (char)((pixel >> 24) & 0xff);
+ *dest++ = (char)((pixel >> 16) & 0xff);
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
}
/* display after every 16 lines */
if (((row+1) & 0xf) == 0) {
- XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
- image_width, 16);
+ XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
+ (int)lastrow, image_width, 16);
XFlush(display);
lastrow = row + 1;
}
@@ -631,12 +730,12 @@ static int rpng_x_display_image()
++src;
blue = ((ush)(*src) << 8);
++src;
- pixel = ((red >> RPixelShift) & RedMask) |
- ((green >> GPixelShift) & GreenMask) |
- ((blue >> BPixelShift) & BlueMask);
+ pixel = ((red >> RShift) & RMask) |
+ ((green >> GShift) & GMask) |
+ ((blue >> BShift) & BMask);
/* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
} else /* if (image_channels == 4) */ {
for (i = image_width; i > 0; --i) {
@@ -663,18 +762,18 @@ static int rpng_x_display_image()
green = ((ush)g << 8);
blue = ((ush)b << 8);
}
- pixel = ((red >> RPixelShift) & RedMask) |
- ((green >> GPixelShift) & GreenMask) |
- ((blue >> BPixelShift) & BlueMask);
+ pixel = ((red >> RShift) & RMask) |
+ ((green >> GShift) & GMask) |
+ ((blue >> BShift) & BMask);
/* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
}
/* display after every 16 lines */
if (((row+1) & 0xf) == 0) {
- XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
- image_width, 16);
+ XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
+ (int)lastrow, image_width, 16);
XFlush(display);
lastrow = row + 1;
}
@@ -688,8 +787,8 @@ static int rpng_x_display_image()
Trace((stderr, "calling final XPutImage()\n"))
if (lastrow < image_height) {
- XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
- image_width, image_height-lastrow);
+ XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
+ (int)lastrow, image_width, image_height-lastrow);
XFlush(display);
}
@@ -699,7 +798,7 @@ static int rpng_x_display_image()
-static void rpng_x_cleanup()
+static void rpng_x_cleanup(void)
{
if (image_data) {
free(image_data);
@@ -722,6 +821,9 @@ static void rpng_x_cleanup()
if (have_colormap)
XFreeColormap(display, colormap);
+
+ if (have_nondefault_visual)
+ XFree(visual_list);
}
diff --git a/contrib/gregbook/rpng2-win.c b/contrib/gregbook/rpng2-win.c
index 66e682eef..9bc66c739 100644
--- a/contrib/gregbook/rpng2-win.c
+++ b/contrib/gregbook/rpng2-win.c
@@ -22,10 +22,13 @@
Changelog:
- 1.01: initial public release
- 1.02: fixed cut-and-paste error in usage screen (oops...)
+ - 1.03: modified to allow abbreviated options
+ - 1.04: removed bogus extra argument from usage fprintf() [Glenn R-P?];
+ fixed command-line parsing bug
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -52,14 +55,14 @@
#define PROGNAME "rpng2-win"
#define LONGNAME "Progressive PNG Viewer for Windows"
-#define VERSION "1.02 of 22 September 1999"
+#define VERSION "1.04 of 19 March 2000"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
+#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
#include <time.h>
-#include <math.h> /* only for PvdM background code */
+#include <math.h> /* only for PvdM background code */
#include <windows.h>
/* all for PvdM background code: */
@@ -80,9 +83,9 @@
#define rgb2_max bg_bsat
#define rgb2_min bg_brot
-/* #define DEBUG */ /* this enables the Trace() macros */
+/* #define DEBUG */ /* this enables the Trace() macros */
-#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
+#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
/* could just include png.h, but this macro is the only thing we need
@@ -90,18 +93,18 @@
* only happen with alpha (which could easily be avoided with
* "ush acopy = (alpha);") */
-#define alpha_composite(composite, fg, alpha, bg) { \
- ush temp = ((ush)(fg)*(ush)(alpha) + \
- (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
- (composite) = (uch)((temp + (temp >> 8)) >> 8); \
+#define alpha_composite(composite, fg, alpha, bg) { \
+ ush temp = ((ush)(fg)*(ush)(alpha) + \
+ (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
+ (composite) = (uch)((temp + (temp >> 8)) >> 8); \
}
-#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
- * block size corresponds roughly to a download
- * speed 10% faster than theoretical 33.6K maximum
- * (assuming 8 data bits, 1 stop bit and no other
- * overhead) */
+#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
+ * block size corresponds roughly to a download
+ * speed 10% faster than theoretical 33.6K maximum
+ * (assuming 8 data bits, 1 stop bit and no other
+ * overhead) */
/* local prototypes */
static void rpng2_win_init(void);
@@ -116,7 +119,7 @@ LRESULT CALLBACK rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM);
static char titlebar[1024], *window_name = titlebar;
static char *progname = PROGNAME;
static char *appname = LONGNAME;
-static char *icon_name = PROGNAME; /* GRR: not (yet) used */
+static char *icon_name = PROGNAME; /* GRR: not (yet) used */
static char *filename;
static FILE *infile;
@@ -125,7 +128,7 @@ static mainprog_info rpng2_info;
static uch inbuf[INBUFSIZE];
static int incount;
-static int pat = 6; /* must be less than num_bgpat */
+static int pat = 6; /* must be less than num_bgpat */
static int bg_image = 0;
static int bgscale = 16;
static ulg bg_rowbytes;
@@ -134,22 +137,22 @@ static uch *bg_data;
static struct rgb_color {
uch r, g, b;
} rgb[] = {
- { 0, 0, 0}, /* 0: black */
- {255, 255, 255}, /* 1: white */
- {173, 132, 57}, /* 2: tan */
- { 64, 132, 0}, /* 3: medium green */
- {189, 117, 1}, /* 4: gold */
- {253, 249, 1}, /* 5: yellow */
- { 0, 0, 255}, /* 6: blue */
- { 0, 0, 120}, /* 7: medium blue */
- {255, 0, 255}, /* 8: magenta */
- { 64, 0, 64}, /* 9: dark magenta */
- {255, 0, 0}, /* 10: red */
- { 64, 0, 0}, /* 11: dark red */
- {255, 127, 0}, /* 12: orange */
- {192, 96, 0}, /* 13: darker orange */
- { 24, 60, 0}, /* 14: dark green-yellow */
- { 85, 125, 200} /* 15: ice blue */
+ { 0, 0, 0}, /* 0: black */
+ {255, 255, 255}, /* 1: white */
+ {173, 132, 57}, /* 2: tan */
+ { 64, 132, 0}, /* 3: medium green */
+ {189, 117, 1}, /* 4: gold */
+ {253, 249, 1}, /* 5: yellow */
+ { 0, 0, 255}, /* 6: blue */
+ { 0, 0, 120}, /* 7: medium blue */
+ {255, 0, 255}, /* 8: magenta */
+ { 64, 0, 64}, /* 9: dark magenta */
+ {255, 0, 0}, /* 10: red */
+ { 64, 0, 0}, /* 11: dark red */
+ {255, 127, 0}, /* 12: orange */
+ {192, 96, 0}, /* 13: darker orange */
+ { 24, 60, 0}, /* 14: dark green-yellow */
+ { 85, 125, 200} /* 15: ice blue */
};
/* not used for now, but should be for error-checking:
static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
@@ -174,25 +177,25 @@ static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
*/
static struct background_pattern {
ush type;
- int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */
- int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/
+ int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */
+ int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/
} bg[] = {
- {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */
- {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */
- {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */
- {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */
- {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */
- {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */
- {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */
- {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */
- {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */
- {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */
- {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */
- {1, 3,0, 0,0}, /* diamonds: medium green vs. black */
- {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */
- {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */
- {2, 16, 256, 100, 250}, /* radial: very tight spiral */
- {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */
+ {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */
+ {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */
+ {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */
+ {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */
+ {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */
+ {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */
+ {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */
+ {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */
+ {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */
+ {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */
+ {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */
+ {1, 3,0, 0,0}, /* diamonds: medium green vs. black */
+ {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */
+ {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */
+ {2, 16, 256, 100, 250}, /* radial: very tight spiral */
+ {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */
};
static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
@@ -212,16 +215,17 @@ static int global_showmode;
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
{
- char *args[1024]; /* arbitrary limit, but should suffice */
- char *p, *q, *bgstr = NULL, **argv = args;
+ char *args[1024]; /* arbitrary limit, but should suffice */
+ char **argv = args;
+ char *p, *q, *bgstr = NULL;
int argc = 0;
int rc, alen, flen;
int error = 0;
int timing = FALSE;
int have_bg = FALSE;
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
+ double LUT_exponent; /* just the lookup table */
+ double CRT_exponent = 2.2; /* just the monitor */
+ double default_display_exponent; /* whole display system */
MSG msg;
@@ -316,33 +320,39 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
/* Now parse the command line for options and the PNG filename. */
while (*++argv && !error) {
- if (!strcmp(*argv, "-gamma")) {
+ if (!strncmp(*argv, "-gamma", 2)) {
if (!*++argv)
++error;
- rpng2_info.display_exponent = atof(*argv);
- if (rpng2_info.display_exponent <= 0.0)
- ++error;
- } else if (!strcmp(*argv, "-bgcolor")) {
+ else {
+ rpng2_info.display_exponent = atof(*argv);
+ if (rpng2_info.display_exponent <= 0.0)
+ ++error;
+ }
+ } else if (!strncmp(*argv, "-bgcolor", 4)) {
if (!*++argv)
++error;
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
else {
- have_bg = TRUE;
- bg_image = FALSE;
+ bgstr = *argv;
+ if (strlen(bgstr) != 7 || bgstr[0] != '#')
+ ++error;
+ else {
+ have_bg = TRUE;
+ bg_image = FALSE;
+ }
}
- } else if (!strcmp(*argv, "-bgpat")) {
+ } else if (!strncmp(*argv, "-bgpat", 4)) {
if (!*++argv)
++error;
- pat = atoi(*argv) - 1;
- if (pat < 0 || pat >= num_bgpat)
- ++error;
else {
- bg_image = TRUE;
- have_bg = FALSE;
+ pat = atoi(*argv) - 1;
+ if (pat < 0 || pat >= num_bgpat)
+ ++error;
+ else {
+ bg_image = TRUE;
+ have_bg = FALSE;
+ }
}
- } else if (!strcmp(*argv, "-timing")) {
+ } else if (!strncmp(*argv, "-timing", 2)) {
timing = TRUE;
} else {
if (**argv != '-') {
@@ -387,6 +397,9 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
fclose(infile);
}
+
+ /* usage screen */
+
if (error) {
fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
readpng2_version_info();
@@ -398,14 +411,14 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
"\t\t to the product of the lookup-table exponent (varies)\n"
"\t\t and the CRT exponent (usually 2.2); must be positive\n"
" bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7f00'' for orange: same as HTML colors);\n"
+ "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
"\t\t used with transparent images; overrides -bgpat\n"
" pat \tdesired background pattern number (1-%d); used with\n"
"\t\t transparent images; overrides -bgcolor\n"
" -timing\tenables delay for every block read, to simulate modem\n"
"\t\t download of image (~36 Kbps)\n"
"\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
- "\n", PROGNAME, " ", default_display_exponent, num_bgpat);
+ "\n", PROGNAME, default_display_exponent, num_bgpat);
exit(1);
}
@@ -560,7 +573,7 @@ static int rpng2_win_create_window()
if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
wimage_rowbytes*rpng2_info.height)))
{
- return 4; /* fail */
+ return 4; /* fail */
}
/*---------------------------------------------------------------------------
@@ -655,7 +668,7 @@ static int rpng2_win_create_window()
TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len);
ReleaseDC(global_hwnd, hdc);
- rpng2_win_load_bg_image(); /* resets bg_image if fails */
+ rpng2_win_load_bg_image(); /* resets bg_image if fails */
}
if (!bg_image) {
@@ -753,7 +766,7 @@ static int rpng2_win_load_bg_image()
even_odd = even_odd_vert ^ even_odd_horiz;
invert_column =
(even_odd_horiz && (bg[pat].type & 0x10));
- if (even_odd == 0) { /* gradient #1 */
+ if (even_odd == 0) { /* gradient #1 */
if (invert_column) {
*dest++ = r1_inv;
*dest++ = g1_inv;
@@ -763,16 +776,16 @@ static int rpng2_win_load_bg_image()
*dest++ = g1;
*dest++ = b1;
}
- } else { /* gradient #2 */
+ } else { /* gradient #2 */
if ((invert_column && invert_gradient2) ||
(!invert_column && !invert_gradient2))
{
- *dest++ = r2; /* not inverted or */
- *dest++ = g2; /* doubly inverted */
+ *dest++ = r2; /* not inverted or */
+ *dest++ = g2; /* doubly inverted */
*dest++ = b2;
} else {
*dest++ = r2_inv;
- *dest++ = g2_inv; /* singly inverted */
+ *dest++ = g2_inv; /* singly inverted */
*dest++ = b2_inv;
}
}
@@ -908,7 +921,7 @@ static int rpng2_win_load_bg_image()
g1 = *src++;
b1 = *src++;
*dest++ = b1;
- *dest++ = g1; /* note reverse order */
+ *dest++ = g1; /* note reverse order */
*dest++ = r1;
}
}
@@ -962,7 +975,7 @@ static void rpng2_win_display_row(ulg row)
g = *src++;
b = *src++;
*dest++ = b;
- *dest++ = g; /* note reverse order */
+ *dest++ = g; /* note reverse order */
*dest++ = r;
}
} else /* if (rpng2_info.channels == 4) */ {
@@ -1028,7 +1041,9 @@ static void rpng2_win_finish_display()
* that the image is done */
rpng2_info.done = TRUE;
- printf("Done. Press Q, Esc or mouse button 1 to quit.\n");
+ printf(
+ "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+ fflush(stdout);
}
@@ -1084,15 +1099,15 @@ LRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
/* wait for the user to tell us when to quit */
case WM_CHAR:
- switch (wP) { /* only need one, so ignore repeat count */
+ switch (wP) { /* only need one, so ignore repeat count */
case 'q':
case 'Q':
- case 0x1B: /* Esc key */
+ case 0x1B: /* Esc key */
PostQuitMessage(0);
}
return 0;
- case WM_LBUTTONDOWN: /* another way of quitting */
+ case WM_LBUTTONDOWN: /* another way of quitting */
case WM_DESTROY:
PostQuitMessage(0);
return 0;
diff --git a/contrib/gregbook/rpng2-x.c b/contrib/gregbook/rpng2-x.c
index 8e536e7bb..47ab5b9cb 100644
--- a/contrib/gregbook/rpng2-x.c
+++ b/contrib/gregbook/rpng2-x.c
@@ -6,9 +6,11 @@
a web browser (though the front end is only set up to read from files).
It supports gamma correction, user-specified background colors, and user-
specified background patterns (for transparent images). This version is
- for the X Window System (tested under Unix, but may work under VMS or OS/2
- with a little tweaking). Thanks to Adam Costello and Pieter S. van der
- Meulen for the "diamond" and "radial waves" patterns, respectively.
+ for the X Window System (tested by the author under Unix and by Martin
+ Zinser under OpenVMS; may work under OS/2 with a little tweaking).
+
+ Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond"
+ and "radial waves" patterns, respectively.
to do:
- 8-bit support
@@ -17,7 +19,16 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Changelog:
+ - 1.01: initial public release
+ - 1.02: modified to allow abbreviated options; fixed char/uchar mismatch
+ - 1.10: added support for non-default visuals; fixed X pixel-conversion
+ - 1.11: added -usleep option for demos; fixed command-line parsing bug
+ - 1.12: added -pause option for demos and testing
+
+ ---------------------------------------------------------------------------
+
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -44,21 +55,21 @@
#define PROGNAME "rpng2-x"
#define LONGNAME "Progressive PNG Viewer for X"
-#define VERSION "1.01 of 31 March 1999"
+#define VERSION "1.12 of 19 March 2000"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
+#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
#include <time.h>
-#include <math.h> /* only for PvdM background code */
+#include <math.h> /* only for PvdM background code */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
-#include <X11/keysym.h> /* defines XK_* macros */
+#include <X11/keysym.h> /* defines XK_* macros */
#ifdef VMS
-#include <unistd.h>
+# include <unistd.h>
#endif
/* all for PvdM background code: */
@@ -79,9 +90,9 @@
#define rgb2_max bg_bsat
#define rgb2_min bg_brot
-/* #define DEBUG */ /* this enables the Trace() macros */
+/* #define DEBUG */ /* this enables the Trace() macros */
-#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
+#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
/* could just include png.h, but this macro is the only thing we need
@@ -89,18 +100,18 @@
* only happen with alpha (which could easily be avoided with
* "ush acopy = (alpha);") */
-#define alpha_composite(composite, fg, alpha, bg) { \
- ush temp = ((ush)(fg)*(ush)(alpha) + \
- (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
- (composite) = (uch)((temp + (temp >> 8)) >> 8); \
+#define alpha_composite(composite, fg, alpha, bg) { \
+ ush temp = ((ush)(fg)*(ush)(alpha) + \
+ (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
+ (composite) = (uch)((temp + (temp >> 8)) >> 8); \
}
-#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
- * block size corresponds roughly to a download
- * speed 10% faster than theoretical 33.6K maximum
- * (assuming 8 data bits, 1 stop bit and no other
- * overhead) */
+#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
+ * block size corresponds roughly to a download
+ * speed 10% faster than theoretical 33.6K maximum
+ * (assuming 8 data bits, 1 stop bit and no other
+ * overhead) */
/* local prototypes */
static void rpng2_x_init(void);
@@ -123,12 +134,16 @@ static mainprog_info rpng2_info;
static uch inbuf[INBUFSIZE];
static int incount;
-static int pat = 6; /* must be less than num_bgpat */
+static int pat = 6; /* must be less than num_bgpat */
static int bg_image = 0;
static int bgscale = 16;
static ulg bg_rowbytes;
static uch *bg_data;
+int pause_after_pass = FALSE;
+int demo_timing = FALSE;
+ulg usleep_duration = 0L;
+
static struct rgb_color {
uch r, g, b;
} rgb[] = {
@@ -201,12 +216,14 @@ static XImage *ximage;
static Display *display;
static int depth;
static Visual *visual;
-static int RPixelShift, GPixelShift, BPixelShift;
-static ulg RedMask, GreenMask, BlueMask;
+static XVisualInfo *visual_list;
+static int RShift, GShift, BShift;
+static ulg RMask, GMask, BMask;
static Window window;
static GC gc;
static Colormap colormap;
+static int have_nondefault_visual = FALSE;
static int have_colormap = FALSE;
static int have_window = FALSE;
@@ -294,37 +311,53 @@ int main(int argc, char **argv)
/* Now parse the command line for options and the PNG filename. */
while (*++argv && !error) {
- if (!strcmp(*argv, "-display")) {
+ if (!strncmp(*argv, "-display", 2)) {
if (!*++argv)
++error;
- displayname = *argv;
- } else if (!strcmp(*argv, "-gamma")) {
+ else
+ displayname = *argv;
+ } else if (!strncmp(*argv, "-gamma", 2)) {
if (!*++argv)
++error;
- rpng2_info.display_exponent = atof(*argv);
- if (rpng2_info.display_exponent <= 0.0)
- ++error;
- } else if (!strcmp(*argv, "-bgcolor")) {
+ else {
+ rpng2_info.display_exponent = atof(*argv);
+ if (rpng2_info.display_exponent <= 0.0)
+ ++error;
+ }
+ } else if (!strncmp(*argv, "-bgcolor", 4)) {
if (!*++argv)
++error;
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
else {
- have_bg = TRUE;
- bg_image = FALSE;
+ bgstr = *argv;
+ if (strlen(bgstr) != 7 || bgstr[0] != '#')
+ ++error;
+ else {
+ have_bg = TRUE;
+ bg_image = FALSE;
+ }
}
- } else if (!strcmp(*argv, "-bgpat")) {
+ } else if (!strncmp(*argv, "-bgpat", 4)) {
if (!*++argv)
++error;
- pat = atoi(*argv) - 1;
- if (pat < 0 || pat >= num_bgpat)
+ else {
+ pat = atoi(*argv) - 1;
+ if (pat < 0 || pat >= num_bgpat)
+ ++error;
+ else {
+ bg_image = TRUE;
+ have_bg = FALSE;
+ }
+ }
+ } else if (!strncmp(*argv, "-usleep", 2)) {
+ if (!*++argv)
++error;
else {
- bg_image = TRUE;
- have_bg = FALSE;
+ usleep_duration = (ulg)atol(*argv);
+ demo_timing = TRUE;
}
- } else if (!strcmp(*argv, "-timing")) {
+ } else if (!strncmp(*argv, "-pause", 2)) {
+ pause_after_pass = TRUE;
+ } else if (!strncmp(*argv, "-timing", 2)) {
timing = TRUE;
} else {
if (**argv != '-') {
@@ -377,25 +410,32 @@ int main(int argc, char **argv)
fclose(infile);
}
+
+ /* usage screen */
+
if (error) {
fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
readpng2_version_info();
fprintf(stderr, "\n"
"Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
- " %*s [-timing] file.png\n\n"
+ " %*s [-usleep dur | -timing] [-pause] file.png\n\n"
" xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
" exp \ttransfer-function exponent (``gamma'') of the display\n"
"\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
"\t\t to the product of the lookup-table exponent (varies)\n"
"\t\t and the CRT exponent (usually 2.2); must be positive\n"
" bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7f00'' for orange: same as HTML colors);\n"
+ "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
"\t\t used with transparent images; overrides -bgpat\n"
" pat \tdesired background pattern number (1-%d); used with\n"
"\t\t transparent images; overrides -bgcolor\n"
+ " dur \tduration in microseconds to wait after displaying each\n"
+ "\t\t row (for demo purposes)\n"
" -timing\tenables delay for every block read, to simulate modem\n"
"\t\t download of image (~36 Kbps)\n"
- "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
+ " -pause\tpauses after displaying each pass until key pressed\n"
+ "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
+ "is displayed) to quit.\n"
"\n", PROGNAME, strlen(PROGNAME), " ", default_display_exponent,
num_bgpat);
exit(1);
@@ -489,7 +529,7 @@ int main(int argc, char **argv)
* in turn is called by libpng after all of the pre-IDAT chunks have been
* read and processed--i.e., we now have enough info to finish initializing */
-static void rpng2_x_init()
+static void rpng2_x_init(void)
{
ulg i;
ulg rowbytes = rpng2_info.rowbytes;
@@ -531,12 +571,14 @@ static void rpng2_x_init()
-static int rpng2_x_create_window()
+static int rpng2_x_create_window(void)
{
ulg bg_red = rpng2_info.bg_red;
ulg bg_green = rpng2_info.bg_green;
ulg bg_blue = rpng2_info.bg_blue;
ulg bg_pixel = 0L;
+ ulg attrmask;
+ int need_colormap = FALSE;
int screen, pad;
uch *xdata;
Window root;
@@ -556,39 +598,70 @@ static int rpng2_x_create_window()
depth = DisplayPlanes(display, screen);
root = RootWindow(display, screen);
-/* GRR: add 8-bit support */
- if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {
- fprintf(stderr,
- "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n",
- depth);
- return 2;
- }
+#ifdef DEBUG
+ XSynchronize(display, True);
+#endif
- XMatchVisualInfo(display, screen, depth,
- (depth == 8)? PseudoColor : TrueColor, &visual_info);
- visual = visual_info.visual;
+ if (depth != 16 && depth != 24 && depth != 32) {
+ int visuals_matched = 0;
+
+ Trace((stderr, "default depth is %d: checking other visuals\n",
+ depth))
+
+ /* 24-bit first */
+ visual_info.screen = screen;
+ visual_info.depth = 24;
+ visual_list = XGetVisualInfo(display,
+ VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
+ if (visuals_matched == 0) {
+/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
+ fprintf(stderr, "default screen depth %d not supported, and no"
+ " 24-bit visuals found\n", depth);
+ return 2;
+ }
+ Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
+ visuals_matched))
+ visual = visual_list[0].visual;
+ depth = visual_list[0].depth;
+/*
+ colormap_size = visual_list[0].colormap_size;
+ visual_class = visual->class;
+ visualID = XVisualIDFromVisual(visual);
+ */
+ have_nondefault_visual = TRUE;
+ need_colormap = TRUE;
+ } else {
+ XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
+ visual = visual_info.visual;
+ }
- RedMask = visual->red_mask;
- GreenMask = visual->green_mask;
- BlueMask = visual->blue_mask;
+ RMask = visual->red_mask;
+ GMask = visual->green_mask;
+ BMask = visual->blue_mask;
/* GRR: add/check 8-bit support */
- if (depth == 8) {
+ if (depth == 8 || need_colormap) {
colormap = XCreateColormap(display, root, visual, AllocNone);
if (!colormap) {
fprintf(stderr, "XCreateColormap() failed\n");
return 2;
}
have_colormap = TRUE;
- bg_image = FALSE; /* gradient just wastes palette entries */
- } else if (depth == 16) {
- RPixelShift = 15 - rpng2_x_msb(RedMask); /* these are right-shifts */
- GPixelShift = 15 - rpng2_x_msb(GreenMask);
- BPixelShift = 15 - rpng2_x_msb(BlueMask);
- } else /* if (depth > 16) */ {
- RPixelShift = rpng2_x_msb(RedMask) - 7; /* these are left-shifts */
- GPixelShift = rpng2_x_msb(GreenMask) - 7;
- BPixelShift = rpng2_x_msb(BlueMask) - 7;
+ if (depth == 8)
+ bg_image = FALSE; /* gradient just wastes palette entries */
+ }
+ if (depth == 15 || depth == 16) {
+ RShift = 15 - rpng2_x_msb(RMask); /* these are right-shifts */
+ GShift = 15 - rpng2_x_msb(GMask);
+ BShift = 15 - rpng2_x_msb(BMask);
+ } else if (depth > 16) {
+ RShift = rpng2_x_msb(RMask) - 7; /* these are left-shifts */
+ GShift = rpng2_x_msb(GMask) - 7;
+ BShift = rpng2_x_msb(BMask) - 7;
+ }
+ if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
+ fprintf(stderr, "rpng2 internal logic error: negative X shift(s)!\n");
+ return 2;
}
/*---------------------------------------------------------------------------
@@ -597,10 +670,16 @@ static int rpng2_x_create_window()
attr.backing_store = Always;
attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
+ attrmask = CWBackingStore | CWEventMask;
+ if (have_nondefault_visual) {
+ attr.colormap = colormap;
+ attr.background_pixel = 0;
+ attr.border_pixel = 1;
+ attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
+ }
window = XCreateWindow(display, root, 0, 0, rpng2_info.width,
- rpng2_info.height, 0, depth, InputOutput, visual,
- CWBackingStore | CWEventMask, &attr);
+ rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr);
if (window == None) {
fprintf(stderr, "XCreateWindow() failed\n");
@@ -621,8 +700,9 @@ static int rpng2_x_create_window()
if ((size_hints = XAllocSizeHints()) != NULL) {
/* window will not be resizable */
size_hints->flags = PMinSize | PMaxSize;
- size_hints->min_width = size_hints->max_width = rpng2_info.width;
- size_hints->min_height = size_hints->max_height = rpng2_info.height;
+ size_hints->min_width = size_hints->max_width = (int)rpng2_info.width;
+ size_hints->min_height = size_hints->max_height =
+ (int)rpng2_info.height;
}
if ((wm_hints = XAllocWMHints()) != NULL) {
@@ -668,7 +748,7 @@ static int rpng2_x_create_window()
return 3;
}
- /* to avoid testing the bitmap order every pixel (or doubling the size of
+ /* to avoid testing the byte order every pixel (or doubling the size of
* the drawing routine with a giant if-test), we arbitrarily set the byte
* order to MSBFirst and let Xlib worry about inverting things on little-
* endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the
@@ -684,17 +764,17 @@ static int rpng2_x_create_window()
---------------------------------------------------------------------------*/
if (bg_image)
- rpng2_x_load_bg_image(); /* resets bg_image if fails */
+ rpng2_x_load_bg_image(); /* resets bg_image if fails */
if (!bg_image) {
if (depth == 24 || depth == 32) {
- bg_pixel = (bg_red << RPixelShift) |
- (bg_green << GPixelShift) |
- (bg_blue << BPixelShift);
+ bg_pixel = (bg_red << RShift) |
+ (bg_green << GShift) |
+ (bg_blue << BShift);
} else if (depth == 16) {
- bg_pixel = (((bg_red << 8) >> RPixelShift) & RedMask) |
- (((bg_green << 8) >> GPixelShift) & GreenMask) |
- (((bg_blue << 8) >> BPixelShift) & BlueMask);
+ bg_pixel = (((bg_red << 8) >> RShift) & RMask) |
+ (((bg_green << 8) >> GShift) & GMask) |
+ (((bg_blue << 8) >> BShift) & BMask);
} else /* depth == 8 */ {
/* GRR: add 8-bit support */
@@ -723,7 +803,7 @@ static int rpng2_x_create_window()
-static int rpng2_x_load_bg_image()
+static int rpng2_x_load_bg_image(void)
{
uch *src;
char *dest;
@@ -772,8 +852,8 @@ static int rpng2_x_load_bg_image()
int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
for (row = 0; row < rpng2_info.height; ++row) {
- yidx = row % bgscale;
- even_odd_vert = (row / bgscale) & 1;
+ yidx = (int)(row % bgscale);
+ even_odd_vert = (int)((row / bgscale) & 1);
r1 = r1_min + (r1_diff * yidx) / yidx_max;
g1 = g1_min + (g1_diff * yidx) / yidx_max;
@@ -789,13 +869,13 @@ static int rpng2_x_load_bg_image()
g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
- dest = (char *)(bg_data + row*bg_rowbytes);
+ dest = (char *)bg_data + row*bg_rowbytes;
for (i = 0; i < rpng2_info.width; ++i) {
- even_odd_horiz = (i / bgscale) & 1;
+ even_odd_horiz = (int)((i / bgscale) & 1);
even_odd = even_odd_vert ^ even_odd_horiz;
invert_column =
(even_odd_horiz && (bg[pat].type & 0x10));
- if (even_odd == 0) { /* gradient #1 */
+ if (even_odd == 0) { /* gradient #1 */
if (invert_column) {
*dest++ = r1_inv;
*dest++ = g1_inv;
@@ -805,16 +885,16 @@ static int rpng2_x_load_bg_image()
*dest++ = g1;
*dest++ = b1;
}
- } else { /* gradient #2 */
+ } else { /* gradient #2 */
if ((invert_column && invert_gradient2) ||
(!invert_column && !invert_gradient2))
{
- *dest++ = r2; /* not inverted or */
- *dest++ = g2; /* doubly inverted */
+ *dest++ = r2; /* not inverted or */
+ *dest++ = g2; /* doubly inverted */
*dest++ = b2;
} else {
*dest++ = r2_inv;
- *dest++ = g2_inv; /* singly inverted */
+ *dest++ = g2_inv; /* singly inverted */
*dest++ = b2_inv;
}
}
@@ -839,12 +919,12 @@ static int rpng2_x_load_bg_image()
b2 = rgb[bg[pat].rgb2_max].b;
for (row = 0; row < rpng2_info.height; ++row) {
- yidx = row % bgscale;
+ yidx = (int)(row % bgscale);
if (yidx > hmax)
yidx = bgscale-1 - yidx;
- dest = (char *)(bg_data + row*bg_rowbytes);
+ dest = (char *)bg_data + row*bg_rowbytes;
for (i = 0; i < rpng2_info.width; ++i) {
- xidx = i % bgscale;
+ xidx = (int)(i % bgscale);
if (xidx > hmax)
xidx = bgscale-1 - xidx;
k = xidx + yidx;
@@ -871,8 +951,8 @@ static int rpng2_x_load_bg_image()
PROGNAME);
fflush(stderr);
- hh = rpng2_info.height / 2;
- hw = rpng2_info.width / 2;
+ hh = (int)(rpng2_info.height / 2);
+ hw = (int)(rpng2_info.width / 2);
/* variables for radial waves:
* aoffset: number of degrees to rotate hue [CURRENTLY NOT USED]
@@ -891,10 +971,10 @@ static int rpng2_x_load_bg_image()
maxDist = (double)((hw*hw) + (hh*hh));
for (row = 0; row < rpng2_info.height; ++row) {
- y = row - hh;
- dest = (char *)(bg_data + row*bg_rowbytes);
+ y = (int)(row - hh);
+ dest = (char *)bg_data + row*bg_rowbytes;
for (i = 0; i < rpng2_info.width; ++i) {
- x = i - hw;
+ x = (int)(i - hw);
angle = (x == 0)? PI_2 : atan((double)y / (double)x);
gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
gray = MIN(1.0, gray);
@@ -951,14 +1031,15 @@ static int rpng2_x_load_bg_image()
red = *src++;
green = *src++;
blue = *src++;
- pixel = (red << RPixelShift) |
- (green << GPixelShift) |
- (blue << BPixelShift);
+ pixel = (red << RShift) |
+ (green << GShift) |
+ (blue << BShift);
/* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = ((uch *)&pixel)[3];
- *dest++ = ((uch *)&pixel)[2];
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ /* GRR BUG: this assumes bpp == 32, but may be 24: */
+ *dest++ = (char)((pixel >> 24) & 0xff);
+ *dest++ = (char)((pixel >> 16) & 0xff);
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
}
@@ -969,18 +1050,15 @@ static int rpng2_x_load_bg_image()
src = bg_data + row*bg_rowbytes;
dest = ximage->data + row*ximage_rowbytes;
for (i = rpng2_info.width; i > 0; --i) {
- red = ((ush)(*src) << 8);
- ++src;
- green = ((ush)(*src) << 8);
- ++src;
- blue = ((ush)(*src) << 8);
- ++src;
- pixel = ((red >> RPixelShift) & RedMask) |
- ((green >> GPixelShift) & GreenMask) |
- ((blue >> BPixelShift) & BlueMask);
+ red = ((ush)(*src) << 8); ++src;
+ green = ((ush)(*src) << 8); ++src;
+ blue = ((ush)(*src) << 8); ++src;
+ pixel = ((red >> RShift) & RMask) |
+ ((green >> GShift) & GMask) |
+ ((blue >> BShift) & BMask);
/* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
}
@@ -1011,7 +1089,7 @@ static void rpng2_x_display_row(ulg row)
uch r, g, b, a;
int ximage_rowbytes = ximage->bytes_per_line;
ulg i, pixel;
- static int rows=0;
+ static int rows=0, prevpass=(-1);
static ulg firstrow;
/*---------------------------------------------------------------------------
@@ -1022,8 +1100,28 @@ static void rpng2_x_display_row(ulg row)
Trace((stderr, "beginning rpng2_x_display_row()\n"))
+ if (rpng2_info.pass != prevpass) {
+ if (pause_after_pass && rpng2_info.pass > 0) {
+ XEvent e;
+ KeySym k;
+
+ fprintf(stderr,
+ "%s: end of pass %d of 7; click in image window to continue\n",
+ PROGNAME, prevpass + 1);
+ do
+ XNextEvent(display, &e);
+ while (!(e.type == ButtonPress && e.xbutton.button == Button1)
+ && !(e.type == KeyPress &&
+ ((k = XLookupKeysym(&e.xkey, 0)) == XK_q
+ || k == XK_Escape) )) ;
+ }
+ fprintf(stderr, "%s: pass %d of 7\r", PROGNAME, rpng2_info.pass + 1);
+ fflush(stderr);
+ prevpass = rpng2_info.pass;
+ }
+
if (rows == 0)
- firstrow = row; /* first row not yet displayed */
+ firstrow = row; /* first row that is not yet displayed */
++rows; /* count of rows received but not yet displayed */
@@ -1046,14 +1144,15 @@ static void rpng2_x_display_row(ulg row)
red = *src++;
green = *src++;
blue = *src++;
- pixel = (red << RPixelShift) |
- (green << GPixelShift) |
- (blue << BPixelShift);
- /* recall that we set ximage->byte_order = MSBFirst */
- *dest++ = ((uch *)&pixel)[3];
- *dest++ = ((uch *)&pixel)[2];
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ pixel = (red << RShift) |
+ (green << GShift) |
+ (blue << BShift);
+ /* recall that we set ximage->byte_order = MSBFirst above */
+ /* GRR BUG: this assumes bpp == 32, but may be 24: */
+ *dest++ = (char)((pixel >> 24) & 0xff);
+ *dest++ = (char)((pixel >> 16) & 0xff);
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
} else /* if (rpng2_info.channels == 4) */ {
for (i = rpng2_info.width; i > 0; --i) {
@@ -1082,14 +1181,15 @@ static void rpng2_x_display_row(ulg row)
alpha_composite(green, g, a, bg_green);
alpha_composite(blue, b, a, bg_blue);
}
- pixel = (red << RPixelShift) |
- (green << GPixelShift) |
- (blue << BPixelShift);
- /* recall that we set ximage->byte_order = MSBFirst */
- *dest++ = ((uch *)&pixel)[3];
- *dest++ = ((uch *)&pixel)[2];
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ pixel = (red << RShift) |
+ (green << GShift) |
+ (blue << BShift);
+ /* recall that we set ximage->byte_order = MSBFirst above */
+ /* GRR BUG: this assumes bpp == 32, but may be 24: */
+ *dest++ = (char)((pixel >> 24) & 0xff);
+ *dest++ = (char)((pixel >> 16) & 0xff);
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
}
@@ -1108,12 +1208,12 @@ static void rpng2_x_display_row(ulg row)
++src;
blue = ((ush)(*src) << 8);
++src;
- pixel = ((red >> RPixelShift) & RedMask) |
- ((green >> GPixelShift) & GreenMask) |
- ((blue >> BPixelShift) & BlueMask);
- /* recall that we set ximage->byte_order = MSBFirst */
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ pixel = ((red >> RShift) & RMask) |
+ ((green >> GShift) & GMask) |
+ ((blue >> BShift) & BMask);
+ /* recall that we set ximage->byte_order = MSBFirst above */
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
} else /* if (rpng2_info.channels == 4) */ {
for (i = rpng2_info.width; i > 0; --i) {
@@ -1145,12 +1245,12 @@ static void rpng2_x_display_row(ulg row)
green = ((ush)g << 8);
blue = ((ush)b << 8);
}
- pixel = ((red >> RPixelShift) & RedMask) |
- ((green >> GPixelShift) & GreenMask) |
- ((blue >> BPixelShift) & BlueMask);
- /* recall that we set ximage->byte_order = MSBFirst */
- *dest++ = ((uch *)&pixel)[1];
- *dest++ = ((uch *)&pixel)[0];
+ pixel = ((red >> RShift) & RMask) |
+ ((green >> GShift) & GMask) |
+ ((blue >> BShift) & BMask);
+ /* recall that we set ximage->byte_order = MSBFirst above */
+ *dest++ = (char)((pixel >> 8) & 0xff);
+ *dest++ = (char)( pixel & 0xff);
}
}
@@ -1162,13 +1262,23 @@ static void rpng2_x_display_row(ulg row)
/*---------------------------------------------------------------------------
- Display after every 16 rows or when on last row. (Region may include
- previously displayed lines due to interlacing--i.e., not contiguous.)
+ Display after every 16 rows or when on one of last two rows. (Region
+ may include previously displayed lines due to interlacing--i.e., not
+ contiguous. Also, second-to-last row is final one in interlaced images
+ with odd number of rows.) For demos, flush (and delay) after every 16th
+ row so "sparse" passes don't go twice as fast.
---------------------------------------------------------------------------*/
- if ((rows & 0xf) == 0 || row == rpng2_info.height-1) {
- XPutImage(display, window, gc, ximage, 0, firstrow, 0, firstrow,
- rpng2_info.width, row - firstrow + 1);
+ if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) {
+ XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
+ (int)firstrow, rpng2_info.width, row - firstrow + 1);
+ XFlush(display);
+ rows = 0;
+ usleep(usleep_duration);
+ } else
+ if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) {
+ XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
+ (int)firstrow, rpng2_info.width, row - firstrow + 1);
XFlush(display);
rows = 0;
}
@@ -1179,7 +1289,7 @@ static void rpng2_x_display_row(ulg row)
-static void rpng2_x_finish_display()
+static void rpng2_x_finish_display(void)
{
Trace((stderr, "beginning rpng2_x_finish_display()\n"))
@@ -1188,14 +1298,16 @@ static void rpng2_x_finish_display()
* the image is done */
rpng2_info.done = TRUE;
- printf("Done. Press Q, Esc or mouse button 1 to quit.\n");
+ printf(
+ "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+ fflush(stdout);
}
-static void rpng2_x_cleanup()
+static void rpng2_x_cleanup(void)
{
if (bg_image && bg_data) {
free(bg_data);
@@ -1228,6 +1340,9 @@ static void rpng2_x_cleanup()
if (have_colormap)
XFreeColormap(display, colormap);
+
+ if (have_nondefault_visual)
+ XFree(visual_list);
}
diff --git a/contrib/gregbook/toucan.png b/contrib/gregbook/toucan.png
new file mode 100644
index 000000000..03960d493
--- /dev/null
+++ b/contrib/gregbook/toucan.png
Binary files differ
diff --git a/contrib/gregbook/wpng.c b/contrib/gregbook/wpng.c
index 7709b33a0..d6e85148b 100644
--- a/contrib/gregbook/wpng.c
+++ b/contrib/gregbook/wpng.c
@@ -19,7 +19,15 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Changelog:
+ - 1.01: initial public release
+ - 1.02: modified to allow abbreviated options
+ - 1.03: removed extraneous character from usage screen; fixed bug in
+ command-line parsing
+
+ ---------------------------------------------------------------------------
+
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -45,7 +53,7 @@
---------------------------------------------------------------------------*/
#define PROGNAME "wpng"
-#define VERSION "1.01 of 31 March 1999"
+#define VERSION "1.03 of 19 March 2000"
#define APPNAME "Simple PGM/PPM/PAM to PNG Converter"
#if defined(__MSDOS__) || defined(__OS2__)
@@ -57,27 +65,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <setjmp.h> /* for jmpbuf declaration in writepng.h */
+#include <setjmp.h> /* for jmpbuf declaration in writepng.h */
#include <time.h>
#ifdef DOS_OS2_W32
-# include <io.h> /* for isatty(), setmode() prototypes */
-# include <fcntl.h> /* O_BINARY for fdopen() without text translation */
+# include <io.h> /* for isatty(), setmode() prototypes */
+# include <fcntl.h> /* O_BINARY for fdopen() without text translation */
# ifdef __EMX__
# ifndef getch
-# define getch() _read_kbd(0, 1, 0) /* need getche() */
+# define getch() _read_kbd(0, 1, 0) /* need getche() */
# endif
# else /* !__EMX__ */
# ifdef __GO32__
# include <pc.h>
-# define getch() getkey() /* GRR: need getche() */
+# define getch() getkey() /* GRR: need getche() */
# else
-# include <conio.h> /* for getche() console input */
+# include <conio.h> /* for getche() console input */
# endif
# endif /* ?__EMX__ */
# define FGETS(buf,len,stream) dos_kbd_gets(buf,len)
#else
-# include <unistd.h> /* for isatty() prototype */
+# include <unistd.h> /* for isatty() prototype */
# define FGETS fgets
#endif
@@ -87,7 +95,7 @@
text that includes control characters discouraged by the PNG spec; text
that includes an escape character (27) must be re-entered regardless */
-#include "writepng.h" /* typedefs, common macros, writepng prototypes */
+#include "writepng.h" /* typedefs, common macros, writepng prototypes */
@@ -112,7 +120,7 @@ int main(int argc, char **argv)
FILE *keybd;
#endif
#ifdef sgi
- FILE *tmpfile; /* or we could just use keybd, since no overlap */
+ FILE *tmpfile; /* or we could just use keybd, since no overlap */
char tmpline[80];
#endif
char *inname = NULL, outname[256];
@@ -204,36 +212,40 @@ int main(int argc, char **argv)
/* Now parse the command line for options and the PNM filename. */
while (*++argv && !error) {
- if (!strcmp(*argv, "-interlaced")) {
+ if (!strncmp(*argv, "-i", 2)) {
wpng_info.interlaced = TRUE;
- } else if (!strcmp(*argv, "-time")) {
+ } else if (!strncmp(*argv, "-time", 3)) {
wpng_info.modtime = time(NULL);
wpng_info.have_time = TRUE;
- } else if (!strcmp(*argv, "-text")) {
+ } else if (!strncmp(*argv, "-text", 3)) {
text = TRUE;
- } else if (!strcmp(*argv, "-gamma")) {
+ } else if (!strncmp(*argv, "-gamma", 2)) {
if (!*++argv)
++error;
- wpng_info.gamma = atof(*argv);
- if (wpng_info.gamma <= 0.0)
- ++error;
- else if (wpng_info.gamma > 1.01)
- fprintf(stderr, PROGNAME
- " warning: file gammas are usually less than 1.0\n");
- } else if (!strcmp(*argv, "-bgcolor")) {
+ else {
+ wpng_info.gamma = atof(*argv);
+ if (wpng_info.gamma <= 0.0)
+ ++error;
+ else if (wpng_info.gamma > 1.01)
+ fprintf(stderr, PROGNAME
+ " warning: file gammas are usually less than 1.0\n");
+ }
+ } else if (!strncmp(*argv, "-bgcolor", 4)) {
if (!*++argv)
++error;
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
else {
- unsigned r, g, b; /* this approach quiets compiler warnings */
-
- sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
- wpng_info.bg_red = (uch)r;
- wpng_info.bg_green = (uch)g;
- wpng_info.bg_blue = (uch)b;
- wpng_info.have_bg = TRUE;
+ bgstr = *argv;
+ if (strlen(bgstr) != 7 || bgstr[0] != '#')
+ ++error;
+ else {
+ unsigned r, g, b; /* this way quiets compiler warnings */
+
+ sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
+ wpng_info.bg_red = (uch)r;
+ wpng_info.bg_green = (uch)g;
+ wpng_info.bg_blue = (uch)b;
+ wpng_info.have_bg = TRUE;
+ }
}
} else {
if (**argv != '-') {
@@ -362,7 +374,7 @@ int main(int argc, char **argv)
"\t\t (where LUT = lookup-table exponent and CRT = CRT exponent;\n"
"\t\t first varies, second is usually 2.2, all are positive)\n"
" bg \tdesired background color for alpha-channel images, in\n"
- "\t\t 7-character hex RGB format (e.g., ``#ff7f00'' for orange:\n"
+ "\t\t 7-character hex RGB format (e.g., ``#ff7700'' for orange:\n"
"\t\t same as HTML colors)\n"
" -text\tprompt interactively for text info (tEXt chunks)\n"
" -time\tinclude a tIME chunk (last modification time)\n"
@@ -419,7 +431,7 @@ int main(int argc, char **argv)
wpng_info.have_text &= ~TEXT_TITLE;
valid = FALSE;
#else
- if (p[result] == 27) { /* escape character */
+ if (p[result] == 27) { /* escape character */
wpng_info.have_text &= ~TEXT_TITLE;
valid = FALSE;
}
@@ -449,7 +461,7 @@ int main(int argc, char **argv)
wpng_info.have_text &= ~TEXT_AUTHOR;
valid = FALSE;
#else
- if (p[result] == 27) { /* escape character */
+ if (p[result] == 27) { /* escape character */
wpng_info.have_text &= ~TEXT_AUTHOR;
valid = FALSE;
}
@@ -489,7 +501,7 @@ int main(int argc, char **argv)
wpng_info.have_text &= ~TEXT_DESC;
valid = FALSE;
#else
- if (p[result] == 27) { /* escape character */
+ if (p[result] == 27) { /* escape character */
wpng_info.have_text &= ~TEXT_DESC;
valid = FALSE;
}
@@ -519,7 +531,7 @@ int main(int argc, char **argv)
wpng_info.have_text &= ~TEXT_COPY;
valid = FALSE;
#else
- if (p[result] == 27) { /* escape character */
+ if (p[result] == 27) { /* escape character */
wpng_info.have_text &= ~TEXT_COPY;
valid = FALSE;
}
@@ -549,7 +561,7 @@ int main(int argc, char **argv)
wpng_info.have_text &= ~TEXT_EMAIL;
valid = FALSE;
#else
- if (p[result] == 27) { /* escape character */
+ if (p[result] == 27) { /* escape character */
wpng_info.have_text &= ~TEXT_EMAIL;
valid = FALSE;
}
@@ -579,7 +591,7 @@ int main(int argc, char **argv)
wpng_info.have_text &= ~TEXT_URL;
valid = FALSE;
#else
- if (p[result] == 27) { /* escape character */
+ if (p[result] == 27) { /* escape character */
wpng_info.have_text &= ~TEXT_URL;
valid = FALSE;
}
@@ -755,7 +767,7 @@ static int wpng_isvalid_latin1(uch *p, int len)
-static void wpng_cleanup()
+static void wpng_cleanup(void)
{
if (wpng_info.outfile) {
fclose(wpng_info.outfile);
@@ -791,11 +803,11 @@ static char *dos_kbd_gets(char *buf, int len)
buf[count++] = ch = getche();
} while (ch != '\r' && count < len-1);
- buf[count--] = '\0'; /* terminate string */
- if (buf[count] == '\r') /* Enter key makes CR, so change to newline */
+ buf[count--] = '\0'; /* terminate string */
+ if (buf[count] == '\r') /* Enter key makes CR, so change to newline */
buf[count] = '\n';
- fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */
+ fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */
fflush(stderr);
return buf;
diff --git a/contrib/gregbook/writepng.c b/contrib/gregbook/writepng.c
index b94c677f8..6802b12fb 100644
--- a/contrib/gregbook/writepng.c
+++ b/contrib/gregbook/writepng.c
@@ -4,7 +4,7 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors
@@ -30,10 +30,10 @@
---------------------------------------------------------------------------*/
-#include <stdlib.h> /* for exit() prototype */
+#include <stdlib.h> /* for exit() prototype */
-#include "png.h" /* libpng header; includes zlib.h and setjmp.h */
-#include "writepng.h" /* typedefs, common macros, public prototypes */
+#include "png.h" /* libpng header; includes zlib.h and setjmp.h */
+#include "writepng.h" /* typedefs, common macros, public prototypes */
/* local prototype */
@@ -42,7 +42,7 @@ static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
-void writepng_version_info()
+void writepng_version_info(void)
{
fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
PNG_LIBPNG_VER_STRING, png_libpng_ver);
@@ -82,7 +82,7 @@ int writepng_init(mainprog_info *mainprog_ptr)
* but compatible error handlers must either use longjmp() themselves
* (as in this program) or exit immediately, so here we go: */
- if (setjmp(png_jmp_env(mainprog_ptr))) {
+ if (setjmp(mainprog_ptr->jmpbuf)) {
png_destroy_write_struct(&png_ptr, &info_ptr);
return 2;
}
@@ -239,7 +239,7 @@ int writepng_encode_image(mainprog_info *mainprog_ptr)
/* as always, setjmp() must be called in every function that calls a
* PNG-writing libpng function */
- if (setjmp(png_jmp_env(mainprog_ptr))) {
+ if (setjmp(mainprog_ptr->jmpbuf)) {
png_destroy_write_struct(&png_ptr, &info_ptr);
mainprog_ptr->png_ptr = NULL;
mainprog_ptr->info_ptr = NULL;
@@ -277,7 +277,7 @@ int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */
/* as always, setjmp() must be called in every function that calls a
* PNG-writing libpng function */
- if (setjmp(png_jmp_env(mainprog_ptr))) {
+ if (setjmp(mainprog_ptr->jmpbuf)) {
png_destroy_write_struct(&png_ptr, &info_ptr);
mainprog_ptr->png_ptr = NULL;
mainprog_ptr->info_ptr = NULL;
@@ -307,7 +307,7 @@ int writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */
/* as always, setjmp() must be called in every function that calls a
* PNG-writing libpng function */
- if (setjmp(png_jmp_env(mainprog_ptr))) {
+ if (setjmp(mainprog_ptr->jmpbuf)) {
png_destroy_write_struct(&png_ptr, &info_ptr);
mainprog_ptr->png_ptr = NULL;
mainprog_ptr->info_ptr = NULL;
diff --git a/contrib/gregbook/writepng.h b/contrib/gregbook/writepng.h
index 123d2d662..93c3da820 100644
--- a/contrib/gregbook/writepng.h
+++ b/contrib/gregbook/writepng.h
@@ -4,7 +4,7 @@
---------------------------------------------------------------------------
- Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+ Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors