mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
Imported from libpng-1.0.6.tar
This commit is contained in:
26
contrib/gregbook/LICENSE
Normal file
26
contrib/gregbook/LICENSE
Normal file
@@ -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.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -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
|
||||
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
|
||||
|
||||
ZPATH = /usr/local
|
||||
ZINC = -I$(ZPATH)/include
|
||||
#ZLIB = -L$(ZPATH)/lib -lz
|
||||
ZLIB = $(ZPATH)/lib/libz.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
|
||||
|
||||
#XPATH = /usr/X11
|
||||
XPATH = /usr/X11R6
|
||||
XINC = -I$(XPATH)/include
|
||||
XLIB = -L$(XPATH)/lib -lX11
|
||||
#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 =
|
||||
@@ -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
|
||||
@@ -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.
|
||||
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 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.
|
||||
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:
|
||||
|
||||
License
|
||||
README this file
|
||||
README.w32 additional Windows-specific information
|
||||
LICENSE terms of distribution and reuse (BSD-like)
|
||||
|
||||
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:
|
||||
Makefile.unx Unix makefile
|
||||
Makefile.w32 Windows (MSVC) makefile
|
||||
makevms.com OpenVMS build script
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
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
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
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:
|
||||
wpng.c generic (text) front end for the converter
|
||||
writepng.c generic back end for the converter
|
||||
writepng.h header file for the converter
|
||||
|
||||
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:
|
||||
toucan.png transparent PNG for testing (by Stefan Schneider)
|
||||
|
||||
This product includes software developed by Greg Roelofs
|
||||
and contributors for the book, "PNG: The Definitive
|
||||
Guide," published by O'Reilly and Associates.
|
||||
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.
|
||||
|
||||
----------------------------------------------------------
|
||||
http://www.cdrom.com/pub/png/book/sources.html
|
||||
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.
|
||||
|
||||
53
contrib/gregbook/README.w32
Normal file
53
contrib/gregbook/README.w32
Normal file
@@ -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
|
||||
@@ -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
|
||||
$! Set locations where zlib and libpng sources live.
|
||||
$!
|
||||
$ zlibsrc = "[---.zlib]"
|
||||
$ ccopt="/include=(''zlibsrc',[--])"
|
||||
$ 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" -
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
display_exponent = atof(*argv);
|
||||
if (display_exponent <= 0.0)
|
||||
++error;
|
||||
} else if (!strcmp(*argv, "-bgcolor")) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
bgstr = *argv;
|
||||
if (strlen(bgstr) != 7 || bgstr[0] != '#')
|
||||
++error;
|
||||
else
|
||||
have_bg = TRUE;
|
||||
displayname = *argv;
|
||||
} else if (!strncmp(*argv, "-gamma", 2)) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
else {
|
||||
display_exponent = atof(*argv);
|
||||
if (display_exponent <= 0.0)
|
||||
++error;
|
||||
}
|
||||
} else if (!strncmp(*argv, "-bgcolor", 2)) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
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;
|
||||
|
||||
RedMask = visual->red_mask;
|
||||
GreenMask = visual->green_mask;
|
||||
BlueMask = visual->blue_mask;
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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")) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
bgstr = *argv;
|
||||
if (strlen(bgstr) != 7 || bgstr[0] != '#')
|
||||
++error;
|
||||
else {
|
||||
have_bg = TRUE;
|
||||
bg_image = FALSE;
|
||||
rpng2_info.display_exponent = atof(*argv);
|
||||
if (rpng2_info.display_exponent <= 0.0)
|
||||
++error;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-bgpat")) {
|
||||
} else if (!strncmp(*argv, "-bgcolor", 4)) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
pat = atoi(*argv) - 1;
|
||||
if (pat < 0 || pat >= num_bgpat)
|
||||
else {
|
||||
bgstr = *argv;
|
||||
if (strlen(bgstr) != 7 || bgstr[0] != '#')
|
||||
++error;
|
||||
else {
|
||||
have_bg = TRUE;
|
||||
bg_image = FALSE;
|
||||
}
|
||||
}
|
||||
} else if (!strncmp(*argv, "-bgpat", 4)) {
|
||||
if (!*++argv)
|
||||
++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;
|
||||
|
||||
@@ -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")) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
bgstr = *argv;
|
||||
if (strlen(bgstr) != 7 || bgstr[0] != '#')
|
||||
++error;
|
||||
else {
|
||||
have_bg = TRUE;
|
||||
bg_image = FALSE;
|
||||
rpng2_info.display_exponent = atof(*argv);
|
||||
if (rpng2_info.display_exponent <= 0.0)
|
||||
++error;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-bgpat")) {
|
||||
} else if (!strncmp(*argv, "-bgcolor", 4)) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
pat = atoi(*argv) - 1;
|
||||
if (pat < 0 || pat >= num_bgpat)
|
||||
else {
|
||||
bgstr = *argv;
|
||||
if (strlen(bgstr) != 7 || bgstr[0] != '#')
|
||||
++error;
|
||||
else {
|
||||
have_bg = TRUE;
|
||||
bg_image = FALSE;
|
||||
}
|
||||
}
|
||||
} else if (!strncmp(*argv, "-bgpat", 4)) {
|
||||
if (!*++argv)
|
||||
++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, "-usleep", 2)) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
else {
|
||||
usleep_duration = (ulg)atol(*argv);
|
||||
demo_timing = TRUE;
|
||||
}
|
||||
} 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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
XMatchVisualInfo(display, screen, depth,
|
||||
(depth == 8)? PseudoColor : 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BIN
contrib/gregbook/toucan.png
Normal file
BIN
contrib/gregbook/toucan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -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")) {
|
||||
if (!*++argv)
|
||||
++error;
|
||||
bgstr = *argv;
|
||||
if (strlen(bgstr) != 7 || bgstr[0] != '#')
|
||||
++error;
|
||||
else {
|
||||
unsigned r, g, b; /* this approach quiets compiler warnings */
|
||||
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;
|
||||
else {
|
||||
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;
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user