Imported from libpng-1.0.5.tar
This commit is contained in:
parent
ad5dd1f0fb
commit
860ab2b1c0
7
ANNOUNCE
7
ANNOUNCE
@ -1,5 +1,5 @@
|
||||
|
||||
Libpng 1.0.5 - October 5, 1999
|
||||
Libpng 1.0.5 - October 15, 1999
|
||||
|
||||
This is a public release of libpng, intended for use in production codes.
|
||||
|
||||
@ -60,6 +60,11 @@ Changes since the last public release (1.0.3):
|
||||
Added a "png_check_version" function in png.c and pngtest.c that will generate
|
||||
a helpful compiler error if an old png.h is found in the search path.
|
||||
Added a copy of pngnow.png to the distribution.
|
||||
Surrounded example.c code with #if 0 .. #endif to prevent people from
|
||||
inadvertently trying to compile it.
|
||||
Added type casting mostly in pngrtran.c and pngwtran.c
|
||||
Removed some pointless "ptr = NULL" in pngmem.c
|
||||
Added a "contrib" directory containing the source code from Greg's book.
|
||||
|
||||
Send comments/corrections/commendations to
|
||||
png-implement@ccrc.wustl.edu or to randeg@alum.rpi.edu
|
||||
|
13
CHANGES
13
CHANGES
@ -459,7 +459,18 @@ version 1.0.4b [September 30, 1999]
|
||||
version 1.0.4c [October 1, 1999]
|
||||
Added a "png_check_version" function in png.c and pngtest.c that will generate
|
||||
a helpful compiler error if an old png.h is found in the search path.
|
||||
version 1.0.5 [October 5, 1999]
|
||||
Changed type of png_user_transform_depth|channels from int to png_byte.
|
||||
version 1.0.4d [October 6, 1999]
|
||||
Changed 0.45 to 0.45455 in png_set_sRGB()
|
||||
Removed unused PLTE entries from pngnow.png
|
||||
Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly.
|
||||
version 1.0.4e [October 10, 1999]
|
||||
Fixed sign error in pngvcrd.c (Greg Roelofs)
|
||||
Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P)
|
||||
version 1.0.5 [October 15, 1999]
|
||||
Surrounded example.c code with #if 0 .. #endif to prevent people from
|
||||
inadvertently trying to compile it.
|
||||
Changed png_get_header_version() from a function to a macro in png.h
|
||||
Added type casting mostly in pngrtran.c and pngwtran.c
|
||||
Removed some pointless "ptr = NULL" in pngmem.c
|
||||
Added a "contrib" directory containing the source code from Greg's book.
|
||||
|
79
INSTALL
79
INSTALL
@ -1,5 +1,5 @@
|
||||
|
||||
Installing libpng version 1.0.5 - October 5, 1999
|
||||
Installing libpng version 1.0.5 - October 15, 1999
|
||||
|
||||
Before installing libpng, you must first install zlib. zlib
|
||||
can usually be found wherever you got libpng. zlib can be
|
||||
@ -21,6 +21,8 @@ Your directory structure should look like this:
|
||||
README
|
||||
*.h
|
||||
*.c
|
||||
contrib
|
||||
gregbook
|
||||
scripts
|
||||
makefile.*
|
||||
pngtest.png
|
||||
@ -38,46 +40,46 @@ appropriate makefile.sys in the scripts directory.
|
||||
The files that are presently available in the scripts directory
|
||||
include
|
||||
|
||||
descrip.mms => VMS makefile for MMS or MMK
|
||||
makefile.std => Generic UNIX makefile
|
||||
makefile.knr => Archaic UNIX Makefile that converts files with
|
||||
ansi2knr (Requires ansi2knr.c from
|
||||
ftp://ftp.cs.wisc.edu/ghost)
|
||||
makefile.dec => DEC Alpha UNIX makefile
|
||||
makefile.hpux => HPUX (10.20 and 11.00) makefile
|
||||
makefile.sgi => Silicon Graphics IRIX makefile
|
||||
makefile.sunos => Sun makefile
|
||||
makefile.solaris => Solaris 2.X makefile (gcc, creates libpng.so.2.1.0.5)
|
||||
makefile.linux => Linux/ELF makefile (gcc, creates libpng.so.2.1.0.5)
|
||||
makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc
|
||||
makefile.mips => MIPS makefile
|
||||
makefile.acorn => Acorn makefile
|
||||
makefile.amiga => Amiga makefile
|
||||
smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
|
||||
(Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
|
||||
makefile.atari => Atari makefile
|
||||
makefile.beos => BEOS makefile for X86
|
||||
makefile.borland => Borland makefile
|
||||
build.bat => MS-DOS batch file for Borland compiler
|
||||
makefile.dj2 => DJGPP 2 makefile
|
||||
makefile.msc => Microsoft C makefile
|
||||
makefile.vcawin32 => makefile for Microsoft Visual C++ 5.0 and later (uses
|
||||
assembler code)
|
||||
makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and later (does not
|
||||
use assembler code)
|
||||
makefile.turboc3 => Turbo C 3.0 makefile
|
||||
makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
|
||||
pngos2.def => OS/2 module definition file used by makefile.os2
|
||||
makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model
|
||||
makevms.com => VMS build script
|
||||
pngdll.mak => To make a png32bd.dll with Borland C++ 4.5
|
||||
pngdef.pas => Defines for a png32bd.dll with Borland C++ 4.5
|
||||
SCOPTIONS.ppc => Used with smakefile.ppc
|
||||
descrip.mms => VMS makefile for MMS or MMK
|
||||
makefile.std => Generic UNIX makefile
|
||||
makefile.knr => Archaic UNIX Makefile that converts files with
|
||||
ansi2knr (Requires ansi2knr.c from
|
||||
ftp://ftp.cs.wisc.edu/ghost)
|
||||
makefile.dec => DEC Alpha UNIX makefile
|
||||
makefile.hpux => HPUX (10.20 and 11.00) makefile
|
||||
makefile.sgi => Silicon Graphics IRIX makefile
|
||||
makefile.sunos => Sun makefile
|
||||
makefile.solaris => Solaris 2.X makefile (gcc, creates libpng.so.2.1.0.5)
|
||||
makefile.linux => Linux/ELF makefile (gcc, creates libpng.so.2.1.0.5)
|
||||
makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc
|
||||
makefile.mips => MIPS makefile
|
||||
makefile.acorn => Acorn makefile
|
||||
makefile.amiga => Amiga makefile
|
||||
smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
|
||||
(Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
|
||||
makefile.atari => Atari makefile
|
||||
makefile.beos => BEOS makefile for X86
|
||||
makefile.borland => Borland makefile
|
||||
build.bat => MS-DOS batch file for Borland compiler
|
||||
makefile.dj2 => DJGPP 2 makefile
|
||||
makefile.msc => Microsoft C makefile
|
||||
makefile.vcawin32 => makefile for Microsoft Visual C++ 5.0 and later (uses
|
||||
assembler code)
|
||||
makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and later (does
|
||||
not use assembler code)
|
||||
makefile.turboc3 => Turbo C 3.0 makefile
|
||||
makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
|
||||
pngos2.def => OS/2 module definition file used by makefile.os2
|
||||
makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model
|
||||
makevms.com => VMS build script
|
||||
pngdll.mak => To make a png32bd.dll with Borland C++ 4.5
|
||||
pngdef.pas => Defines for a png32bd.dll with Borland C++ 4.5
|
||||
SCOPTIONS.ppc => Used with smakefile.ppc
|
||||
|
||||
Copy the file (or files) that you need from the
|
||||
scripts directory into this directory, for example
|
||||
|
||||
MSDOS example: copy scripts\makefile.msd makefile
|
||||
MSDOS example: copy scripts\makefile.msc makefile
|
||||
UNIX example: cp scripts/makefile.std makefile
|
||||
|
||||
Read the makefile to see if you need to change any source or
|
||||
@ -89,6 +91,9 @@ changes.
|
||||
Then just run "make test" which will create the libpng library in
|
||||
this directory and run a quick test that reads the "pngtest.png"
|
||||
file and writes a "pngout.png" file that should be identical to it.
|
||||
Look for "9782 zero samples" in the output of the test. For more
|
||||
confidence, you can run another test by typing "pngtest pngnow.png"
|
||||
and looking for "289 zero samples" in the output.
|
||||
|
||||
Most of the makefiles will allow you to run "make install" to
|
||||
put the library in its final resting place (if you want to
|
||||
|
18
KNOWNBUG
18
KNOWNBUG
@ -38,3 +38,21 @@ Known bugs and suggested enhancements in libpng-1.0.4
|
||||
for the png_set_gAMA(), png_set_cHRM(), and corresponding png_get_()
|
||||
functions will be needed.
|
||||
|
||||
4. September 1999 -- BUG [FIXED] --
|
||||
|
||||
Portions of the new MMX code in pngvcrd.c were ifdef'd out because they
|
||||
didn't work properly, but the bug appears to have been found and fixed.
|
||||
As a result, all parts of the code are once again enabled. If you think
|
||||
there's still a problem, you can recompile with one of the following two
|
||||
macros defined and see if the problem goes away:
|
||||
|
||||
DISABLE_PNGVCRD_COMBINE
|
||||
DISABLE_PNGVCRD_INTERLACE
|
||||
|
||||
The second one is in the function where the bug was; as far as we are
|
||||
aware, there was never any bug in the other function. Please notify us
|
||||
if you find any problems in libpng, regardless of whether the two macros
|
||||
make any difference: png-implement@ccrc.wustl.edu
|
||||
|
||||
Again, we believe the MMX code in pngvcrd.c is 100% correct, but it has
|
||||
not yet been tested extensively.
|
||||
|
15
LICENSE
15
LICENSE
@ -5,7 +5,7 @@ Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
Copyright (c) 1996, 1997 Andreas Dilger
|
||||
(libpng versions 0.90, December 1996, through 0.96, May 1997)
|
||||
Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
(libpng versions 0.97, January 1998, through 1.0.5, October 5, 1999)
|
||||
(libpng versions 0.97, January 1998, through 1.0.5, October 15, 1999)
|
||||
|
||||
For the purposes of this copyright and license, "Contributing Authors"
|
||||
is defined as the following set of individuals:
|
||||
@ -54,6 +54,17 @@ supporting the PNG file format in commercial products. If you use this
|
||||
source code in a product, acknowledgment is not required but would be
|
||||
appreciated.
|
||||
|
||||
A "png_get_copyright" function is available, for convenient use in "about"
|
||||
boxes and the like:
|
||||
|
||||
printf("%s",png_get_copyright(NULL));
|
||||
|
||||
Also, the PNG logo (in PNG format, of course) is supplied in the
|
||||
file "pngnow.png".
|
||||
|
||||
Libpng is OSI Certified Open Source Software. OSI Certified is a
|
||||
certification mark of the Open Source Initiative.
|
||||
|
||||
Glenn Randers-Pehrson
|
||||
randeg@alum.rpi.edu
|
||||
October 5, 1999
|
||||
October 15, 1999
|
||||
|
24
README
24
README
@ -1,14 +1,15 @@
|
||||
README for libpng 1.0.5 - October 5, 1999 (shared library 2.1)
|
||||
README for libpng 1.0.5 - October 15, 1999 (shared library 2.1)
|
||||
See the note about version numbers near the top of png.h
|
||||
|
||||
See INSTALL for instructions on how to install libpng.
|
||||
|
||||
This is the first official release of libpng. Don't let the fact that
|
||||
it's the first release fool you. The libpng library has been in
|
||||
extensive use and testing for about two and a half years. However, it's
|
||||
finally gotten to the stage where there haven't been significant
|
||||
Version 0.89 was the first official release of libpng. Don't let the
|
||||
fact that it's the first release fool you. The libpng library has been in
|
||||
extensive use and testing since mid-1995. By late 1997 it had
|
||||
finally gotten to the stage where there hadn't been significant
|
||||
changes to the API in some time, and people have a bad feeling about
|
||||
libraries with versions < 1.0.
|
||||
libraries with versions < 1.0. Version 1.0.0 was released in
|
||||
March 1998.
|
||||
|
||||
****
|
||||
Note that some of the changes to the png_info structure render this
|
||||
@ -28,8 +29,8 @@ directly, to avoid such problems in the future.
|
||||
It is important to note that the APIs do not make current programs
|
||||
that access the info struct directly incompatible with the new
|
||||
library. However, it is strongly suggested that new programs use
|
||||
the new APIs (as shown in example.c), and older programs be converted
|
||||
to the new format, to facilitate upgrades in the future.
|
||||
the new APIs (as shown in example.c and pngtest.c), and older programs
|
||||
be converted to the new format, to facilitate upgrades in the future.
|
||||
****
|
||||
|
||||
Additions since 0.90 include the ability to compile libpng as a
|
||||
@ -50,7 +51,8 @@ critical or an ancillary chunk.
|
||||
|
||||
The changes made to the library, and bugs fixed are based on discussions
|
||||
on the PNG implementation mailing list <png-implement@ccrc.wustl.edu>
|
||||
and not on material submitted to Guy.
|
||||
and not on material submitted privately to Guy, Andreas, or Glenn. They will
|
||||
forward any good suggestions to the list.
|
||||
|
||||
For a detailed description on using libpng, read libpng.txt. For
|
||||
examples of libpng in a program, see example.c and pngtest.c. For usage
|
||||
@ -152,6 +154,10 @@ Files in this distribution:
|
||||
pngwrite.c => High-level write functions
|
||||
pngwtran.c => Write data transformations
|
||||
pngwutil.c => Write utility functions
|
||||
contrib => Contributions
|
||||
gregbook => source code for PNG reading and writing, from
|
||||
Greg Roelofs' "PNG: The Definitive Guide",
|
||||
O'Reilly, 1999
|
||||
scripts => Directory containing scripts for building libpng:
|
||||
descrip.mms => VMS makefile for MMS or MMK
|
||||
makefile.std => Generic UNIX makefile
|
||||
|
2
Y2KINFO
2
Y2KINFO
@ -1,7 +1,7 @@
|
||||
Y2K compliance in libpng:
|
||||
=========================
|
||||
|
||||
October 5, 1999
|
||||
October 15, 1999
|
||||
|
||||
Since the PNG Development group is an ad-hoc body, we can't make
|
||||
an official declaration.
|
||||
|
52
contrib/gregbook/README
Normal file
52
contrib/gregbook/README
Normal file
@ -0,0 +1,52 @@
|
||||
PNG: The Definitive Guide: Source Code
|
||||
|
||||
Chapters 13, 14 and 15 of PNG: The Definitive Guide discuss three
|
||||
cross-platform demo programs that show how to use the libpng reference
|
||||
library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is a
|
||||
very simple example that that shows how a standard file-viewer might use
|
||||
libpng, while the second is designed to process streaming data and shows how
|
||||
a web browser might be written. wpng is a simple command-line program that
|
||||
reads binary PPM files (the ``raw'' RGB subset of NetPBM) and converts them
|
||||
to PNG.
|
||||
|
||||
The source code for all three demo programs currently compiles only under
|
||||
Unix and 32-bit Windows. It has been tested with gcc 2.7.2.3 under Linux and
|
||||
Solaris and with Microsoft Visual C++ 5.0 under Windows 95. Brief
|
||||
instructions for compiling the programs are included at the top of the
|
||||
makefiles; makefile.unx is the Unix version, and makefile.w32 is (you
|
||||
guessed it!) the version for 32-bit Windows. libpng and zlib are required.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
License
|
||||
|
||||
The source code to the demo programs may be used and distributed freely
|
||||
(even if you didn't buy the book--but feel free to do so at any time),
|
||||
subject to the terms of the following BSD-like license:
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above
|
||||
copyright notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above
|
||||
copyright notice, disclaimer, and this list of conditions in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
|
||||
This product includes software developed by Greg Roelofs
|
||||
and contributors for the book, "PNG: The Definitive
|
||||
Guide," published by O'Reilly and Associates.
|
||||
|
||||
----------------------------------------------------------
|
||||
http://www.cdrom.com/pub/png/book/sources.html
|
95
contrib/gregbook/makefile.unx
Normal file
95
contrib/gregbook/makefile.unx
Normal file
@ -0,0 +1,95 @@
|
||||
# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make.
|
||||
# Greg Roelofs
|
||||
# Last modified: 16 February 1999
|
||||
#
|
||||
# The programs built by this makefile are described in the book,
|
||||
# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
|
||||
# Associates, 1999). Go buy a copy, eh? Buy some for friends
|
||||
# and family, too. (Not that this is a blatant plug or anything.)
|
||||
#
|
||||
# Invoke this makefile from a shell prompt in the usual way; for example:
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This makefile builds statically linked executables (against libpng and zlib,
|
||||
# that is), but that can be changed by uncommenting the appropriate PNGLIB and
|
||||
# ZLIB lines.
|
||||
|
||||
|
||||
# macros --------------------------------------------------------------------
|
||||
|
||||
PNGPATH = /usr/local
|
||||
PNGINC = -I$(PNGPATH)/include
|
||||
#PNGLIB = -L$(PNGPATH)/lib -lpng
|
||||
PNGLIB = $(PNGPATH)/lib/libpng.a
|
||||
|
||||
ZPATH = /usr/local
|
||||
ZINC = -I$(ZPATH)/include
|
||||
#ZLIB = -L$(ZPATH)/lib -lz
|
||||
ZLIB = $(ZPATH)/lib/libz.a
|
||||
|
||||
#XPATH = /usr/X11
|
||||
XPATH = /usr/X11R6
|
||||
XINC = -I$(XPATH)/include
|
||||
XLIB = -L$(XPATH)/lib -lX11
|
||||
|
||||
INCS = $(PNGINC) $(ZINC) $(XINC)
|
||||
RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm
|
||||
WLIBS = $(PNGLIB) $(ZLIB) -lm
|
||||
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
RM = rm -f
|
||||
CFLAGS = -O -Wall $(INCS)
|
||||
# [note that -Wall is a gcc-specific compilation flag ("all warnings on")]
|
||||
LDFLAGS =
|
||||
O = .o
|
||||
E =
|
||||
|
||||
RPNG = rpng-x
|
||||
RPNG2 = rpng2-x
|
||||
WPNG = wpng
|
||||
|
||||
ROBJS = $(RPNG)$(O) readpng$(O)
|
||||
ROBJS2 = $(RPNG2)$(O) readpng2$(O)
|
||||
WOBJS = $(WPNG)$(O) writepng$(O)
|
||||
|
||||
EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
|
||||
|
||||
|
||||
# implicit make rules -------------------------------------------------------
|
||||
|
||||
.c$(O):
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
|
||||
# dependencies --------------------------------------------------------------
|
||||
|
||||
all: $(EXES)
|
||||
|
||||
$(RPNG)$(E): $(ROBJS)
|
||||
$(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS)
|
||||
|
||||
$(RPNG2)$(E): $(ROBJS2)
|
||||
$(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS)
|
||||
|
||||
$(WPNG)$(E): $(WOBJS)
|
||||
$(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS)
|
||||
|
||||
$(RPNG)$(O): $(RPNG).c readpng.h
|
||||
$(RPNG2)$(O): $(RPNG2).c readpng2.h
|
||||
$(WPNG)$(O): $(WPNG).c writepng.h
|
||||
|
||||
readpng$(O): readpng.c readpng.h
|
||||
readpng2$(O): readpng2.c readpng2.h
|
||||
writepng$(O): writepng.c writepng.h
|
||||
|
||||
|
||||
# maintenance ---------------------------------------------------------------
|
||||
|
||||
clean:
|
||||
$(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
|
112
contrib/gregbook/makefile.w32
Normal file
112
contrib/gregbook/makefile.w32
Normal file
@ -0,0 +1,112 @@
|
||||
# Sample makefile for rpng-win / rpng2-win / wpng using MSVC and NMAKE.
|
||||
# Greg Roelofs
|
||||
# Last modified: 16 February 1999
|
||||
#
|
||||
# The programs built by this makefile are described in the book,
|
||||
# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
|
||||
# Associates, 1999). Go buy a copy, eh? Buy some for friends
|
||||
# and family, too. (Not that this is a blatant plug or anything.)
|
||||
#
|
||||
# Invoke this makefile from a DOS prompt window via:
|
||||
#
|
||||
# %devstudio%\vc\bin\vcvars32.bat
|
||||
# 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.
|
||||
#
|
||||
# Note that the names of the dynamic and static libpng and zlib libraries
|
||||
# used below may change in later releases of the libraries. This makefile
|
||||
# builds statically linked executables, but that can be changed by uncom-
|
||||
# menting the appropriate PNGLIB and ZLIB lines.
|
||||
|
||||
!include <ntwin32.mak>
|
||||
|
||||
|
||||
# macros --------------------------------------------------------------------
|
||||
|
||||
PNGPATH = ../libpng
|
||||
PNGINC = -I$(PNGPATH)
|
||||
#PNGLIB = $(PNGPATH)/pngdll.lib
|
||||
PNGLIB = $(PNGPATH)/libpng.lib
|
||||
|
||||
ZPATH = ../zlib
|
||||
ZINC = -I$(ZPATH)
|
||||
#ZLIB = $(ZPATH)/zlibdll.lib
|
||||
ZLIB = $(ZPATH)/zlibstat.lib
|
||||
|
||||
WINLIBS = -defaultlib:user32.lib gdi32.lib
|
||||
# ["real" apps may also need comctl32.lib, comdlg32.lib, winmm.lib, etc.]
|
||||
|
||||
INCS = $(PNGINC) $(ZINC)
|
||||
RLIBS = $(PNGLIB) $(ZLIB) $(WINLIBS)
|
||||
WLIBS = $(PNGLIB) $(ZLIB)
|
||||
|
||||
CC = cl
|
||||
LD = link
|
||||
RM = del
|
||||
CFLAGS = -nologo -O -W3 $(INCS) $(cvars)
|
||||
# [note that -Wall is an MSVC-specific compilation flag ("all warnings on")]
|
||||
# [see %devstudio%\vc\include\win32.mak for cvars macro definition]
|
||||
O = .obj
|
||||
E = .exe
|
||||
|
||||
RLDFLAGS = -nologo -subsystem:windows
|
||||
WLDFLAGS = -nologo
|
||||
|
||||
RPNG = rpng-win
|
||||
RPNG2 = rpng2-win
|
||||
WPNG = wpng
|
||||
|
||||
ROBJS = $(RPNG)$(O) readpng$(O)
|
||||
ROBJS2 = $(RPNG2)$(O) readpng2$(O)
|
||||
WOBJS = $(WPNG)$(O) writepng$(O)
|
||||
|
||||
EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
|
||||
|
||||
|
||||
# implicit make rules -------------------------------------------------------
|
||||
|
||||
.c$(O):
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
|
||||
# dependencies --------------------------------------------------------------
|
||||
|
||||
all: $(EXES)
|
||||
|
||||
$(RPNG)$(E): $(ROBJS)
|
||||
$(LD) $(RLDFLAGS) -out:$@ $(ROBJS) $(RLIBS)
|
||||
|
||||
$(RPNG2)$(E): $(ROBJS2)
|
||||
$(LD) $(RLDFLAGS) -out:$@ $(ROBJS2) $(RLIBS)
|
||||
|
||||
$(WPNG)$(E): $(WOBJS)
|
||||
$(LD) $(WLDFLAGS) -out:$@ $(WOBJS) $(WLIBS)
|
||||
|
||||
$(RPNG)$(O): $(RPNG).c readpng.h
|
||||
$(RPNG2)$(O): $(RPNG2).c readpng2.h
|
||||
$(WPNG)$(O): $(WPNG).c writepng.h
|
||||
|
||||
readpng$(O): readpng.c readpng.h
|
||||
readpng2$(O): readpng2.c readpng2.h
|
||||
writepng$(O): writepng.c writepng.h
|
||||
|
||||
|
||||
# maintenance ---------------------------------------------------------------
|
||||
|
||||
clean:
|
||||
# ideally we could just do this:
|
||||
# $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
|
||||
# ...but the Windows "DEL" command is none too bright, so:
|
||||
$(RM) r*$(E)
|
||||
$(RM) w*$(E)
|
||||
$(RM) r*$(O)
|
||||
$(RM) w*$(O)
|
275
contrib/gregbook/readpng.c
Normal file
275
contrib/gregbook/readpng.c
Normal file
@ -0,0 +1,275 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
rpng - simple PNG display program readpng.c
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "png.h" /* libpng header; includes zlib.h */
|
||||
#include "readpng.h" /* typedefs, common macros, public prototypes */
|
||||
|
||||
|
||||
static png_structp png_ptr = NULL;
|
||||
static png_infop info_ptr = NULL;
|
||||
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type;
|
||||
uch *image_data = NULL;
|
||||
|
||||
|
||||
void readpng_version_info()
|
||||
{
|
||||
fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
|
||||
PNG_LIBPNG_VER_STRING, png_libpng_ver);
|
||||
fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
|
||||
ZLIB_VERSION, zlib_version);
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
uch sig[8];
|
||||
|
||||
|
||||
/* first do a quick check that the file really is a PNG image; could
|
||||
* have used slightly more general png_sig_cmp() function instead */
|
||||
|
||||
fread(sig, 1, 8, infile);
|
||||
if (!png_check_sig(sig, 8))
|
||||
return 1; /* bad signature */
|
||||
|
||||
|
||||
/* could pass pointers to user-defined error handlers instead of NULLs: */
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
return 4; /* out of memory */
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
return 4; /* out of memory */
|
||||
}
|
||||
|
||||
|
||||
/* we could create a second info struct here (end_info), but it's only
|
||||
* useful if we want to keep pre- and post-IDAT chunk info separated
|
||||
* (mainly for PNG-aware image editors and converters) */
|
||||
|
||||
|
||||
/* setjmp() must be called in every function that calls a PNG-reading
|
||||
* libpng function */
|
||||
|
||||
if (setjmp(png_ptr->jmpbuf)) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
png_init_io(png_ptr, infile);
|
||||
png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */
|
||||
|
||||
png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */
|
||||
|
||||
|
||||
/* alternatively, could make separate calls to png_get_image_width(),
|
||||
* etc., but want bit_depth and color_type for later [don't care about
|
||||
* compression_type and filter_type => NULLs] */
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
NULL, NULL, NULL);
|
||||
*pWidth = width;
|
||||
*pHeight = height;
|
||||
|
||||
|
||||
/* OK, that's all we need for now; return happy */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;
|
||||
* scales values to 8-bit if necessary */
|
||||
|
||||
int readpng_get_bgcolor(uch *red, uch *green, uch *blue)
|
||||
{
|
||||
png_color_16p pBackground;
|
||||
|
||||
|
||||
/* setjmp() must be called in every function that calls a PNG-reading
|
||||
* libpng function */
|
||||
|
||||
if (setjmp(png_ptr->jmpbuf)) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
|
||||
return 1;
|
||||
|
||||
/* it is not obvious from the libpng documentation, but this function
|
||||
* takes a pointer to a pointer, and it always returns valid red, green
|
||||
* and blue values, regardless of color_type: */
|
||||
|
||||
png_get_bKGD(png_ptr, info_ptr, &pBackground);
|
||||
|
||||
|
||||
/* however, it always returns the raw bKGD data, regardless of any
|
||||
* bit-depth transformations, so check depth and adjust if necessary */
|
||||
|
||||
if (bit_depth == 16) {
|
||||
*red = pBackground->red >> 8;
|
||||
*green = pBackground->green >> 8;
|
||||
*blue = pBackground->blue >> 8;
|
||||
} else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
|
||||
if (bit_depth == 1)
|
||||
*red = *green = *blue = pBackground->gray? 255 : 0;
|
||||
else if (bit_depth == 2)
|
||||
*red = *green = *blue = (255/3) * pBackground->gray;
|
||||
else /* bit_depth == 4 */
|
||||
*red = *green = *blue = (255/15) * pBackground->gray;
|
||||
} else {
|
||||
*red = (uch)pBackground->red;
|
||||
*green = (uch)pBackground->green;
|
||||
*blue = (uch)pBackground->blue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* display_exponent == LUT_exponent * CRT_exponent */
|
||||
|
||||
uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
|
||||
{
|
||||
double gamma;
|
||||
png_uint_32 i, rowbytes;
|
||||
png_bytepp row_pointers = NULL;
|
||||
|
||||
|
||||
/* setjmp() must be called in every function that calls a PNG-reading
|
||||
* libpng function */
|
||||
|
||||
if (setjmp(png_ptr->jmpbuf)) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
|
||||
* transparency chunks to full alpha channel; strip 16-bit-per-sample
|
||||
* images to 8 bits per sample; and convert grayscale to RGB[A] */
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_expand(png_ptr);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand(png_ptr);
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_expand(png_ptr);
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
|
||||
|
||||
/* unlike the example in the libpng documentation, we have *no* idea where
|
||||
* this file may have come from--so if it doesn't have a file gamma, don't
|
||||
* do any correction ("do no harm") */
|
||||
|
||||
if (png_get_gAMA(png_ptr, info_ptr, &gamma))
|
||||
png_set_gamma(png_ptr, display_exponent, gamma);
|
||||
|
||||
|
||||
/* all transformations have been registered; now update info_ptr data,
|
||||
* get rowbytes and channels, and allocate image memory */
|
||||
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
*pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
*pChannels = (int)png_get_channels(png_ptr, info_ptr);
|
||||
|
||||
if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return NULL;
|
||||
}
|
||||
if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
free(image_data);
|
||||
image_data = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height));
|
||||
|
||||
|
||||
/* set the individual row_pointers to point at the correct offsets */
|
||||
|
||||
for (i = 0; i < height; ++i)
|
||||
row_pointers[i] = image_data + i*rowbytes;
|
||||
|
||||
|
||||
/* now we can go ahead and just read the whole image */
|
||||
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
|
||||
/* and we're done! (png_read_end() can be omitted if no processing of
|
||||
* post-IDAT text/time/etc. is desired) */
|
||||
|
||||
free(row_pointers);
|
||||
row_pointers = NULL;
|
||||
|
||||
png_read_end(png_ptr, NULL);
|
||||
|
||||
return image_data;
|
||||
}
|
||||
|
||||
|
||||
void readpng_cleanup(int free_image_data)
|
||||
{
|
||||
if (free_image_data && image_data) {
|
||||
free(image_data);
|
||||
image_data = NULL;
|
||||
}
|
||||
|
||||
if (png_ptr && info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
png_ptr = NULL;
|
||||
info_ptr = NULL;
|
||||
}
|
||||
}
|
64
contrib/gregbook/readpng.h
Normal file
64
contrib/gregbook/readpng.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
rpng - simple PNG display program readpng.h
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) ((a) > (b)? (a) : (b))
|
||||
# define MIN(a,b) ((a) < (b)? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
|
||||
#else
|
||||
# define Trace(x) ;
|
||||
#endif
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
|
||||
/* prototypes for public functions in readpng.c */
|
||||
|
||||
void readpng_version_info(void);
|
||||
|
||||
int readpng_init(FILE *infile, long *pWidth, long *pHeight);
|
||||
|
||||
int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue);
|
||||
|
||||
uch *readpng_get_image(double display_exponent, int *pChannels,
|
||||
ulg *pRowbytes);
|
||||
|
||||
void readpng_cleanup(int free_image_data);
|
419
contrib/gregbook/readpng2.c
Normal file
419
contrib/gregbook/readpng2.c
Normal file
@ -0,0 +1,419 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
rpng2 - progressive-model PNG display program readpng2.c
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
/* local prototypes */
|
||||
|
||||
static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr);
|
||||
static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
png_uint_32 row_num, int pass);
|
||||
static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);
|
||||
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
|
||||
|
||||
|
||||
|
||||
|
||||
void readpng2_version_info()
|
||||
{
|
||||
fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
|
||||
PNG_LIBPNG_VER_STRING, png_libpng_ver);
|
||||
fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
|
||||
ZLIB_VERSION, zlib_version);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int readpng2_check_sig(uch *sig, int num)
|
||||
{
|
||||
return png_check_sig(sig, num);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns 0 for success, 2 for libpng problem, 4 for out of memory */
|
||||
|
||||
int readpng2_init(mainprog_info *mainprog_ptr)
|
||||
{
|
||||
png_structp png_ptr; /* note: temporary variables! */
|
||||
png_infop info_ptr;
|
||||
|
||||
|
||||
/* could also replace libpng warning-handler (final NULL), but no need: */
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
|
||||
readpng2_error_handler, NULL);
|
||||
if (!png_ptr)
|
||||
return 4; /* out of memory */
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
return 4; /* out of memory */
|
||||
}
|
||||
|
||||
|
||||
/* we could create a second info struct here (end_info), but it's only
|
||||
* useful if we want to keep pre- and post-IDAT chunk info separated
|
||||
* (mainly for PNG-aware image editors and converters) */
|
||||
|
||||
|
||||
/* setjmp() must be called in every function that calls a PNG-reading
|
||||
* libpng function, unless an alternate error handler was installed--
|
||||
* but compatible error handlers must either use longjmp() themselves
|
||||
* (as in this program) or exit immediately, so here we are: */
|
||||
|
||||
if (setjmp(mainprog_ptr->jmpbuf)) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* instead of doing png_init_io() here, now we set up our callback
|
||||
* functions for progressive decoding */
|
||||
|
||||
png_set_progressive_read_fn(png_ptr, mainprog_ptr,
|
||||
readpng2_info_callback, readpng2_row_callback, readpng2_end_callback);
|
||||
|
||||
|
||||
/* make sure we save our pointers for use in readpng2_decode_data() */
|
||||
|
||||
mainprog_ptr->png_ptr = png_ptr;
|
||||
mainprog_ptr->info_ptr = info_ptr;
|
||||
|
||||
|
||||
/* and that's all there is to initialization */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns 0 for success, 2 for libpng (longjmp) problem */
|
||||
|
||||
int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length)
|
||||
{
|
||||
png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
|
||||
png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
|
||||
|
||||
|
||||
/* setjmp() must be called in every function that calls a PNG-reading
|
||||
* libpng function */
|
||||
|
||||
if (setjmp(mainprog_ptr->jmpbuf)) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
mainprog_ptr->png_ptr = NULL;
|
||||
mainprog_ptr->info_ptr = NULL;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* hand off the next chunk of input data to libpng for decoding */
|
||||
|
||||
png_process_data(png_ptr, info_ptr, rawbuf, length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
mainprog_info *mainprog_ptr;
|
||||
int color_type, bit_depth;
|
||||
double gamma;
|
||||
|
||||
|
||||
/* setjmp() doesn't make sense here, because we'd either have to exit(),
|
||||
* longjmp() ourselves, or return control to libpng, which doesn't want
|
||||
* to see us again. By not doing anything here, libpng will instead jump
|
||||
* to readpng2_decode_data(), which can return an error value to the main
|
||||
* program. */
|
||||
|
||||
|
||||
/* retrieve the pointer to our special-purpose struct, using the png_ptr
|
||||
* that libpng passed back to us (i.e., not a global this time--there's
|
||||
* no real difference for a single image, but for a multithreaded browser
|
||||
* decoding several PNG images at the same time, one needs to avoid mixing
|
||||
* up different images' structs) */
|
||||
|
||||
mainprog_ptr = png_get_progressive_ptr(png_ptr);
|
||||
|
||||
if (mainprog_ptr == NULL) { /* we be hosed */
|
||||
fprintf(stderr,
|
||||
"readpng2 error: main struct not recoverable in info_callback.\n");
|
||||
fflush(stderr);
|
||||
return;
|
||||
/*
|
||||
* Alternatively, we could call our error-handler just like libpng
|
||||
* does, which would effectively terminate the program. Since this
|
||||
* can only happen if png_ptr gets redirected somewhere odd or the
|
||||
* main PNG struct gets wiped, we're probably toast anyway. (If
|
||||
* png_ptr itself is NULL, we would not have been called.)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* this is just like in the non-progressive case */
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &mainprog_ptr->width,
|
||||
&mainprog_ptr->height, &bit_depth, &color_type, NULL, NULL, NULL);
|
||||
|
||||
|
||||
/* since we know we've read all of the PNG file's "header" (i.e., up
|
||||
* to IDAT), we can check for a background color here */
|
||||
|
||||
if (mainprog_ptr->need_bgcolor &&
|
||||
png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
|
||||
{
|
||||
png_color_16p pBackground;
|
||||
|
||||
/* it is not obvious from the libpng documentation, but this function
|
||||
* takes a pointer to a pointer, and it always returns valid red,
|
||||
* green and blue values, regardless of color_type: */
|
||||
png_get_bKGD(png_ptr, info_ptr, &pBackground);
|
||||
|
||||
/* however, it always returns the raw bKGD data, regardless of any
|
||||
* bit-depth transformations, so check depth and adjust if necessary */
|
||||
if (bit_depth == 16) {
|
||||
mainprog_ptr->bg_red = pBackground->red >> 8;
|
||||
mainprog_ptr->bg_green = pBackground->green >> 8;
|
||||
mainprog_ptr->bg_blue = pBackground->blue >> 8;
|
||||
} else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
|
||||
if (bit_depth == 1)
|
||||
mainprog_ptr->bg_red = mainprog_ptr->bg_green =
|
||||
mainprog_ptr->bg_blue = pBackground->gray? 255 : 0;
|
||||
else if (bit_depth == 2)
|
||||
mainprog_ptr->bg_red = mainprog_ptr->bg_green =
|
||||
mainprog_ptr->bg_blue = (255/3) * pBackground->gray;
|
||||
else /* bit_depth == 4 */
|
||||
mainprog_ptr->bg_red = mainprog_ptr->bg_green =
|
||||
mainprog_ptr->bg_blue = (255/15) * pBackground->gray;
|
||||
} else {
|
||||
mainprog_ptr->bg_red = (uch)pBackground->red;
|
||||
mainprog_ptr->bg_green = (uch)pBackground->green;
|
||||
mainprog_ptr->bg_blue = (uch)pBackground->blue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* as before, let libpng expand palette images to RGB, low-bit-depth
|
||||
* grayscale images to 8 bits, transparency chunks to full alpha channel;
|
||||
* strip 16-bit-per-sample images to 8 bits per sample; and convert
|
||||
* grayscale to RGB[A] */
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_expand(png_ptr);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand(png_ptr);
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_expand(png_ptr);
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
|
||||
|
||||
/* Unlike the basic viewer, which was designed to operate on local files,
|
||||
* this program is intended to simulate a web browser--even though we
|
||||
* actually read from a local file, too. But because we are pretending
|
||||
* that most of the images originate on the Internet, we follow the recom-
|
||||
* mendation of the sRGB proposal and treat unlabelled images (no gAMA
|
||||
* chunk) as existing in the sRGB color space. That is, we assume that
|
||||
* such images have a file gamma of 0.45455, which corresponds to a PC-like
|
||||
* display system. This change in assumptions will have no effect on a
|
||||
* PC-like system, but on a Mac, SGI, NeXT or other system with a non-
|
||||
* identity lookup table, it will darken unlabelled images, which effec-
|
||||
* tively favors images from PC-like systems over those originating on
|
||||
* the local platform. Note that mainprog_ptr->display_exponent is the
|
||||
* "gamma" value for the entire display system, i.e., the product of
|
||||
* LUT_exponent and CRT_exponent. */
|
||||
|
||||
if (png_get_gAMA(png_ptr, info_ptr, &gamma))
|
||||
png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma);
|
||||
else
|
||||
png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455);
|
||||
|
||||
|
||||
/* we'll let libpng expand interlaced images, too */
|
||||
|
||||
mainprog_ptr->passes = png_set_interlace_handling(png_ptr);
|
||||
|
||||
|
||||
/* all transformations have been registered; now update info_ptr data and
|
||||
* then get rowbytes and channels */
|
||||
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
mainprog_ptr->rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr);
|
||||
|
||||
|
||||
/* Call the main program to allocate memory for the image buffer and
|
||||
* initialize windows and whatnot. (The old-style function-pointer
|
||||
* invocation is used for compatibility with a few supposedly ANSI
|
||||
* compilers that nevertheless barf on "fn_ptr()"-style syntax.) */
|
||||
|
||||
(*mainprog_ptr->mainprog_init)();
|
||||
|
||||
|
||||
/* and that takes care of initialization */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
png_uint_32 row_num, int pass)
|
||||
{
|
||||
mainprog_info *mainprog_ptr;
|
||||
|
||||
|
||||
/* first check whether the row differs from the previous pass; if not,
|
||||
* nothing to combine or display */
|
||||
|
||||
if (!new_row)
|
||||
return;
|
||||
|
||||
|
||||
/* retrieve the pointer to our special-purpose struct so we can access
|
||||
* the old rows and image-display callback function */
|
||||
|
||||
mainprog_ptr = png_get_progressive_ptr(png_ptr);
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num],
|
||||
new_row);
|
||||
|
||||
|
||||
/* finally, call the display routine in the main program with the number
|
||||
* of the row we just updated */
|
||||
|
||||
(*mainprog_ptr->mainprog_display_row)(row_num);
|
||||
|
||||
|
||||
/* and we're ready for more */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
mainprog_info *mainprog_ptr;
|
||||
|
||||
|
||||
/* retrieve the pointer to our special-purpose struct */
|
||||
|
||||
mainprog_ptr = png_get_progressive_ptr(png_ptr);
|
||||
|
||||
|
||||
/* let the main program know that it should flush any buffered image
|
||||
* data to the display now and set a "done" flag or whatever, but note
|
||||
* that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do
|
||||
* NOT call readpng2_cleanup() either here or in the finish_display()
|
||||
* routine; wait until control returns to the main program via
|
||||
* readpng2_decode_data() */
|
||||
|
||||
(*mainprog_ptr->mainprog_finish_display)();
|
||||
|
||||
|
||||
/* all done */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void readpng2_cleanup(mainprog_info *mainprog_ptr)
|
||||
{
|
||||
png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
|
||||
png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
|
||||
|
||||
if (png_ptr && info_ptr)
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
|
||||
mainprog_ptr->png_ptr = NULL;
|
||||
mainprog_ptr->info_ptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
|
||||
{
|
||||
mainprog_info *mainprog_ptr;
|
||||
|
||||
/* This function, aside from the extra step of retrieving the "error
|
||||
* pointer" (below) and the fact that it exists within the application
|
||||
* rather than within libpng, is essentially identical to libpng's
|
||||
* default error handler. The second point is critical: since both
|
||||
* setjmp() and longjmp() are called from the same code, they are
|
||||
* guaranteed to have compatible notions of how big a jmp_buf is,
|
||||
* regardless of whether _BSD_SOURCE or anything else has (or has not)
|
||||
* been defined. */
|
||||
|
||||
fprintf(stderr, "readpng2 libpng error: %s\n", msg);
|
||||
fflush(stderr);
|
||||
|
||||
mainprog_ptr = png_get_error_ptr(png_ptr);
|
||||
if (mainprog_ptr == NULL) { /* we are completely hosed now */
|
||||
fprintf(stderr,
|
||||
"readpng2 severe error: jmpbuf not recoverable; terminating.\n");
|
||||
fflush(stderr);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
longjmp(mainprog_ptr->jmpbuf, 1);
|
||||
}
|
85
contrib/gregbook/readpng2.h
Normal file
85
contrib/gregbook/readpng2.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
rpng2 - progressive-model PNG display program readpng2.h
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) ((a) > (b)? (a) : (b))
|
||||
# define MIN(a,b) ((a) < (b)? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
|
||||
#else
|
||||
# define Trace(x) ;
|
||||
#endif
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
typedef struct _mainprog_info {
|
||||
double display_exponent;
|
||||
ulg width;
|
||||
ulg height;
|
||||
void *png_ptr;
|
||||
void *info_ptr;
|
||||
void (*mainprog_init)(void);
|
||||
void (*mainprog_display_row)(ulg row_num);
|
||||
void (*mainprog_finish_display)(void);
|
||||
uch *image_data;
|
||||
uch **row_pointers;
|
||||
jmp_buf jmpbuf;
|
||||
int passes; /* not used */
|
||||
int rowbytes;
|
||||
int channels;
|
||||
int need_bgcolor;
|
||||
int done;
|
||||
uch bg_red;
|
||||
uch bg_green;
|
||||
uch bg_blue;
|
||||
} mainprog_info;
|
||||
|
||||
|
||||
/* prototypes for public functions in readpng2.c */
|
||||
|
||||
void readpng2_version_info(void);
|
||||
|
||||
int readpng2_check_sig(uch *sig, int num);
|
||||
|
||||
int readpng2_init(mainprog_info *mainprog_ptr);
|
||||
|
||||
int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length);
|
||||
|
||||
void readpng2_cleanup(mainprog_info *mainprog_ptr);
|
600
contrib/gregbook/rpng-win.c
Normal file
600
contrib/gregbook/rpng-win.c
Normal file
@ -0,0 +1,600 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
rpng - simple PNG display program rpng-win.c
|
||||
|
||||
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 32-bit Windows; it may compile under 16-bit Windows
|
||||
with a little tweaking (or maybe not).
|
||||
|
||||
to do:
|
||||
- stdout/stderr don't work! need message window (maybe scrollable?)
|
||||
- handle quoted command-line args (especially filenames with spaces)
|
||||
- have minimum window width: oh well
|
||||
- use %.1023s to simplify truncation of title-bar string?
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define PROGNAME "rpng-win"
|
||||
#define LONGNAME "Simple PNG Viewer for Windows"
|
||||
#define VERSION "1.0 of 20 February 1999"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* #define DEBUG : this enables the Trace() macros */
|
||||
|
||||
#include "readpng.h" /* typedefs, common macros, readpng prototypes */
|
||||
|
||||
|
||||
/* could just include png.h, but this macro is the only thing we need
|
||||
* (name and typedefs changed to local versions); note that side effects
|
||||
* 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); \
|
||||
}
|
||||
|
||||
|
||||
/* local prototypes */
|
||||
static int rpng_win_create_window(HINSTANCE hInst, int showmode);
|
||||
static int rpng_win_display_image(void);
|
||||
static void rpng_win_cleanup(void);
|
||||
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 *filename;
|
||||
static FILE *infile;
|
||||
|
||||
static char *bgstr;
|
||||
static uch bg_red=0, bg_green=0, bg_blue=0;
|
||||
|
||||
static double display_exponent;
|
||||
|
||||
static ulg image_width, image_height, image_rowbytes;
|
||||
static int image_channels;
|
||||
static uch *image_data;
|
||||
|
||||
/* Windows-specific variables */
|
||||
static ulg wimage_rowbytes;
|
||||
static uch *dib;
|
||||
static uch *wimage_data;
|
||||
static BITMAPINFOHEADER *bmih;
|
||||
|
||||
static HWND global_hwnd;
|
||||
|
||||
|
||||
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
|
||||
{
|
||||
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 */
|
||||
MSG msg;
|
||||
|
||||
|
||||
filename = (char *)NULL;
|
||||
|
||||
|
||||
/* First set the default value for our display-system exponent, i.e.,
|
||||
* the product of the CRT exponent and the exponent corresponding to
|
||||
* the frame-buffer's lookup table (LUT), if any. This is not an
|
||||
* exhaustive list of LUT values (e.g., OpenStep has a lot of weird
|
||||
* ones), but it should cover 99% of the current possibilities. And
|
||||
* yes, these ifdefs are completely wasted in a Windows program... */
|
||||
|
||||
#if defined(NeXT)
|
||||
LUT_exponent = 1.0 / 2.2;
|
||||
/*
|
||||
if (some_next_function_that_returns_gamma(&next_gamma))
|
||||
LUT_exponent = 1.0 / next_gamma;
|
||||
*/
|
||||
#elif defined(sgi)
|
||||
LUT_exponent = 1.0 / 1.7;
|
||||
/* there doesn't seem to be any documented function to get the
|
||||
* "gamma" value, so we do it the hard way */
|
||||
infile = fopen("/etc/config/system.glGammaVal", "r");
|
||||
if (infile) {
|
||||
double sgi_gamma;
|
||||
|
||||
fgets(tmpline, 80, infile);
|
||||
fclose(infile);
|
||||
sgi_gamma = atof(tmpline);
|
||||
if (sgi_gamma > 0.0)
|
||||
LUT_exponent = 1.0 / sgi_gamma;
|
||||
}
|
||||
#elif defined(Macintosh)
|
||||
LUT_exponent = 1.8 / 2.61;
|
||||
/*
|
||||
if (some_mac_function_that_returns_gamma(&mac_gamma))
|
||||
LUT_exponent = mac_gamma / 2.61;
|
||||
*/
|
||||
#else
|
||||
LUT_exponent = 1.0; /* assume no LUT: most PCs */
|
||||
#endif
|
||||
|
||||
/* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
|
||||
default_display_exponent = LUT_exponent * CRT_exponent;
|
||||
|
||||
|
||||
/* If the user has set the SCREEN_GAMMA environment variable as suggested
|
||||
* (somewhat imprecisely) in the libpng documentation, use that; otherwise
|
||||
* use the default value we just calculated. Either way, the user may
|
||||
* override this via a command-line option. */
|
||||
|
||||
if ((p = getenv("SCREEN_GAMMA")) != NULL)
|
||||
display_exponent = atof(p);
|
||||
else
|
||||
display_exponent = default_display_exponent;
|
||||
|
||||
|
||||
/* Windows really hates command lines, so we have to set up our own argv.
|
||||
* Note that we do NOT bother with quoted arguments here, so don't use
|
||||
* filenames with spaces in 'em! */
|
||||
|
||||
argv[argc++] = PROGNAME;
|
||||
p = cmd;
|
||||
for (;;) {
|
||||
if (*p == ' ')
|
||||
while (*++p == ' ')
|
||||
;
|
||||
/* now p points at the first non-space after some spaces */
|
||||
if (*p == '\0')
|
||||
break; /* nothing after the spaces: done */
|
||||
argv[argc++] = q = p;
|
||||
while (*q && *q != ' ')
|
||||
++q;
|
||||
/* now q points at a space or the end of the string */
|
||||
if (*q == '\0')
|
||||
break; /* last argv already terminated; quit */
|
||||
*q = '\0'; /* change space to terminator */
|
||||
p = q + 1;
|
||||
}
|
||||
argv[argc] = NULL; /* terminate the argv array itself */
|
||||
|
||||
|
||||
/* Now parse the command line for options and the PNG filename. */
|
||||
|
||||
while (*++argv && !error) {
|
||||
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;
|
||||
} else {
|
||||
if (**argv != '-') {
|
||||
filename = *argv;
|
||||
if (argv[1]) /* shouldn't be any more args after filename */
|
||||
++error;
|
||||
} else
|
||||
++error; /* not expecting any other options */
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
++error;
|
||||
} else if (!(infile = fopen(filename, "rb"))) {
|
||||
fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
|
||||
++error;
|
||||
} else {
|
||||
if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
|
||||
switch (rc) {
|
||||
case 1:
|
||||
fprintf(stderr, PROGNAME
|
||||
": [%s] is not a PNG file: incorrect signature\n",
|
||||
filename);
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr, PROGNAME
|
||||
": [%s] has bad IHDR (libpng longjmp)\n",
|
||||
filename);
|
||||
break;
|
||||
case 4:
|
||||
fprintf(stderr, PROGNAME ": insufficient memory\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, PROGNAME
|
||||
": unknown readpng_init() error\n");
|
||||
break;
|
||||
}
|
||||
++error;
|
||||
}
|
||||
if (error)
|
||||
fclose(infile);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
|
||||
readpng_version_info();
|
||||
fprintf(stderr, "\n"
|
||||
"Usage: %s [-gamma exp] [-bgcolor bg] file.png\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);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* set the title-bar string, but make sure buffer doesn't overflow */
|
||||
|
||||
alen = strlen(appname);
|
||||
flen = strlen(filename);
|
||||
if (alen + flen + 3 > 1023)
|
||||
sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
|
||||
else
|
||||
sprintf(titlebar, "%s: %s", appname, filename);
|
||||
|
||||
|
||||
/* if the user didn't specify a background color on the command line,
|
||||
* check for one in the PNG file--if not, the initialized values of 0
|
||||
* (black) will be used */
|
||||
|
||||
if (have_bg)
|
||||
sscanf(bgstr+1, "%2x%2x%2x", &bg_red, &bg_green, &bg_blue);
|
||||
else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {
|
||||
readpng_cleanup(TRUE);
|
||||
fprintf(stderr, PROGNAME
|
||||
": libpng error while checking for background color\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
/* do the basic Windows initialization stuff, make the window and fill it
|
||||
* with the background color */
|
||||
|
||||
if (rpng_win_create_window(hInst, showmode))
|
||||
exit(2);
|
||||
|
||||
|
||||
/* decode the image, all at once */
|
||||
|
||||
Trace((stderr, "calling readpng_get_image()\n"))
|
||||
image_data = readpng_get_image(display_exponent, &image_channels,
|
||||
&image_rowbytes);
|
||||
Trace((stderr, "done with readpng_get_image()\n"))
|
||||
|
||||
|
||||
/* done with PNG file, so clean up to minimize memory usage (but do NOT
|
||||
* nuke image_data!) */
|
||||
|
||||
readpng_cleanup(FALSE);
|
||||
fclose(infile);
|
||||
|
||||
if (!image_data) {
|
||||
fprintf(stderr, PROGNAME ": unable to decode PNG image\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
|
||||
/* display image (composite with background if requested) */
|
||||
|
||||
Trace((stderr, "calling rpng_win_display_image()\n"))
|
||||
if (rpng_win_display_image()) {
|
||||
free(image_data);
|
||||
exit(4);
|
||||
}
|
||||
Trace((stderr, "done with rpng_win_display_image()\n"))
|
||||
|
||||
|
||||
/* wait for the user to tell us when to quit */
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
|
||||
/* OK, we're done: clean up all image and Windows resources and go away */
|
||||
|
||||
rpng_win_cleanup();
|
||||
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int rpng_win_create_window(HINSTANCE hInst, int showmode)
|
||||
{
|
||||
uch *dest;
|
||||
int extra_width, extra_height;
|
||||
ulg i, j;
|
||||
WNDCLASSEX wndclass;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Allocate memory for the display-specific version of the image (round up
|
||||
to multiple of 4 for Windows DIB).
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2;
|
||||
|
||||
if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
|
||||
wimage_rowbytes*image_height)))
|
||||
{
|
||||
return 4; /* fail */
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Initialize the DIB. Negative height means to use top-down BMP ordering
|
||||
(must be uncompressed, but that's what we want). Bit count of 1, 4 or 8
|
||||
implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values
|
||||
directly => wimage_data begins immediately after BMP header.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
memset(dib, 0, sizeof(BITMAPINFOHEADER));
|
||||
bmih = (BITMAPINFOHEADER *)dib;
|
||||
bmih->biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmih->biWidth = image_width;
|
||||
bmih->biHeight = -((long)image_height);
|
||||
bmih->biPlanes = 1;
|
||||
bmih->biBitCount = 24;
|
||||
bmih->biCompression = 0;
|
||||
wimage_data = dib + sizeof(BITMAPINFOHEADER);
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Fill in background color (black by default); data are in BGR order.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
for (j = 0; j < image_height; ++j) {
|
||||
dest = wimage_data + j*wimage_rowbytes;
|
||||
for (i = image_width; i > 0; --i) {
|
||||
*dest++ = bg_blue;
|
||||
*dest++ = bg_green;
|
||||
*dest++ = bg_red;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Set the window parameters.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
memset(&wndclass, 0, sizeof(wndclass));
|
||||
|
||||
wndclass.cbSize = sizeof(wndclass);
|
||||
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wndclass.lpfnWndProc = rpng_win_wndproc;
|
||||
wndclass.hInstance = hInst;
|
||||
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
|
||||
wndclass.lpszMenuName = NULL;
|
||||
wndclass.lpszClassName = progname;
|
||||
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
|
||||
RegisterClassEx(&wndclass);
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Finally, create the window.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
extra_width = 2*(GetSystemMetrics(SM_CXBORDER) +
|
||||
GetSystemMetrics(SM_CXDLGFRAME));
|
||||
extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +
|
||||
GetSystemMetrics(SM_CYDLGFRAME)) +
|
||||
GetSystemMetrics(SM_CYCAPTION);
|
||||
|
||||
global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width,
|
||||
image_height+extra_height, NULL, NULL, hInst, NULL);
|
||||
|
||||
ShowWindow(global_hwnd, showmode);
|
||||
UpdateWindow(global_hwnd);
|
||||
|
||||
return 0;
|
||||
|
||||
} /* end function rpng_win_create_window() */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int rpng_win_display_image()
|
||||
{
|
||||
uch *src, *dest;
|
||||
uch r, g, b, a;
|
||||
ulg i, row, lastrow;
|
||||
RECT rect;
|
||||
|
||||
|
||||
Trace((stderr, "beginning display loop (image_channels == %d)\n",
|
||||
image_channels))
|
||||
Trace((stderr, "(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n",
|
||||
image_width, image_rowbytes, wimage_rowbytes))
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Blast image data to buffer. This whole routine takes place before the
|
||||
message loop begins, so there's no real point in any pseudo-progressive
|
||||
display...
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
for (lastrow = row = 0; row < image_height; ++row) {
|
||||
src = image_data + row*image_rowbytes;
|
||||
dest = wimage_data + row*wimage_rowbytes;
|
||||
if (image_channels == 3) {
|
||||
for (i = image_width; i > 0; --i) {
|
||||
r = *src++;
|
||||
g = *src++;
|
||||
b = *src++;
|
||||
*dest++ = b;
|
||||
*dest++ = g; /* note reverse order */
|
||||
*dest++ = r;
|
||||
}
|
||||
} else /* if (image_channels == 4) */ {
|
||||
for (i = image_width; i > 0; --i) {
|
||||
r = *src++;
|
||||
g = *src++;
|
||||
b = *src++;
|
||||
a = *src++;
|
||||
if (a == 255) {
|
||||
*dest++ = b;
|
||||
*dest++ = g;
|
||||
*dest++ = r;
|
||||
} else if (a == 0) {
|
||||
*dest++ = bg_blue;
|
||||
*dest++ = bg_green;
|
||||
*dest++ = bg_red;
|
||||
} else {
|
||||
/* this macro (copied from png.h) composites the
|
||||
* foreground and background values and puts the
|
||||
* result into the first argument; there are no
|
||||
* side effects with the first argument */
|
||||
alpha_composite(*dest++, b, a, bg_blue);
|
||||
alpha_composite(*dest++, g, a, bg_green);
|
||||
alpha_composite(*dest++, r, a, bg_red);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* display after every 16 lines */
|
||||
if (((row+1) & 0xf) == 0) {
|
||||
rect.left = 0L;
|
||||
rect.top = (LONG)lastrow;
|
||||
rect.right = (LONG)image_width; /* possibly off by one? */
|
||||
rect.bottom = (LONG)lastrow + 16L; /* possibly off by one? */
|
||||
InvalidateRect(global_hwnd, &rect, FALSE);
|
||||
UpdateWindow(global_hwnd); /* similar to XFlush() */
|
||||
lastrow = row + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Trace((stderr, "calling final image-flush routine\n"))
|
||||
if (lastrow < image_height) {
|
||||
rect.left = 0L;
|
||||
rect.top = (LONG)lastrow;
|
||||
rect.right = (LONG)image_width; /* possibly off by one? */
|
||||
rect.bottom = (LONG)image_height; /* possibly off by one? */
|
||||
InvalidateRect(global_hwnd, &rect, FALSE);
|
||||
UpdateWindow(global_hwnd); /* similar to XFlush() */
|
||||
}
|
||||
|
||||
/*
|
||||
last param determines whether or not background is wiped before paint
|
||||
InvalidateRect(global_hwnd, NULL, TRUE);
|
||||
UpdateWindow(global_hwnd);
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void rpng_win_cleanup()
|
||||
{
|
||||
if (image_data) {
|
||||
free(image_data);
|
||||
image_data = NULL;
|
||||
}
|
||||
|
||||
if (dib) {
|
||||
free(dib);
|
||||
dib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
|
||||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
int rc;
|
||||
|
||||
switch (iMsg) {
|
||||
case WM_CREATE:
|
||||
/* one-time processing here, if any */
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
/* dest */
|
||||
rc = StretchDIBits(hdc, 0, 0, image_width, image_height,
|
||||
/* source */
|
||||
0, 0, image_width, image_height,
|
||||
wimage_data, (BITMAPINFO *)bmih,
|
||||
/* iUsage: no clue */
|
||||
0, SRCCOPY);
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
|
||||
/* wait for the user to tell us when to quit */
|
||||
case WM_CHAR:
|
||||
switch (wP) { /* only need one, so ignore repeat count */
|
||||
case 'q':
|
||||
case 'Q':
|
||||
case 0x1B: /* Esc key */
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN: /* another way of quitting */
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, iMsg, wP, lP);
|
||||
}
|
739
contrib/gregbook/rpng-x.c
Normal file
739
contrib/gregbook/rpng-x.c
Normal file
@ -0,0 +1,739 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
rpng - simple PNG display program rpng-x.c
|
||||
|
||||
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).
|
||||
|
||||
to do:
|
||||
- 8-bit support
|
||||
- use %.1023s to simplify truncation of title-bar string?
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define PROGNAME "rpng-x"
|
||||
#define LONGNAME "Simple PNG Viewer for X"
|
||||
#define VERSION "1.01 of 31 March 1999"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
/* #define DEBUG : this enables the Trace() macros */
|
||||
|
||||
#include "readpng.h" /* typedefs, common macros, readpng prototypes */
|
||||
|
||||
|
||||
/* could just include png.h, but this macro is the only thing we need
|
||||
* (name and typedefs changed to local versions); note that side effects
|
||||
* 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); \
|
||||
}
|
||||
|
||||
|
||||
/* local prototypes */
|
||||
static int rpng_x_create_window(void);
|
||||
static int rpng_x_display_image(void);
|
||||
static void rpng_x_cleanup(void);
|
||||
static int rpng_x_msb(ulg u32val);
|
||||
|
||||
|
||||
static char titlebar[1024], *window_name = titlebar;
|
||||
static char *appname = LONGNAME;
|
||||
static char *icon_name = PROGNAME;
|
||||
static char *filename;
|
||||
static FILE *infile;
|
||||
|
||||
static char *bgstr;
|
||||
static uch bg_red=0, bg_green=0, bg_blue=0;
|
||||
|
||||
static double display_exponent;
|
||||
|
||||
static ulg image_width, image_height, image_rowbytes;
|
||||
static int image_channels;
|
||||
static uch *image_data;
|
||||
|
||||
/* X-specific variables */
|
||||
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 Window window;
|
||||
static GC gc;
|
||||
static Colormap colormap;
|
||||
|
||||
static int have_colormap = FALSE;
|
||||
static int have_window = FALSE;
|
||||
/*
|
||||
ulg numcolors=0, pixels[256];
|
||||
ush reds[256], greens[256], blues[256];
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef sgi
|
||||
char tmpline[80];
|
||||
#endif
|
||||
char *p;
|
||||
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 */
|
||||
XEvent e;
|
||||
KeySym k;
|
||||
|
||||
|
||||
displayname = (char *)NULL;
|
||||
filename = (char *)NULL;
|
||||
|
||||
|
||||
/* First set the default value for our display-system exponent, i.e.,
|
||||
* the product of the CRT exponent and the exponent corresponding to
|
||||
* the frame-buffer's lookup table (LUT), if any. This is not an
|
||||
* exhaustive list of LUT values (e.g., OpenStep has a lot of weird
|
||||
* ones), but it should cover 99% of the current possibilities. */
|
||||
|
||||
#if defined(NeXT)
|
||||
LUT_exponent = 1.0 / 2.2;
|
||||
/*
|
||||
if (some_next_function_that_returns_gamma(&next_gamma))
|
||||
LUT_exponent = 1.0 / next_gamma;
|
||||
*/
|
||||
#elif defined(sgi)
|
||||
LUT_exponent = 1.0 / 1.7;
|
||||
/* there doesn't seem to be any documented function to get the
|
||||
* "gamma" value, so we do it the hard way */
|
||||
infile = fopen("/etc/config/system.glGammaVal", "r");
|
||||
if (infile) {
|
||||
double sgi_gamma;
|
||||
|
||||
fgets(tmpline, 80, infile);
|
||||
fclose(infile);
|
||||
sgi_gamma = atof(tmpline);
|
||||
if (sgi_gamma > 0.0)
|
||||
LUT_exponent = 1.0 / sgi_gamma;
|
||||
}
|
||||
#elif defined(Macintosh)
|
||||
LUT_exponent = 1.8 / 2.61;
|
||||
/*
|
||||
if (some_mac_function_that_returns_gamma(&mac_gamma))
|
||||
LUT_exponent = mac_gamma / 2.61;
|
||||
*/
|
||||
#else
|
||||
LUT_exponent = 1.0; /* assume no LUT: most PCs */
|
||||
#endif
|
||||
|
||||
/* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
|
||||
default_display_exponent = LUT_exponent * CRT_exponent;
|
||||
|
||||
|
||||
/* If the user has set the SCREEN_GAMMA environment variable as suggested
|
||||
* (somewhat imprecisely) in the libpng documentation, use that; otherwise
|
||||
* use the default value we just calculated. Either way, the user may
|
||||
* override this via a command-line option. */
|
||||
|
||||
if ((p = getenv("SCREEN_GAMMA")) != NULL)
|
||||
display_exponent = atof(p);
|
||||
else
|
||||
display_exponent = default_display_exponent;
|
||||
|
||||
|
||||
/* Now parse the command line for options and the PNG filename. */
|
||||
|
||||
while (*++argv && !error) {
|
||||
if (!strcmp(*argv, "-display")) {
|
||||
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;
|
||||
} else {
|
||||
if (**argv != '-') {
|
||||
filename = *argv;
|
||||
if (argv[1]) /* shouldn't be any more args after filename */
|
||||
++error;
|
||||
} else
|
||||
++error; /* not expecting any other options */
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
++error;
|
||||
} else if (!(infile = fopen(filename, "rb"))) {
|
||||
fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
|
||||
++error;
|
||||
} else {
|
||||
if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
|
||||
switch (rc) {
|
||||
case 1:
|
||||
fprintf(stderr, PROGNAME
|
||||
": [%s] is not a PNG file: incorrect signature\n",
|
||||
filename);
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr, PROGNAME
|
||||
": [%s] has bad IHDR (libpng longjmp)\n",
|
||||
filename);
|
||||
break;
|
||||
case 4:
|
||||
fprintf(stderr, PROGNAME ": insufficient memory\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, PROGNAME
|
||||
": unknown readpng_init() error\n");
|
||||
break;
|
||||
}
|
||||
++error;
|
||||
} else {
|
||||
display = XOpenDisplay(displayname);
|
||||
if (!display) {
|
||||
readpng_cleanup(TRUE);
|
||||
fprintf(stderr, PROGNAME ": can't open X display [%s]\n",
|
||||
displayname? displayname : "default");
|
||||
++error;
|
||||
}
|
||||
}
|
||||
if (error)
|
||||
fclose(infile);
|
||||
}
|
||||
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* set the title-bar string, but make sure buffer doesn't overflow */
|
||||
|
||||
alen = strlen(appname);
|
||||
flen = strlen(filename);
|
||||
if (alen + flen + 3 > 1023)
|
||||
sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
|
||||
else
|
||||
sprintf(titlebar, "%s: %s", appname, filename);
|
||||
|
||||
|
||||
/* if the user didn't specify a background color on the command line,
|
||||
* check for one in the PNG file--if not, the initialized values of 0
|
||||
* (black) will be used */
|
||||
|
||||
if (have_bg) {
|
||||
unsigned r, g, b; /* this approach quiets compiler warnings */
|
||||
|
||||
sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
|
||||
bg_red = (uch)r;
|
||||
bg_green = (uch)g;
|
||||
bg_blue = (uch)b;
|
||||
} else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {
|
||||
readpng_cleanup(TRUE);
|
||||
fprintf(stderr, PROGNAME
|
||||
": libpng error while checking for background color\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
/* do the basic X initialization stuff, make the window and fill it
|
||||
* with the background color */
|
||||
|
||||
if (rpng_x_create_window())
|
||||
exit(2);
|
||||
|
||||
|
||||
/* decode the image, all at once */
|
||||
|
||||
Trace((stderr, "calling readpng_get_image()\n"))
|
||||
image_data = readpng_get_image(display_exponent, &image_channels,
|
||||
&image_rowbytes);
|
||||
Trace((stderr, "done with readpng_get_image()\n"))
|
||||
|
||||
|
||||
/* done with PNG file, so clean up to minimize memory usage (but do NOT
|
||||
* nuke image_data!) */
|
||||
|
||||
readpng_cleanup(FALSE);
|
||||
fclose(infile);
|
||||
|
||||
if (!image_data) {
|
||||
fprintf(stderr, PROGNAME ": unable to decode PNG image\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
|
||||
/* display image (composite with background if requested) */
|
||||
|
||||
Trace((stderr, "calling rpng_x_display_image()\n"))
|
||||
if (rpng_x_display_image()) {
|
||||
free(image_data);
|
||||
exit(4);
|
||||
}
|
||||
Trace((stderr, "done with rpng_x_display_image()\n"))
|
||||
|
||||
|
||||
/* wait for the user to tell us when to quit */
|
||||
|
||||
do
|
||||
XNextEvent(display, &e);
|
||||
while (!(e.type == ButtonPress && e.xbutton.button == Button1) &&
|
||||
!(e.type == KeyPress && /* v--- or 1 for shifted keys */
|
||||
((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) ));
|
||||
|
||||
|
||||
/* OK, we're done: clean up all image and X resources and go away */
|
||||
|
||||
rpng_x_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int rpng_x_create_window()
|
||||
{
|
||||
uch *xdata;
|
||||
int screen, pad;
|
||||
ulg bg_pixel = 0L;
|
||||
Window root;
|
||||
XEvent e;
|
||||
XGCValues gcvalues;
|
||||
XSetWindowAttributes attr;
|
||||
XSizeHints *size_hints;
|
||||
XTextProperty windowName, *pWindowName = &windowName;
|
||||
XTextProperty iconName, *pIconName = &iconName;
|
||||
XVisualInfo visual_info;
|
||||
XWMHints *wm_hints;
|
||||
|
||||
|
||||
bitmap_order = BitmapBitOrder(display);
|
||||
screen = DefaultScreen(display);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* GRR: add/check 8-bit support */
|
||||
if (depth == 8) {
|
||||
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;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Finally, create the window.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
attr.backing_store = Always;
|
||||
attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
|
||||
|
||||
window = XCreateWindow(display, root, 0, 0, image_width, image_height,
|
||||
0, depth, InputOutput, visual, CWBackingStore | CWEventMask, &attr);
|
||||
|
||||
if (window == None) {
|
||||
fprintf(stderr, "XCreateWindow() failed\n");
|
||||
return 2;
|
||||
} else
|
||||
have_window = TRUE;
|
||||
|
||||
if (depth == 8)
|
||||
XSetWindowColormap(display, window, colormap);
|
||||
|
||||
if (!XStringListToTextProperty(&window_name, 1, pWindowName))
|
||||
pWindowName = NULL;
|
||||
if (!XStringListToTextProperty(&icon_name, 1, pIconName))
|
||||
pIconName = NULL;
|
||||
|
||||
/* OK if either hints allocation fails; XSetWMProperties() allows NULLs */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if ((wm_hints = XAllocWMHints()) != NULL) {
|
||||
wm_hints->initial_state = NormalState;
|
||||
wm_hints->input = True;
|
||||
/* wm_hints->icon_pixmap = icon_pixmap; */
|
||||
wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ;
|
||||
}
|
||||
|
||||
XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
|
||||
size_hints, wm_hints, NULL);
|
||||
|
||||
XMapWindow(display, window);
|
||||
|
||||
gc = XCreateGC(display, window, 0, &gcvalues);
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Fill window with the specified background color.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
if (depth == 24 || depth == 32) {
|
||||
bg_pixel = ((ulg)bg_red << RPixelShift) |
|
||||
((ulg)bg_green << GPixelShift) |
|
||||
((ulg)bg_blue << BPixelShift);
|
||||
} else if (depth == 16) {
|
||||
bg_pixel = ((((ulg)bg_red << 8) >> RPixelShift) & RedMask) |
|
||||
((((ulg)bg_green << 8) >> GPixelShift) & GreenMask) |
|
||||
((((ulg)bg_blue << 8) >> BPixelShift) & BlueMask);
|
||||
} else /* depth == 8 */ {
|
||||
|
||||
/* GRR: add 8-bit support */
|
||||
|
||||
}
|
||||
|
||||
XSetForeground(display, gc, bg_pixel);
|
||||
XFillRectangle(display, window, gc, 0, 0, image_width, image_height);
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Wait for first Expose event to do any drawing, then flush.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
do
|
||||
XNextEvent(display, &e);
|
||||
while (e.type != Expose || e.xexpose.count);
|
||||
|
||||
XFlush(display);
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Allocate memory for the X- and display-specific version of the image.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
if (depth == 24 || depth == 32) {
|
||||
xdata = (uch *)malloc(4*image_width*image_height);
|
||||
pad = 32;
|
||||
} else if (depth == 16) {
|
||||
xdata = (uch *)malloc(2*image_width*image_height);
|
||||
pad = 16;
|
||||
} else /* depth == 8 */ {
|
||||
xdata = (uch *)malloc(image_width*image_height);
|
||||
pad = 8;
|
||||
}
|
||||
|
||||
if (!xdata) {
|
||||
fprintf(stderr, PROGNAME ": unable to allocate image memory\n");
|
||||
return 4;
|
||||
}
|
||||
|
||||
ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
|
||||
(char *)xdata, image_width, image_height, pad, 0);
|
||||
|
||||
if (!ximage) {
|
||||
fprintf(stderr, PROGNAME ": XCreateImage() failed\n");
|
||||
free(xdata);
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* to avoid testing the bitmap_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
|
||||
* efficient approach (the giant if-test would be better), but in the
|
||||
* interest of clarity, we take the easy way out... */
|
||||
|
||||
ximage->byte_order = MSBFirst;
|
||||
|
||||
return 0;
|
||||
|
||||
} /* end function rpng_x_create_window() */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int rpng_x_display_image()
|
||||
{
|
||||
uch *src, *dest;
|
||||
uch r, g, b, a;
|
||||
int ximage_rowbytes = ximage->bytes_per_line;
|
||||
ulg i, row, lastrow = 0;
|
||||
ulg pixel;
|
||||
|
||||
|
||||
Trace((stderr, "beginning display loop (image_channels == %d)\n",
|
||||
image_channels))
|
||||
Trace((stderr, "(width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
|
||||
image_width, image_rowbytes, ximage_rowbytes))
|
||||
|
||||
if (depth == 24 || depth == 32) {
|
||||
ulg red, green, blue;
|
||||
|
||||
for (lastrow = row = 0; row < image_height; ++row) {
|
||||
src = image_data + row*image_rowbytes;
|
||||
dest = ximage->data + row*ximage_rowbytes;
|
||||
if (image_channels == 3) {
|
||||
for (i = image_width; i > 0; --i) {
|
||||
red = *src++;
|
||||
green = *src++;
|
||||
blue = *src++;
|
||||
pixel = (red << RPixelShift) |
|
||||
(green << GPixelShift) |
|
||||
(blue << BPixelShift);
|
||||
/* 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];
|
||||
}
|
||||
} else /* if (image_channels == 4) */ {
|
||||
for (i = image_width; i > 0; --i) {
|
||||
r = *src++;
|
||||
g = *src++;
|
||||
b = *src++;
|
||||
a = *src++;
|
||||
if (a == 255) {
|
||||
red = r;
|
||||
green = g;
|
||||
blue = b;
|
||||
} else if (a == 0) {
|
||||
red = bg_red;
|
||||
green = bg_green;
|
||||
blue = bg_blue;
|
||||
} else {
|
||||
/* this macro (from png.h) composites the foreground
|
||||
* and background values and puts the result into the
|
||||
* first argument */
|
||||
alpha_composite(red, r, a, bg_red);
|
||||
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 above */
|
||||
*dest++ = ((uch *)&pixel)[3];
|
||||
*dest++ = ((uch *)&pixel)[2];
|
||||
*dest++ = ((uch *)&pixel)[1];
|
||||
*dest++ = ((uch *)&pixel)[0];
|
||||
}
|
||||
}
|
||||
/* display after every 16 lines */
|
||||
if (((row+1) & 0xf) == 0) {
|
||||
XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
|
||||
image_width, 16);
|
||||
XFlush(display);
|
||||
lastrow = row + 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (depth == 16) {
|
||||
ush red, green, blue;
|
||||
|
||||
for (lastrow = row = 0; row < image_height; ++row) {
|
||||
src = image_data + row*image_rowbytes;
|
||||
dest = ximage->data + row*ximage_rowbytes;
|
||||
if (image_channels == 3) {
|
||||
for (i = image_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);
|
||||
/* recall that we set ximage->byte_order = MSBFirst above */
|
||||
*dest++ = ((uch *)&pixel)[1];
|
||||
*dest++ = ((uch *)&pixel)[0];
|
||||
}
|
||||
} else /* if (image_channels == 4) */ {
|
||||
for (i = image_width; i > 0; --i) {
|
||||
r = *src++;
|
||||
g = *src++;
|
||||
b = *src++;
|
||||
a = *src++;
|
||||
if (a == 255) {
|
||||
red = ((ush)r << 8);
|
||||
green = ((ush)g << 8);
|
||||
blue = ((ush)b << 8);
|
||||
} else if (a == 0) {
|
||||
red = ((ush)bg_red << 8);
|
||||
green = ((ush)bg_green << 8);
|
||||
blue = ((ush)bg_blue << 8);
|
||||
} else {
|
||||
/* this macro (from png.h) composites the foreground
|
||||
* and background values and puts the result back into
|
||||
* the first argument (== fg byte here: safe) */
|
||||
alpha_composite(r, r, a, bg_red);
|
||||
alpha_composite(g, g, a, bg_green);
|
||||
alpha_composite(b, b, a, bg_blue);
|
||||
red = ((ush)r << 8);
|
||||
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 above */
|
||||
*dest++ = ((uch *)&pixel)[1];
|
||||
*dest++ = ((uch *)&pixel)[0];
|
||||
}
|
||||
}
|
||||
/* display after every 16 lines */
|
||||
if (((row+1) & 0xf) == 0) {
|
||||
XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
|
||||
image_width, 16);
|
||||
XFlush(display);
|
||||
lastrow = row + 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else /* depth == 8 */ {
|
||||
|
||||
/* GRR: add 8-bit support */
|
||||
|
||||
}
|
||||
|
||||
Trace((stderr, "calling final XPutImage()\n"))
|
||||
if (lastrow < image_height) {
|
||||
XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
|
||||
image_width, image_height-lastrow);
|
||||
XFlush(display);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void rpng_x_cleanup()
|
||||
{
|
||||
if (image_data) {
|
||||
free(image_data);
|
||||
image_data = NULL;
|
||||
}
|
||||
|
||||
if (ximage) {
|
||||
if (ximage->data) {
|
||||
free(ximage->data); /* we allocated it, so we free it */
|
||||
ximage->data = (char *)NULL; /* instead of XDestroyImage() */
|
||||
}
|
||||
XDestroyImage(ximage);
|
||||
ximage = NULL;
|
||||
}
|
||||
|
||||
XFreeGC(display, gc);
|
||||
|
||||
if (have_window)
|
||||
XDestroyWindow(display, window);
|
||||
|
||||
if (have_colormap)
|
||||
XFreeColormap(display, colormap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int rpng_x_msb(ulg u32val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 31; i >= 0; --i) {
|
||||
if (u32val & 0x80000000L)
|
||||
break;
|
||||
u32val <<= 1;
|
||||
}
|
||||
return i;
|
||||
}
|
1102
contrib/gregbook/rpng2-win.c
Normal file
1102
contrib/gregbook/rpng2-win.c
Normal file
File diff suppressed because it is too large
Load Diff
1241
contrib/gregbook/rpng2-x.c
Normal file
1241
contrib/gregbook/rpng2-x.c
Normal file
File diff suppressed because it is too large
Load Diff
804
contrib/gregbook/wpng.c
Normal file
804
contrib/gregbook/wpng.c
Normal file
@ -0,0 +1,804 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
wpng - simple PNG-writing program wpng.c
|
||||
|
||||
This program converts certain NetPBM binary files (grayscale and RGB,
|
||||
maxval = 255) to PNG. Non-interlaced PNGs are written progressively;
|
||||
interlaced PNGs are read and written in one memory-intensive blast.
|
||||
Thanks to Jean-loup Gailly for providing the necessary trick to read
|
||||
interactive text from the keyboard while stdin is redirected.
|
||||
|
||||
NOTE: includes provisional support for PNM type "8" (portable alphamap)
|
||||
images, presumed to be a 32-bit interleaved RGBA format; no pro-
|
||||
vision for possible interleaved grayscale+alpha (16-bit) format.
|
||||
THIS IS UNLIKELY TO BECOME AN OFFICIAL NETPBM ALPHA FORMAT!
|
||||
|
||||
to do:
|
||||
- delete output file if quit before calling any writepng routines
|
||||
- process backspace with -text option under DOS/Win? (currently get ^H)
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define PROGNAME "wpng"
|
||||
#define VERSION "1.01 of 31 March 1999"
|
||||
#define APPNAME "Simple PGM/PPM/PAM to PNG Converter"
|
||||
|
||||
#if defined(__MSDOS__) || defined(__OS2__)
|
||||
# define DOS_OS2_W32
|
||||
#elif defined(_WIN32) || defined(__WIN32__)
|
||||
# define DOS_OS2_W32
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.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 */
|
||||
# ifdef __EMX__
|
||||
# ifndef getch
|
||||
# define getch() _read_kbd(0, 1, 0) /* need getche() */
|
||||
# endif
|
||||
# else /* !__EMX__ */
|
||||
# ifdef __GO32__
|
||||
# include <pc.h>
|
||||
# define getch() getkey() /* GRR: need getche() */
|
||||
# else
|
||||
# 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 */
|
||||
# define FGETS fgets
|
||||
#endif
|
||||
|
||||
/* #define DEBUG : this enables the Trace() macros */
|
||||
|
||||
/* #define FORBID_LATIN1_CTRL : this requires the user to re-enter any
|
||||
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 */
|
||||
|
||||
|
||||
|
||||
/* local prototypes */
|
||||
|
||||
static int wpng_isvalid_latin1(uch *p, int len);
|
||||
static void wpng_cleanup(void);
|
||||
|
||||
#ifdef DOS_OS2_W32
|
||||
static char *dos_kbd_gets(char *buf, int len);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static mainprog_info wpng_info; /* lone global */
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifndef DOS_OS2_W32
|
||||
FILE *keybd;
|
||||
#endif
|
||||
#ifdef sgi
|
||||
FILE *tmpfile; /* or we could just use keybd, since no overlap */
|
||||
char tmpline[80];
|
||||
#endif
|
||||
char *inname = NULL, outname[256];
|
||||
char *p, pnmchar, pnmline[256];
|
||||
char *bgstr, *textbuf = NULL;
|
||||
ulg rowbytes;
|
||||
int rc, len = 0;
|
||||
int error = 0;
|
||||
int text = FALSE;
|
||||
int maxval;
|
||||
double LUT_exponent; /* just the lookup table */
|
||||
double CRT_exponent = 2.2; /* just the monitor */
|
||||
double default_display_exponent; /* whole display system */
|
||||
double default_gamma = 0.0;
|
||||
|
||||
|
||||
wpng_info.infile = NULL;
|
||||
wpng_info.outfile = NULL;
|
||||
wpng_info.image_data = NULL;
|
||||
wpng_info.row_pointers = NULL;
|
||||
wpng_info.filter = FALSE;
|
||||
wpng_info.interlaced = FALSE;
|
||||
wpng_info.have_bg = FALSE;
|
||||
wpng_info.have_time = FALSE;
|
||||
wpng_info.have_text = 0;
|
||||
wpng_info.gamma = 0.0;
|
||||
|
||||
|
||||
/* First get the default value for our display-system exponent, i.e.,
|
||||
* the product of the CRT exponent and the exponent corresponding to
|
||||
* the frame-buffer's lookup table (LUT), if any. If the PNM image
|
||||
* looks correct on the user's display system, its file gamma is the
|
||||
* inverse of this value. (Note that this is not an exhaustive list
|
||||
* of LUT values--e.g., OpenStep has a lot of weird ones--but it should
|
||||
* cover 99% of the current possibilities. This section must ensure
|
||||
* that default_display_exponent is positive.) */
|
||||
|
||||
#if defined(NeXT)
|
||||
/* third-party utilities can modify the default LUT exponent */
|
||||
LUT_exponent = 1.0 / 2.2;
|
||||
/*
|
||||
if (some_next_function_that_returns_gamma(&next_gamma))
|
||||
LUT_exponent = 1.0 / next_gamma;
|
||||
*/
|
||||
#elif defined(sgi)
|
||||
LUT_exponent = 1.0 / 1.7;
|
||||
/* there doesn't seem to be any documented function to
|
||||
* get the "gamma" value, so we do it the hard way */
|
||||
tmpfile = fopen("/etc/config/system.glGammaVal", "r");
|
||||
if (tmpfile) {
|
||||
double sgi_gamma;
|
||||
|
||||
fgets(tmpline, 80, tmpfile);
|
||||
fclose(tmpfile);
|
||||
sgi_gamma = atof(tmpline);
|
||||
if (sgi_gamma > 0.0)
|
||||
LUT_exponent = 1.0 / sgi_gamma;
|
||||
}
|
||||
#elif defined(Macintosh)
|
||||
LUT_exponent = 1.8 / 2.61;
|
||||
/*
|
||||
if (some_mac_function_that_returns_gamma(&mac_gamma))
|
||||
LUT_exponent = mac_gamma / 2.61;
|
||||
*/
|
||||
#else
|
||||
LUT_exponent = 1.0; /* assume no LUT: most PCs */
|
||||
#endif
|
||||
|
||||
/* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
|
||||
default_display_exponent = LUT_exponent * CRT_exponent;
|
||||
|
||||
|
||||
/* If the user has set the SCREEN_GAMMA environment variable as suggested
|
||||
* (somewhat imprecisely) in the libpng documentation, use that; otherwise
|
||||
* use the default value we just calculated. Either way, the user may
|
||||
* override this via a command-line option. */
|
||||
|
||||
if ((p = getenv("SCREEN_GAMMA")) != NULL) {
|
||||
double exponent = atof(p);
|
||||
|
||||
if (exponent > 0.0)
|
||||
default_gamma = 1.0 / exponent;
|
||||
}
|
||||
|
||||
if (default_gamma == 0.0)
|
||||
default_gamma = 1.0 / default_display_exponent;
|
||||
|
||||
|
||||
/* Now parse the command line for options and the PNM filename. */
|
||||
|
||||
while (*++argv && !error) {
|
||||
if (!strcmp(*argv, "-interlaced")) {
|
||||
wpng_info.interlaced = TRUE;
|
||||
} else if (!strcmp(*argv, "-time")) {
|
||||
wpng_info.modtime = time(NULL);
|
||||
wpng_info.have_time = TRUE;
|
||||
} else if (!strcmp(*argv, "-text")) {
|
||||
text = TRUE;
|
||||
} else if (!strcmp(*argv, "-gamma")) {
|
||||
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 */
|
||||
|
||||
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 != '-') {
|
||||
inname = *argv;
|
||||
if (argv[1]) /* shouldn't be any more args after filename */
|
||||
++error;
|
||||
} else
|
||||
++error; /* not expecting any other options */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* open the input and output files, or register an error and abort */
|
||||
|
||||
if (!inname) {
|
||||
if (isatty(0)) {
|
||||
fprintf(stderr, PROGNAME
|
||||
": must give input filename or provide image data via stdin\n");
|
||||
++error;
|
||||
} else {
|
||||
#ifdef DOS_OS2_W32
|
||||
/* some buggy C libraries require BOTH setmode() and fdopen(bin) */
|
||||
setmode(fileno(stdin), O_BINARY);
|
||||
setmode(fileno(stdout), O_BINARY);
|
||||
#endif
|
||||
if ((wpng_info.infile = fdopen(fileno(stdin), "rb")) == NULL) {
|
||||
fprintf(stderr, PROGNAME
|
||||
": unable to reopen stdin in binary mode\n");
|
||||
++error;
|
||||
} else
|
||||
if ((wpng_info.outfile = fdopen(fileno(stdout), "wb")) == NULL) {
|
||||
fprintf(stderr, PROGNAME
|
||||
": unable to reopen stdout in binary mode\n");
|
||||
fclose(wpng_info.infile);
|
||||
++error;
|
||||
} else
|
||||
wpng_info.filter = TRUE;
|
||||
}
|
||||
} else if ((len = strlen(inname)) > 250) {
|
||||
fprintf(stderr, PROGNAME ": input filename is too long [%d chars]\n",
|
||||
len);
|
||||
++error;
|
||||
} else if (!(wpng_info.infile = fopen(inname, "rb"))) {
|
||||
fprintf(stderr, PROGNAME ": can't open input file [%s]\n", inname);
|
||||
++error;
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
fgets(pnmline, 256, wpng_info.infile);
|
||||
if (pnmline[0] != 'P' || ((pnmchar = pnmline[1]) != '5' &&
|
||||
pnmchar != '6' && pnmchar != '8'))
|
||||
{
|
||||
fprintf(stderr, PROGNAME
|
||||
": input file [%s] is not a binary PGM, PPM or PAM file\n",
|
||||
inname);
|
||||
++error;
|
||||
} else {
|
||||
wpng_info.pnmtype = (int)(pnmchar - '0');
|
||||
if (wpng_info.pnmtype != 8)
|
||||
wpng_info.have_bg = FALSE; /* no need for bg if opaque */
|
||||
do {
|
||||
fgets(pnmline, 256, wpng_info.infile); /* lose any comments */
|
||||
} while (pnmline[0] == '#');
|
||||
sscanf(pnmline, "%ld %ld", &wpng_info.width, &wpng_info.height);
|
||||
do {
|
||||
fgets(pnmline, 256, wpng_info.infile); /* more comment lines */
|
||||
} while (pnmline[0] == '#');
|
||||
sscanf(pnmline, "%d", &maxval);
|
||||
if (wpng_info.width <= 0L || wpng_info.height <= 0L ||
|
||||
maxval != 255)
|
||||
{
|
||||
fprintf(stderr, PROGNAME
|
||||
": only positive width/height, maxval == 255 allowed \n");
|
||||
++error;
|
||||
}
|
||||
wpng_info.sample_depth = 8; /* <==> maxval 255 */
|
||||
|
||||
if (!wpng_info.filter) {
|
||||
/* make outname from inname */
|
||||
if ((p = strrchr(inname, '.')) == NULL ||
|
||||
(p - inname) != (len - 4))
|
||||
{
|
||||
strcpy(outname, inname);
|
||||
strcpy(outname+len, ".png");
|
||||
} else {
|
||||
len -= 4;
|
||||
strncpy(outname, inname, len);
|
||||
strcpy(outname+len, ".png");
|
||||
}
|
||||
/* check if outname already exists; if not, open */
|
||||
if ((wpng_info.outfile = fopen(outname, "rb")) != NULL) {
|
||||
fprintf(stderr, PROGNAME ": output file exists [%s]\n",
|
||||
outname);
|
||||
fclose(wpng_info.outfile);
|
||||
++error;
|
||||
} else if (!(wpng_info.outfile = fopen(outname, "wb"))) {
|
||||
fprintf(stderr, PROGNAME ": can't open output file [%s]\n",
|
||||
outname);
|
||||
++error;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
fclose(wpng_info.infile);
|
||||
wpng_info.infile = NULL;
|
||||
if (wpng_info.filter) {
|
||||
fclose(wpng_info.outfile);
|
||||
wpng_info.outfile = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* if we had any errors, print usage and die horrible death...arrr! */
|
||||
|
||||
if (error) {
|
||||
fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, APPNAME);
|
||||
writepng_version_info();
|
||||
fprintf(stderr, "\n"
|
||||
"Usage: %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\n"
|
||||
"or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\n"
|
||||
" exp \ttransfer-function exponent (``gamma'') of the image in\n"
|
||||
"\t\t floating-point format (e.g., ``%.5f''); if image looks\n"
|
||||
"\t\t correct on given display system, image gamma is equal to\n"
|
||||
"\t\t inverse of display-system exponent, i.e., 1 / (LUT * CRT)\n"
|
||||
"\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 same as HTML colors)\n"
|
||||
" -text\tprompt interactively for text info (tEXt chunks)\n"
|
||||
" -time\tinclude a tIME chunk (last modification time)\n"
|
||||
" -interlace\twrite interlaced PNG image\n"
|
||||
"\n"
|
||||
"pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\n"
|
||||
"unofficial and unsupported!) PAM (`P8') file. Currently it is required\n"
|
||||
"to have maxval == 255 (i.e., no scaling). If pnmfile is specified, it\n"
|
||||
"is converted to the corresponding PNG file with the same base name but a\n"
|
||||
"``.png'' extension; files read from stdin are converted and sent to stdout.\n"
|
||||
"The conversion is progressive (low memory usage) unless interlacing is\n"
|
||||
"requested; in that case the whole image will be buffered in memory and\n"
|
||||
"written in one call.\n"
|
||||
"\n", PROGNAME, PROGNAME, default_gamma);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* prepare the text buffers for libpng's use; note that even though
|
||||
* PNG's png_text struct includes a length field, we don't have to fill
|
||||
* it out */
|
||||
|
||||
if (text &&
|
||||
#ifndef DOS_OS2_W32
|
||||
(keybd = fdopen(fileno(stderr), "r")) != NULL &&
|
||||
#endif
|
||||
(textbuf = (char *)malloc((5 + 9)*75)) != NULL)
|
||||
{
|
||||
int i, valid, result;
|
||||
|
||||
fprintf(stderr,
|
||||
"Enter text info (no more than 72 characters per line);\n");
|
||||
fprintf(stderr, "to skip a field, hit the <Enter> key.\n");
|
||||
/* note: just <Enter> leaves len == 1 */
|
||||
|
||||
do {
|
||||
valid = TRUE;
|
||||
p = textbuf + TEXT_TITLE_OFFSET;
|
||||
fprintf(stderr, " Title: ");
|
||||
fflush(stderr);
|
||||
if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
|
||||
if (p[len-1] == '\n')
|
||||
p[--len] = '\0';
|
||||
wpng_info.title = p;
|
||||
wpng_info.have_text |= TEXT_TITLE;
|
||||
if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
|
||||
fprintf(stderr, " " PROGNAME " warning: character code"
|
||||
" %u is %sdiscouraged by the PNG\n specification "
|
||||
"[first occurrence was at character position #%d]\n",
|
||||
(unsigned)p[result], (p[result] == 27)? "strongly " : "",
|
||||
result+1);
|
||||
fflush(stderr);
|
||||
#ifdef FORBID_LATIN1_CTRL
|
||||
wpng_info.have_text &= ~TEXT_TITLE;
|
||||
valid = FALSE;
|
||||
#else
|
||||
if (p[result] == 27) { /* escape character */
|
||||
wpng_info.have_text &= ~TEXT_TITLE;
|
||||
valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} while (!valid);
|
||||
|
||||
do {
|
||||
valid = TRUE;
|
||||
p = textbuf + TEXT_AUTHOR_OFFSET;
|
||||
fprintf(stderr, " Author: ");
|
||||
fflush(stderr);
|
||||
if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
|
||||
if (p[len-1] == '\n')
|
||||
p[--len] = '\0';
|
||||
wpng_info.author = p;
|
||||
wpng_info.have_text |= TEXT_AUTHOR;
|
||||
if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
|
||||
fprintf(stderr, " " PROGNAME " warning: character code"
|
||||
" %u is %sdiscouraged by the PNG\n specification "
|
||||
"[first occurrence was at character position #%d]\n",
|
||||
(unsigned)p[result], (p[result] == 27)? "strongly " : "",
|
||||
result+1);
|
||||
fflush(stderr);
|
||||
#ifdef FORBID_LATIN1_CTRL
|
||||
wpng_info.have_text &= ~TEXT_AUTHOR;
|
||||
valid = FALSE;
|
||||
#else
|
||||
if (p[result] == 27) { /* escape character */
|
||||
wpng_info.have_text &= ~TEXT_AUTHOR;
|
||||
valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} while (!valid);
|
||||
|
||||
do {
|
||||
valid = TRUE;
|
||||
p = textbuf + TEXT_DESC_OFFSET;
|
||||
fprintf(stderr, " Description (up to 9 lines):\n");
|
||||
for (i = 1; i < 10; ++i) {
|
||||
fprintf(stderr, " [%d] ", i);
|
||||
fflush(stderr);
|
||||
if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1)
|
||||
p += len; /* now points at NULL; char before is newline */
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) {
|
||||
if (p[-1] == '\n') {
|
||||
p[-1] = '\0';
|
||||
--len;
|
||||
}
|
||||
wpng_info.desc = textbuf + TEXT_DESC_OFFSET;
|
||||
wpng_info.have_text |= TEXT_DESC;
|
||||
p = textbuf + TEXT_DESC_OFFSET;
|
||||
if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
|
||||
fprintf(stderr, " " PROGNAME " warning: character code"
|
||||
" %u is %sdiscouraged by the PNG\n specification "
|
||||
"[first occurrence was at character position #%d]\n",
|
||||
(unsigned)p[result], (p[result] == 27)? "strongly " : "",
|
||||
result+1);
|
||||
fflush(stderr);
|
||||
#ifdef FORBID_LATIN1_CTRL
|
||||
wpng_info.have_text &= ~TEXT_DESC;
|
||||
valid = FALSE;
|
||||
#else
|
||||
if (p[result] == 27) { /* escape character */
|
||||
wpng_info.have_text &= ~TEXT_DESC;
|
||||
valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} while (!valid);
|
||||
|
||||
do {
|
||||
valid = TRUE;
|
||||
p = textbuf + TEXT_COPY_OFFSET;
|
||||
fprintf(stderr, " Copyright: ");
|
||||
fflush(stderr);
|
||||
if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
|
||||
if (p[len-1] == '\n')
|
||||
p[--len] = '\0';
|
||||
wpng_info.copyright = p;
|
||||
wpng_info.have_text |= TEXT_COPY;
|
||||
if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
|
||||
fprintf(stderr, " " PROGNAME " warning: character code"
|
||||
" %u is %sdiscouraged by the PNG\n specification "
|
||||
"[first occurrence was at character position #%d]\n",
|
||||
(unsigned)p[result], (p[result] == 27)? "strongly " : "",
|
||||
result+1);
|
||||
fflush(stderr);
|
||||
#ifdef FORBID_LATIN1_CTRL
|
||||
wpng_info.have_text &= ~TEXT_COPY;
|
||||
valid = FALSE;
|
||||
#else
|
||||
if (p[result] == 27) { /* escape character */
|
||||
wpng_info.have_text &= ~TEXT_COPY;
|
||||
valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} while (!valid);
|
||||
|
||||
do {
|
||||
valid = TRUE;
|
||||
p = textbuf + TEXT_EMAIL_OFFSET;
|
||||
fprintf(stderr, " E-mail: ");
|
||||
fflush(stderr);
|
||||
if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
|
||||
if (p[len-1] == '\n')
|
||||
p[--len] = '\0';
|
||||
wpng_info.email = p;
|
||||
wpng_info.have_text |= TEXT_EMAIL;
|
||||
if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
|
||||
fprintf(stderr, " " PROGNAME " warning: character code"
|
||||
" %u is %sdiscouraged by the PNG\n specification "
|
||||
"[first occurrence was at character position #%d]\n",
|
||||
(unsigned)p[result], (p[result] == 27)? "strongly " : "",
|
||||
result+1);
|
||||
fflush(stderr);
|
||||
#ifdef FORBID_LATIN1_CTRL
|
||||
wpng_info.have_text &= ~TEXT_EMAIL;
|
||||
valid = FALSE;
|
||||
#else
|
||||
if (p[result] == 27) { /* escape character */
|
||||
wpng_info.have_text &= ~TEXT_EMAIL;
|
||||
valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} while (!valid);
|
||||
|
||||
do {
|
||||
valid = TRUE;
|
||||
p = textbuf + TEXT_URL_OFFSET;
|
||||
fprintf(stderr, " URL: ");
|
||||
fflush(stderr);
|
||||
if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
|
||||
if (p[len-1] == '\n')
|
||||
p[--len] = '\0';
|
||||
wpng_info.url = p;
|
||||
wpng_info.have_text |= TEXT_URL;
|
||||
if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
|
||||
fprintf(stderr, " " PROGNAME " warning: character code"
|
||||
" %u is %sdiscouraged by the PNG\n specification "
|
||||
"[first occurrence was at character position #%d]\n",
|
||||
(unsigned)p[result], (p[result] == 27)? "strongly " : "",
|
||||
result+1);
|
||||
fflush(stderr);
|
||||
#ifdef FORBID_LATIN1_CTRL
|
||||
wpng_info.have_text &= ~TEXT_URL;
|
||||
valid = FALSE;
|
||||
#else
|
||||
if (p[result] == 27) { /* escape character */
|
||||
wpng_info.have_text &= ~TEXT_URL;
|
||||
valid = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} while (!valid);
|
||||
|
||||
#ifndef DOS_OS2_W32
|
||||
fclose(keybd);
|
||||
#endif
|
||||
|
||||
} else if (text) {
|
||||
fprintf(stderr, PROGNAME ": unable to allocate memory for text\n");
|
||||
text = FALSE;
|
||||
wpng_info.have_text = 0;
|
||||
}
|
||||
|
||||
|
||||
/* allocate libpng stuff, initialize transformations, write pre-IDAT data */
|
||||
|
||||
if ((rc = writepng_init(&wpng_info)) != 0) {
|
||||
switch (rc) {
|
||||
case 2:
|
||||
fprintf(stderr, PROGNAME
|
||||
": libpng initialization problem (longjmp)\n");
|
||||
break;
|
||||
case 4:
|
||||
fprintf(stderr, PROGNAME ": insufficient memory\n");
|
||||
break;
|
||||
case 11:
|
||||
fprintf(stderr, PROGNAME
|
||||
": internal logic error (unexpected PNM type)\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, PROGNAME
|
||||
": unknown writepng_init() error\n");
|
||||
break;
|
||||
}
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
|
||||
/* free textbuf, since it's a completely local variable and all text info
|
||||
* has just been written to the PNG file */
|
||||
|
||||
if (text && textbuf) {
|
||||
free(textbuf);
|
||||
textbuf = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* calculate rowbytes on basis of image type; note that this becomes much
|
||||
* more complicated if we choose to support PBM type, ASCII PNM types, or
|
||||
* 16-bit-per-sample binary data [currently not an official NetPBM type] */
|
||||
|
||||
if (wpng_info.pnmtype == 5)
|
||||
rowbytes = wpng_info.width;
|
||||
else if (wpng_info.pnmtype == 6)
|
||||
rowbytes = wpng_info.width * 3;
|
||||
else /* if (wpng_info.pnmtype == 8) */
|
||||
rowbytes = wpng_info.width * 4;
|
||||
|
||||
|
||||
/* read and write the image, either in its entirety (if writing interlaced
|
||||
* PNG) or row by row (if non-interlaced) */
|
||||
|
||||
fprintf(stderr, "Encoding image data...\n");
|
||||
fflush(stderr);
|
||||
|
||||
if (wpng_info.interlaced) {
|
||||
long i;
|
||||
ulg bytes;
|
||||
ulg image_bytes = rowbytes * wpng_info.height; /* overflow? */
|
||||
|
||||
wpng_info.image_data = (uch *)malloc(image_bytes);
|
||||
wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));
|
||||
if (wpng_info.image_data == NULL || wpng_info.row_pointers == NULL) {
|
||||
fprintf(stderr, PROGNAME ": insufficient memory for image data\n");
|
||||
writepng_cleanup(&wpng_info);
|
||||
wpng_cleanup();
|
||||
exit(5);
|
||||
}
|
||||
for (i = 0; i < wpng_info.height; ++i)
|
||||
wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes;
|
||||
bytes = fread(wpng_info.image_data, 1, image_bytes, wpng_info.infile);
|
||||
if (bytes != image_bytes) {
|
||||
fprintf(stderr, PROGNAME ": expected %lu bytes, got %lu bytes\n",
|
||||
image_bytes, bytes);
|
||||
fprintf(stderr, " (continuing anyway)\n");
|
||||
}
|
||||
if (writepng_encode_image(&wpng_info) != 0) {
|
||||
fprintf(stderr, PROGNAME
|
||||
": libpng problem (longjmp) while writing image data\n");
|
||||
writepng_cleanup(&wpng_info);
|
||||
wpng_cleanup();
|
||||
exit(2);
|
||||
}
|
||||
|
||||
} else /* not interlaced: write progressively (row by row) */ {
|
||||
long j;
|
||||
ulg bytes;
|
||||
|
||||
wpng_info.image_data = (uch *)malloc(rowbytes);
|
||||
if (wpng_info.image_data == NULL) {
|
||||
fprintf(stderr, PROGNAME ": insufficient memory for row data\n");
|
||||
writepng_cleanup(&wpng_info);
|
||||
wpng_cleanup();
|
||||
exit(5);
|
||||
}
|
||||
error = 0;
|
||||
for (j = wpng_info.height; j > 0L; --j) {
|
||||
bytes = fread(wpng_info.image_data, 1, rowbytes, wpng_info.infile);
|
||||
if (bytes != rowbytes) {
|
||||
fprintf(stderr, PROGNAME
|
||||
": expected %lu bytes, got %lu bytes (row %ld)\n", rowbytes,
|
||||
bytes, wpng_info.height-j);
|
||||
++error;
|
||||
break;
|
||||
}
|
||||
if (writepng_encode_row(&wpng_info) != 0) {
|
||||
fprintf(stderr, PROGNAME
|
||||
": libpng problem (longjmp) while writing row %ld\n",
|
||||
wpng_info.height-j);
|
||||
++error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
writepng_cleanup(&wpng_info);
|
||||
wpng_cleanup();
|
||||
exit(2);
|
||||
}
|
||||
if (writepng_encode_finish(&wpng_info) != 0) {
|
||||
fprintf(stderr, PROGNAME ": error on final libpng call\n");
|
||||
writepng_cleanup(&wpng_info);
|
||||
wpng_cleanup();
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* OK, we're done (successfully): clean up all resources and quit */
|
||||
|
||||
fprintf(stderr, "Done.\n");
|
||||
fflush(stderr);
|
||||
|
||||
writepng_cleanup(&wpng_info);
|
||||
wpng_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int wpng_isvalid_latin1(uch *p, int len)
|
||||
{
|
||||
int i, result = -1;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (p[i] == 10 || (p[i] > 31 && p[i] < 127) || p[i] > 160)
|
||||
continue; /* character is completely OK */
|
||||
if (result < 0 || (p[result] != 27 && p[i] == 27))
|
||||
result = i; /* mark location of first questionable one */
|
||||
} /* or of first escape character (bad) */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void wpng_cleanup()
|
||||
{
|
||||
if (wpng_info.outfile) {
|
||||
fclose(wpng_info.outfile);
|
||||
wpng_info.outfile = NULL;
|
||||
}
|
||||
|
||||
if (wpng_info.infile) {
|
||||
fclose(wpng_info.infile);
|
||||
wpng_info.infile = NULL;
|
||||
}
|
||||
|
||||
if (wpng_info.image_data) {
|
||||
free(wpng_info.image_data);
|
||||
wpng_info.image_data = NULL;
|
||||
}
|
||||
|
||||
if (wpng_info.row_pointers) {
|
||||
free(wpng_info.row_pointers);
|
||||
wpng_info.row_pointers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef DOS_OS2_W32
|
||||
|
||||
static char *dos_kbd_gets(char *buf, int len)
|
||||
{
|
||||
int ch, count=0;
|
||||
|
||||
do {
|
||||
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] = '\n';
|
||||
|
||||
fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */
|
||||
fflush(stderr);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif /* DOS_OS2_W32 */
|
368
contrib/gregbook/writepng.c
Normal file
368
contrib/gregbook/writepng.c
Normal file
@ -0,0 +1,368 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
wpng - simple PNG-writing program writepng.c
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
/* local prototype */
|
||||
|
||||
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
|
||||
|
||||
|
||||
|
||||
void writepng_version_info()
|
||||
{
|
||||
fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
|
||||
PNG_LIBPNG_VER_STRING, png_libpng_ver);
|
||||
fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
|
||||
ZLIB_VERSION, zlib_version);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for
|
||||
* unexpected pnmtype; note that outfile might be stdout */
|
||||
|
||||
int writepng_init(mainprog_info *mainprog_ptr)
|
||||
{
|
||||
png_structp png_ptr; /* note: temporary variables! */
|
||||
png_infop info_ptr;
|
||||
int color_type, interlace_type;
|
||||
|
||||
|
||||
/* could also replace libpng warning-handler (final NULL), but no need: */
|
||||
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
|
||||
writepng_error_handler, NULL);
|
||||
if (!png_ptr)
|
||||
return 4; /* out of memory */
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
return 4; /* out of memory */
|
||||
}
|
||||
|
||||
|
||||
/* setjmp() must be called in every function that calls a PNG-writing
|
||||
* libpng function, unless an alternate error handler was installed--
|
||||
* but compatible error handlers must either use longjmp() themselves
|
||||
* (as in this program) or exit immediately, so here we go: */
|
||||
|
||||
if (setjmp(mainprog_ptr->jmpbuf)) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* make sure outfile is (re)opened in BINARY mode */
|
||||
|
||||
png_init_io(png_ptr, mainprog_ptr->outfile);
|
||||
|
||||
|
||||
/* set the compression levels--in general, always want to leave filtering
|
||||
* turned on (except for palette images) and allow all of the filters,
|
||||
* which is the default; want 32K zlib window, unless entire image buffer
|
||||
* is 16K or smaller (unknown here)--also the default; usually want max
|
||||
* compression (NOT the default); and remaining compression flags should
|
||||
* be left alone */
|
||||
|
||||
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
|
||||
/*
|
||||
>> this is default for no filtering; Z_FILTERED is default otherwise:
|
||||
png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
|
||||
>> these are all defaults:
|
||||
png_set_compression_mem_level(png_ptr, 8);
|
||||
png_set_compression_window_bits(png_ptr, 15);
|
||||
png_set_compression_method(png_ptr, 8);
|
||||
*/
|
||||
|
||||
|
||||
/* set the image parameters appropriately */
|
||||
|
||||
if (mainprog_ptr->pnmtype == 5)
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
else if (mainprog_ptr->pnmtype == 6)
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
else if (mainprog_ptr->pnmtype == 8)
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
else {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return 11;
|
||||
}
|
||||
|
||||
interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 :
|
||||
PNG_INTERLACE_NONE;
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,
|
||||
mainprog_ptr->sample_depth, color_type, interlace_type,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
if (mainprog_ptr->gamma > 0.0)
|
||||
png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma);
|
||||
|
||||
if (mainprog_ptr->have_bg) { /* we know it's RGBA, not gray+alpha */
|
||||
png_color_16 background;
|
||||
|
||||
background.red = mainprog_ptr->bg_red;
|
||||
background.green = mainprog_ptr->bg_green;
|
||||
background.blue = mainprog_ptr->bg_blue;
|
||||
png_set_bKGD(png_ptr, info_ptr, &background);
|
||||
}
|
||||
|
||||
if (mainprog_ptr->have_time) {
|
||||
png_time modtime;
|
||||
|
||||
png_convert_from_time_t(&modtime, mainprog_ptr->modtime);
|
||||
png_set_tIME(png_ptr, info_ptr, &modtime);
|
||||
}
|
||||
|
||||
if (mainprog_ptr->have_text) {
|
||||
png_text text[6];
|
||||
int num_text = 0;
|
||||
|
||||
if (mainprog_ptr->have_text & TEXT_TITLE) {
|
||||
text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[num_text].key = "Title";
|
||||
text[num_text].text = mainprog_ptr->title;
|
||||
++num_text;
|
||||
}
|
||||
if (mainprog_ptr->have_text & TEXT_AUTHOR) {
|
||||
text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[num_text].key = "Author";
|
||||
text[num_text].text = mainprog_ptr->author;
|
||||
++num_text;
|
||||
}
|
||||
if (mainprog_ptr->have_text & TEXT_DESC) {
|
||||
text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[num_text].key = "Description";
|
||||
text[num_text].text = mainprog_ptr->desc;
|
||||
++num_text;
|
||||
}
|
||||
if (mainprog_ptr->have_text & TEXT_COPY) {
|
||||
text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[num_text].key = "Copyright";
|
||||
text[num_text].text = mainprog_ptr->copyright;
|
||||
++num_text;
|
||||
}
|
||||
if (mainprog_ptr->have_text & TEXT_EMAIL) {
|
||||
text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[num_text].key = "E-mail";
|
||||
text[num_text].text = mainprog_ptr->email;
|
||||
++num_text;
|
||||
}
|
||||
if (mainprog_ptr->have_text & TEXT_URL) {
|
||||
text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[num_text].key = "URL";
|
||||
text[num_text].text = mainprog_ptr->url;
|
||||
++num_text;
|
||||
}
|
||||
png_set_text(png_ptr, info_ptr, text, num_text);
|
||||
}
|
||||
|
||||
|
||||
/* write all chunks up to (but not including) first IDAT */
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
|
||||
/* if we wanted to write any more text info *after* the image data, we
|
||||
* would set up text struct(s) here and call png_set_text() again, with
|
||||
* just the new data; png_set_tIME() could also go here, but it would
|
||||
* have no effect since we already called it above (only one tIME chunk
|
||||
* allowed) */
|
||||
|
||||
|
||||
/* set up the transformations: for now, just pack low-bit-depth pixels
|
||||
* into bytes (one, two or four pixels per byte) */
|
||||
|
||||
png_set_packing(png_ptr);
|
||||
/* png_set_shift(png_ptr, &sig_bit); to scale low-bit-depth values */
|
||||
|
||||
|
||||
/* make sure we save our pointers for use in writepng_encode_image() */
|
||||
|
||||
mainprog_ptr->png_ptr = png_ptr;
|
||||
mainprog_ptr->info_ptr = info_ptr;
|
||||
|
||||
|
||||
/* OK, that's all we need to do for now; return happy */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns 0 for success, 2 for libpng (longjmp) problem */
|
||||
|
||||
int writepng_encode_image(mainprog_info *mainprog_ptr)
|
||||
{
|
||||
png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
|
||||
png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
|
||||
|
||||
|
||||
/* as always, setjmp() must be called in every function that calls a
|
||||
* PNG-writing libpng function */
|
||||
|
||||
if (setjmp(mainprog_ptr->jmpbuf)) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
mainprog_ptr->png_ptr = NULL;
|
||||
mainprog_ptr->info_ptr = NULL;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* and now we just write the whole image; libpng takes care of interlacing
|
||||
* for us */
|
||||
|
||||
png_write_image(png_ptr, mainprog_ptr->row_pointers);
|
||||
|
||||
|
||||
/* since that's it, we also close out the end of the PNG file now--if we
|
||||
* had any text or time info to write after the IDATs, second argument
|
||||
* would be info_ptr, but we optimize slightly by sending NULL pointer: */
|
||||
|
||||
png_write_end(png_ptr, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns 0 if succeeds, 2 if libpng problem */
|
||||
|
||||
int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */
|
||||
{
|
||||
png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
|
||||
png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
|
||||
|
||||
|
||||
/* as always, setjmp() must be called in every function that calls a
|
||||
* PNG-writing libpng function */
|
||||
|
||||
if (setjmp(mainprog_ptr->jmpbuf)) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
mainprog_ptr->png_ptr = NULL;
|
||||
mainprog_ptr->info_ptr = NULL;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* image_data points at our one row of image data */
|
||||
|
||||
png_write_row(png_ptr, mainprog_ptr->image_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns 0 if succeeds, 2 if libpng problem */
|
||||
|
||||
int writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */
|
||||
{
|
||||
png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
|
||||
png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
|
||||
|
||||
|
||||
/* as always, setjmp() must be called in every function that calls a
|
||||
* PNG-writing libpng function */
|
||||
|
||||
if (setjmp(mainprog_ptr->jmpbuf)) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
mainprog_ptr->png_ptr = NULL;
|
||||
mainprog_ptr->info_ptr = NULL;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/* close out PNG file; if we had any text or time info to write after
|
||||
* the IDATs, second argument would be info_ptr: */
|
||||
|
||||
png_write_end(png_ptr, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void writepng_cleanup(mainprog_info *mainprog_ptr)
|
||||
{
|
||||
png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
|
||||
png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
|
||||
|
||||
if (png_ptr && info_ptr)
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
|
||||
{
|
||||
mainprog_info *mainprog_ptr;
|
||||
|
||||
/* This function, aside from the extra step of retrieving the "error
|
||||
* pointer" (below) and the fact that it exists within the application
|
||||
* rather than within libpng, is essentially identical to libpng's
|
||||
* default error handler. The second point is critical: since both
|
||||
* setjmp() and longjmp() are called from the same code, they are
|
||||
* guaranteed to have compatible notions of how big a jmp_buf is,
|
||||
* regardless of whether _BSD_SOURCE or anything else has (or has not)
|
||||
* been defined. */
|
||||
|
||||
fprintf(stderr, "writepng libpng error: %s\n", msg);
|
||||
fflush(stderr);
|
||||
|
||||
mainprog_ptr = png_get_error_ptr(png_ptr);
|
||||
if (mainprog_ptr == NULL) { /* we are completely hosed now */
|
||||
fprintf(stderr,
|
||||
"writepng severe error: jmpbuf not recoverable; terminating.\n");
|
||||
fflush(stderr);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
longjmp(mainprog_ptr->jmpbuf, 1);
|
||||
}
|
109
contrib/gregbook/writepng.h
Normal file
109
contrib/gregbook/writepng.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
wpng - simple PNG-writing program writepng.h
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
|
||||
|
||||
This software is provided "as is," without warranty of any kind,
|
||||
express or implied. In no event shall the author or contributors
|
||||
be held liable for any damages arising in any way from the use of
|
||||
this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, disclaimer, and this list of conditions.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, disclaimer, and this list of conditions in the 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) ((a) > (b)? (a) : (b))
|
||||
# define MIN(a,b) ((a) < (b)? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
|
||||
#else
|
||||
# define Trace(x) ;
|
||||
#endif
|
||||
|
||||
#define TEXT_TITLE 0x01
|
||||
#define TEXT_AUTHOR 0x02
|
||||
#define TEXT_DESC 0x04
|
||||
#define TEXT_COPY 0x08
|
||||
#define TEXT_EMAIL 0x10
|
||||
#define TEXT_URL 0x20
|
||||
|
||||
#define TEXT_TITLE_OFFSET 0
|
||||
#define TEXT_AUTHOR_OFFSET 72
|
||||
#define TEXT_COPY_OFFSET (2*72)
|
||||
#define TEXT_EMAIL_OFFSET (3*72)
|
||||
#define TEXT_URL_OFFSET (4*72)
|
||||
#define TEXT_DESC_OFFSET (5*72)
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
typedef struct _mainprog_info {
|
||||
double gamma;
|
||||
long width;
|
||||
long height;
|
||||
time_t modtime;
|
||||
FILE *infile;
|
||||
FILE *outfile;
|
||||
void *png_ptr;
|
||||
void *info_ptr;
|
||||
uch *image_data;
|
||||
uch **row_pointers;
|
||||
char *title;
|
||||
char *author;
|
||||
char *desc;
|
||||
char *copyright;
|
||||
char *email;
|
||||
char *url;
|
||||
int filter; /* command-line-filter flag, not PNG row filter! */
|
||||
int pnmtype;
|
||||
int sample_depth;
|
||||
int interlaced;
|
||||
int have_bg;
|
||||
int have_time;
|
||||
int have_text;
|
||||
jmp_buf jmpbuf;
|
||||
uch bg_red;
|
||||
uch bg_green;
|
||||
uch bg_blue;
|
||||
} mainprog_info;
|
||||
|
||||
|
||||
/* prototypes for public functions in writepng.c */
|
||||
|
||||
void writepng_version_info(void);
|
||||
|
||||
int writepng_init(mainprog_info *mainprog_ptr);
|
||||
|
||||
int writepng_encode_image(mainprog_info *mainprog_ptr);
|
||||
|
||||
int writepng_encode_row(mainprog_info *mainprog_ptr);
|
||||
|
||||
int writepng_encode_finish(mainprog_info *mainprog_ptr);
|
||||
|
||||
void writepng_cleanup(mainprog_info *mainprog_ptr);
|
@ -1,4 +1,6 @@
|
||||
|
||||
#if 0 /* in case someone actually tries to compile this */
|
||||
|
||||
/* example.c - an example of using libpng */
|
||||
|
||||
/* This is an example of how to use libpng to read and write PNG files.
|
||||
@ -701,3 +703,4 @@ void write_png(char *file_name /* , ... other image information ... */)
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* if 0 */
|
||||
|
12
libpng.3
12
libpng.3
@ -1,6 +1,6 @@
|
||||
.TH LIBPNG 3 "October 5, 1999"
|
||||
.TH LIBPNG 3 "October 15, 1999"
|
||||
.SH NAME
|
||||
libpng \- Portable Network Graphics (PNG) Reference Library 1.0.5 - October 5, 1999
|
||||
libpng \- Portable Network Graphics (PNG) Reference Library 1.0.5 - October 15, 1999
|
||||
.SH SYNOPSIS
|
||||
\fI\fB
|
||||
|
||||
@ -617,7 +617,7 @@ Following is a copy of the libpng.txt file that accompanies libpng.
|
||||
.SH LIBPNG.TXT
|
||||
libpng.txt - A description on how to use and modify libpng
|
||||
|
||||
libpng version 1.0.5 - October 5, 1999
|
||||
libpng version 1.0.5 - October 15, 1999
|
||||
Updated and distributed by Glenn Randers-Pehrson
|
||||
<randeg@alum.rpi.edu>
|
||||
Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
@ -2675,7 +2675,7 @@ the old method.
|
||||
|
||||
.SH VII. Y2K Compliance in libpng
|
||||
|
||||
October 5, 1999
|
||||
October 15, 1999
|
||||
|
||||
Since the PNG Development group is an ad-hoc body, we can't make
|
||||
an official declaration.
|
||||
@ -2807,7 +2807,7 @@ possible without all of you.
|
||||
|
||||
Thanks to Frank J. T. Wojcik for helping with the documentation.
|
||||
|
||||
Libpng version 1.0.5 - October 5, 1999:
|
||||
Libpng version 1.0.5 - October 15, 1999:
|
||||
Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
|
||||
Currently maintained by Glenn Randers-Pehrson (randeg@alum.rpi.edu).
|
||||
|
||||
@ -2822,7 +2822,7 @@ Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
Copyright (c) 1996, 1997 Andreas Dilger
|
||||
(libpng versions 0.90, December 1996, through 0.96, May 1997)
|
||||
Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
(libpng versions 0.97, January 1998, through 1.0.5, October 5, 1999)
|
||||
(libpng versions 0.97, January 1998, through 1.0.5, October 15, 1999)
|
||||
|
||||
For the purposes of this copyright and license, "Contributing Authors"
|
||||
is defined as the following set of individuals:
|
||||
|
@ -1,6 +1,6 @@
|
||||
libpng.txt - A description on how to use and modify libpng
|
||||
|
||||
libpng version 1.0.5 - October 5, 1999
|
||||
libpng version 1.0.5 - October 15, 1999
|
||||
Updated and distributed by Glenn Randers-Pehrson
|
||||
<randeg@alum.rpi.edu>
|
||||
Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
@ -2058,7 +2058,7 @@ the old method.
|
||||
|
||||
VII. Y2K Compliance in libpng
|
||||
|
||||
October 5, 1999
|
||||
October 15, 1999
|
||||
|
||||
Since the PNG Development group is an ad-hoc body, we can't make
|
||||
an official declaration.
|
||||
|
@ -1,6 +1,6 @@
|
||||
.TH LIBPNGPF 3 October 5, 1999
|
||||
.TH LIBPNGPF 3 October 15, 1999
|
||||
.SH NAME
|
||||
libpng \- Portable Network Graphics (PNG) Reference Library 1.0.5 - October 5, 1999
|
||||
libpng \- Portable Network Graphics (PNG) Reference Library 1.0.5 - October 15, 1999
|
||||
(private functions)
|
||||
.SH SYNOPSIS
|
||||
\fB#include <png.h>\fP
|
||||
|
2
png.5
2
png.5
@ -1,4 +1,4 @@
|
||||
.TH PNG 5 "October 5, 1999"
|
||||
.TH PNG 5 "October 15, 1999"
|
||||
.SH NAME
|
||||
png \- Portable Network Graphics (PNG) format
|
||||
.SH DESCRIPTION
|
||||
|
14
png.c
14
png.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* png.c - location for general purpose libpng functions
|
||||
*
|
||||
* libpng version 1.0.5 - October 5, 1999
|
||||
* libpng version 1.0.5 - October 15, 1999
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
* Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
@ -12,6 +12,8 @@
|
||||
#define PNG_NO_EXTERN
|
||||
#include "png.h"
|
||||
|
||||
PNG_GET_HEADER
|
||||
|
||||
/* Version information for C files. This had better match the version
|
||||
* string defined in png.h.
|
||||
*/
|
||||
@ -86,7 +88,7 @@ png_set_sig_bytes(png_structp png_ptr, int num_bytes)
|
||||
if (num_bytes > 8)
|
||||
png_error(png_ptr, "Too many bytes for PNG signature.");
|
||||
|
||||
png_ptr->sig_bytes = num_bytes < 0 ? 0 : num_bytes;
|
||||
png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
|
||||
}
|
||||
|
||||
/* Checks whether the supplied bytes match the PNG signature. We allow
|
||||
@ -350,12 +352,12 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
|
||||
png_charp
|
||||
png_get_copyright(png_structp png_ptr)
|
||||
{
|
||||
if(png_ptr == NULL)
|
||||
/* silence compiler warning about unused png_ptr */ ;
|
||||
return("\n libpng version 1.0.5 - October 5, 1999\n\
|
||||
if (png_ptr != NULL || png_ptr == NULL) /* silence compiler warning */
|
||||
return ("\n libpng version 1.0.5 - October 15, 1999\n\
|
||||
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n\
|
||||
Copyright (c) 1996, 1997 Andreas Dilger\n\
|
||||
Copyright (c) 1998, 1999 Glenn Randers-Pehrson\n");
|
||||
return ("");
|
||||
}
|
||||
|
||||
/* Generate a compiler error if there is an old png.h in the search path. */
|
||||
@ -364,5 +366,5 @@ png_check_version
|
||||
(version_1_0_5 png_h_is_not_version_1_0_5)
|
||||
{
|
||||
if(png_h_is_not_version_1_0_5 == NULL)
|
||||
/* silence compiler warning about unused parameter */ ;
|
||||
return;
|
||||
}
|
||||
|
47
png.h
47
png.h
@ -1,7 +1,7 @@
|
||||
|
||||
/* png.h - header file for PNG reference library
|
||||
*
|
||||
* libpng version 1.0.5 - October 5, 1999
|
||||
* libpng version 1.0.5 - October 15, 1999
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
* Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
@ -9,13 +9,13 @@
|
||||
* Authors and maintainers:
|
||||
* libpng versions 0.71, May 1995, through 0.89c, May 1996: Guy Schalnat
|
||||
* libpng versions 0.90, December 1996, through 0.96, May 1997: Andreas Dilger
|
||||
* libpng versions 0.97, January 1998, through 1.0.5 - October 5, 1999: Glenn
|
||||
* libpng versions 0.97, January 1998, through 1.0.5 - October 15, 1999: Glenn
|
||||
* See also "Contributing Authors", below.
|
||||
*
|
||||
* Y2K compliance in libpng:
|
||||
* =========================
|
||||
*
|
||||
* October 5, 1999
|
||||
* October 15, 1999
|
||||
*
|
||||
* Since the PNG Development group is an ad-hoc body, we can't make
|
||||
* an official declaration.
|
||||
@ -95,7 +95,7 @@
|
||||
* 1.0.3 1.0.3 10003 2.1.0.3
|
||||
* 1.0.3a-d 1.0.3a-d 10004 2.1.0.3a-d
|
||||
* 1.0.4 1.0.4 10004 2.1.0.4
|
||||
* 1.0.4a-c 1.0.4a-c 10005 2.1.0.4a-c
|
||||
* 1.0.4a-f 1.0.4a-f 10005 2.1.0.4a-f
|
||||
* 1.0.5 1.0.5 10005 2.1.0.5
|
||||
*
|
||||
* Henceforth the source version will match the shared-library minor
|
||||
@ -109,7 +109,9 @@
|
||||
* See libpng.txt or libpng.3 for more information. The PNG specification
|
||||
* is available as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/>
|
||||
* and as a W3C Recommendation <http://www.w3.org/TR/REC.png.html>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT NOTICE:
|
||||
*
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
@ -117,7 +119,7 @@
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
* (libpng versions 0.90, December 1996, through 0.96, May 1997)
|
||||
* Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
* (libpng versions 0.97, January 1998, through 1.0.5, October 5, 1999)
|
||||
* (libpng versions 0.97, January 1998, through 1.0.5, October 15, 1999)
|
||||
*
|
||||
* For the purposes of this copyright and license, "Contributing Authors"
|
||||
* is defined as the following set of individuals:
|
||||
@ -168,7 +170,16 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* A "png_get_copyright" function is available, for convenient use in "about"
|
||||
* boxes and the like:
|
||||
*
|
||||
* printf("%s",png_get_copyright(NULL));
|
||||
*
|
||||
* Also, the PNG logo (in PNG format, of course) is supplied in the
|
||||
* file "pngnow.png".
|
||||
*/
|
||||
|
||||
/*
|
||||
* Libpng is OSI Certified Open Source Software. OSI Certified is a
|
||||
* certification mark of the Open Source Initiative.
|
||||
*/
|
||||
@ -1624,12 +1635,14 @@ extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)
|
||||
|
||||
#ifdef PNG_NO_EXTERN
|
||||
/* this only gets included in png.c */
|
||||
png_charp
|
||||
png_get_header_version(png_structp png_ptr)
|
||||
{
|
||||
if(png_ptr == NULL)
|
||||
/* silence compiler warning about unused png_ptr */ ;
|
||||
return("\n libpng version 1.0.5 - October 5, 1999 (header)\n");
|
||||
|
||||
#define PNG_GET_HEADER \
|
||||
png_charp \
|
||||
png_get_header_version(png_structp png_ptr) \
|
||||
{ \
|
||||
if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ \
|
||||
return("\n libpng version 1.0.5 - October 15, 1999 (header)\n"); \
|
||||
return("\n libpng version 1.0.5 - October 15, 1999 (header)\n"); \
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1649,14 +1662,14 @@ png_get_header_version(png_structp png_ptr)
|
||||
/* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
|
||||
|
||||
# define png_composite(composite, fg, alpha, bg) \
|
||||
{ png_uint_16 temp = ((png_uint_16)(fg) * (png_uint_16)(alpha) + \
|
||||
(png_uint_16)(bg)*(png_uint_16)(255 - \
|
||||
{ png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
|
||||
+ (png_uint_16)(bg)*(png_uint_16)(255 - \
|
||||
(png_uint_16)(alpha)) + (png_uint_16)128); \
|
||||
(composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
|
||||
|
||||
# define png_composite_16(composite, fg, alpha, bg) \
|
||||
{ png_uint_32 temp = ((png_uint_32)(fg) * (png_uint_32)(alpha) + \
|
||||
(png_uint_32)(bg)*(png_uint_32)(65535L - \
|
||||
{ png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
|
||||
+ (png_uint_32)(bg)*(png_uint_32)(65535L - \
|
||||
(png_uint_32)(alpha)) + (png_uint_32)32768L); \
|
||||
(composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* pngasmrd.h - assembler version of utilities to read a PNG file
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1999 Glenn Randers-Pehrson
|
||||
*
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngconf.h - machine configurable file for libpng
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -17,7 +17,6 @@
|
||||
#ifndef PNGCONF_H
|
||||
#define PNGCONF_H
|
||||
|
||||
|
||||
/* This is the size of the compression buffer, and thus the size of
|
||||
* an IDAT chunk. Make this whatever size you feel is best for your
|
||||
* machine. One of these will be allocated per png_struct. When this
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngerror.c - stub functions for i/o and memory allocation
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -75,7 +75,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp message
|
||||
buffer[iout++] = png_digit[c & 0xf];
|
||||
buffer[iout++] = ']';
|
||||
} else {
|
||||
buffer[iout++] = c;
|
||||
buffer[iout++] = (png_byte)c;
|
||||
}
|
||||
}
|
||||
|
||||
|
2
pngget.c
2
pngget.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngget.c - retrieval of values from info struct
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
|
14
pngmem.c
14
pngmem.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngmem.c - stub functions for memory allocation
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -82,12 +82,10 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
(*(free_fn))(png_ptr, struct_ptr);
|
||||
struct_ptr = NULL;
|
||||
return;
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
farfree (struct_ptr);
|
||||
struct_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +234,6 @@ png_free(png_structp png_ptr, png_voidp ptr)
|
||||
if (png_ptr->free_fn != NULL)
|
||||
{
|
||||
(*(png_ptr->free_fn))(png_ptr, ptr);
|
||||
ptr = NULL;
|
||||
return;
|
||||
}
|
||||
else png_free_default(png_ptr, ptr);
|
||||
@ -272,7 +269,6 @@ png_free_default(png_structp png_ptr, png_voidp ptr)
|
||||
if (ptr != NULL)
|
||||
{
|
||||
farfree(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -352,20 +348,16 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
(*(free_fn))(png_ptr, struct_ptr);
|
||||
struct_ptr = NULL;
|
||||
return;
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
farfree(struct_ptr);
|
||||
struct_ptr = NULL;
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
hfree(struct_ptr);
|
||||
struct_ptr = NULL;
|
||||
# else
|
||||
free(struct_ptr);
|
||||
struct_ptr = NULL;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
@ -434,7 +426,6 @@ png_free(png_structp png_ptr, png_voidp ptr)
|
||||
if (png_ptr->free_fn != NULL)
|
||||
{
|
||||
(*(png_ptr->free_fn))(png_ptr, ptr);
|
||||
ptr = NULL;
|
||||
return;
|
||||
}
|
||||
else png_free_default(png_ptr, ptr);
|
||||
@ -446,14 +437,11 @@ png_free_default(png_structp png_ptr, png_voidp ptr)
|
||||
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
farfree(ptr);
|
||||
ptr = NULL;
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
hfree(ptr);
|
||||
ptr = NULL;
|
||||
# else
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
BIN
pngnow.png
BIN
pngnow.png
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngpread.c - read a png file in push mode
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -94,7 +94,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
|
||||
|
||||
png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
|
||||
num_to_check);
|
||||
png_ptr->sig_bytes += num_to_check;
|
||||
png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
|
||||
|
||||
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngread.c - read a PNG file
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -465,10 +465,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
|
||||
png_ptr->row_info.channels = png_ptr->channels;
|
||||
png_ptr->row_info.bit_depth = png_ptr->bit_depth;
|
||||
png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
|
||||
{
|
||||
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
|
||||
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
|
||||
}
|
||||
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
|
||||
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
|
||||
|
||||
png_read_filter_row(png_ptr, &(png_ptr->row_info),
|
||||
png_ptr->row_buf + 1, png_ptr->prev_row + 1,
|
||||
|
2
pngrio.c
2
pngrio.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngrio.c - functions for data input
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
|
140
pngrtran.c
140
pngrtran.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngrtran.c - transforms the data in a row for PNG readers
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -623,7 +623,7 @@ png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
|
||||
}
|
||||
png_ptr->rgb_to_gray_red_coeff = red_byte;
|
||||
png_ptr->rgb_to_gray_green_coeff = green_byte;
|
||||
png_ptr->rgb_to_gray_blue_coeff = 255 - red_byte - green_byte;
|
||||
png_ptr->rgb_to_gray_blue_coeff = (png_byte)(255-red_byte-green_byte);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -706,7 +706,7 @@ png_init_read_transformations(png_structp png_ptr)
|
||||
int i,istop;
|
||||
istop=(int)png_ptr->num_trans;
|
||||
for (i=0; i<istop; i++)
|
||||
png_ptr->trans[i] = 255 - png_ptr->trans[i];
|
||||
png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1053,7 +1053,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
|
||||
if (png_ptr->transformations & PNG_FILLER &&
|
||||
(info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
|
||||
info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
|
||||
++info_ptr->channels;
|
||||
info_ptr->channels++;
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
|
||||
@ -1456,8 +1456,8 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
|
||||
png_bytep bp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
png_byte mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
|
||||
(png_byte)((int)0xf >> shift[0]);
|
||||
png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
|
||||
(png_byte)((int)0xf >> shift[0]));
|
||||
|
||||
for (i = 0; i < istop; i++)
|
||||
{
|
||||
@ -1666,7 +1666,7 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
*(--dp) = 255 - *(--sp);
|
||||
*(--dp) = (png_byte)(255 - *(--sp));
|
||||
*(--dp) = *(--sp);
|
||||
*(--dp) = *(--sp);
|
||||
*(--dp) = *(--sp);
|
||||
@ -1681,8 +1681,8 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
*(--dp) = 255 - *(--sp);
|
||||
*(--dp) = 255 - *(--sp);
|
||||
*(--dp) = (png_byte)(255 - *(--sp));
|
||||
*(--dp) = (png_byte)(255 - *(--sp));
|
||||
*(--dp) = *(--sp);
|
||||
*(--dp) = *(--sp);
|
||||
*(--dp) = *(--sp);
|
||||
@ -1703,7 +1703,7 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
*(--dp) = 255 - *(--sp);
|
||||
*(--dp) = (png_byte)(255 - *(--sp));
|
||||
*(--dp) = *(--sp);
|
||||
}
|
||||
}
|
||||
@ -1716,8 +1716,8 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
*(--dp) = 255 - *(--sp);
|
||||
*(--dp) = 255 - *(--sp);
|
||||
*(--dp) = (png_byte)(255 - *(--sp));
|
||||
*(--dp) = (png_byte)(255 - *(--sp));
|
||||
*(--dp) = *(--sp);
|
||||
*(--dp) = *(--sp);
|
||||
}
|
||||
@ -2065,7 +2065,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
if(red != green || red != blue)
|
||||
{
|
||||
rgb_error |= 1;
|
||||
*(dp++) = (rc*red+gc*green+bc*blue)>>8;
|
||||
*(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>8);
|
||||
}
|
||||
else
|
||||
*(dp++) = *(sp-1);
|
||||
@ -2085,9 +2085,9 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_uint_16 red, green, blue, w;
|
||||
|
||||
red = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
green = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
blue = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
|
||||
if(red == green && red == blue)
|
||||
w = red;
|
||||
@ -2099,15 +2099,15 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
png_ptr->gamma_shift][green>>8];
|
||||
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
|
||||
png_ptr->gamma_shift][blue>>8];
|
||||
png_uint_16 gray16 = (rc * red_1 + gc * green_1
|
||||
+ bc * blue_1)>>8;
|
||||
png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
|
||||
+ bc*blue_1)>>8);
|
||||
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
|
||||
png_ptr->gamma_shift][gray16 >> 8];
|
||||
rgb_error |= 1;
|
||||
}
|
||||
|
||||
*(dp++) = (w>>8) & 0xff;
|
||||
*(dp++) = w & 0xff;
|
||||
*(dp++) = (png_byte)((w>>8) & 0xff);
|
||||
*(dp++) = (png_byte)(w & 0xff);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2119,15 +2119,15 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_uint_16 red, green, blue, gray16;
|
||||
|
||||
red = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
green = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
blue = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
|
||||
if(red != green || red != blue)
|
||||
rgb_error |= 1;
|
||||
gray16 = (rc * red + gc * green + bc * blue)>>8;
|
||||
*(dp++) = (gray16>>8) & 0xff;
|
||||
*(dp++) = gray16 & 0xff;
|
||||
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>8);
|
||||
*(dp++) = (png_byte)((gray16>>8) & 0xff);
|
||||
*(dp++) = (png_byte)(gray16 & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2165,7 +2165,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
png_byte blue = *(sp++);
|
||||
if(red != green || red != blue)
|
||||
rgb_error |= 1;
|
||||
*(dp++) = (gc*red + gc*green + bc*blue)>>8;
|
||||
*(dp++) = (png_byte)((gc*red + gc*green + bc*blue)>>8);
|
||||
*(dp++) = *(sp++); /* alpha */
|
||||
}
|
||||
}
|
||||
@ -2182,9 +2182,9 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_uint_16 red, green, blue, w;
|
||||
|
||||
red = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
green = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
blue = ((*(sp))<<8) | *(sp+1); sp+=2;
|
||||
red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
|
||||
|
||||
if(red == green && red == blue)
|
||||
w = red;
|
||||
@ -2196,15 +2196,15 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
png_ptr->gamma_shift][green>>8];
|
||||
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
|
||||
png_ptr->gamma_shift][blue>>8];
|
||||
png_uint_16 gray16 = (rc * red_1 + gc * green_1
|
||||
+ bc * blue_1)>>8;
|
||||
png_uint_16 gray16 = (png_uint_16)((rc * red_1
|
||||
+ gc * green_1 + bc * blue_1)>>8);
|
||||
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
|
||||
png_ptr->gamma_shift][gray16 >> 8];
|
||||
rgb_error |= 1;
|
||||
}
|
||||
|
||||
*(dp++) = (w>>8) & 0xff;
|
||||
*(dp++) = w & 0xff;
|
||||
*(dp++) = (png_byte)((w>>8) & 0xff);
|
||||
*(dp++) = (png_byte)(w & 0xff);
|
||||
*(dp++) = *(sp++); /* alpha */
|
||||
*(dp++) = *(sp++);
|
||||
}
|
||||
@ -2217,14 +2217,14 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
png_uint_16 red, green, blue, gray16;
|
||||
red = (*(sp)<<8) | *(sp+1); sp+=2;
|
||||
green = (*(sp)<<8) | *(sp+1); sp+=2;
|
||||
blue = (*(sp)<<8) | *(sp+1); sp+=2;
|
||||
red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
|
||||
green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
|
||||
blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
|
||||
if(red != green || red != blue)
|
||||
rgb_error |= 1;
|
||||
gray16 = (rc * red + gc * green + bc * blue)>>8;
|
||||
*(dp++) = (gray16>>8) & 0xff;
|
||||
*(dp++) = gray16 & 0xff;
|
||||
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>8);
|
||||
*(dp++) = (png_byte)((gray16>>8) & 0xff);
|
||||
*(dp++) = (png_byte)(gray16 & 0xff);
|
||||
*(dp++) = *(sp++); /* alpha */
|
||||
*(dp++) = *(sp++);
|
||||
}
|
||||
@ -2543,9 +2543,9 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
}
|
||||
else
|
||||
{
|
||||
png_byte p = (*sp >> shift) & 0x3;
|
||||
png_byte g = (gamma_table [p | (p << 2) | (p << 4) |
|
||||
(p << 6)] >> 6) & 0x3;
|
||||
png_byte p = (png_byte)((*sp >> shift) & 0x3);
|
||||
png_byte g = (png_byte)((gamma_table [p | (p << 2) |
|
||||
(p << 4) | (p << 6)] >> 6) & 0x3);
|
||||
*sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
|
||||
*sp |= (png_byte)(g << shift);
|
||||
}
|
||||
@ -2599,8 +2599,9 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
}
|
||||
else
|
||||
{
|
||||
png_byte p = (*sp >> shift) & 0xf;
|
||||
png_byte g = (gamma_table[p | (p << 4)] >> 4) & 0xf;
|
||||
png_byte p = (png_byte)((*sp >> shift) & 0xf);
|
||||
png_byte g = (png_byte)((gamma_table[p |
|
||||
(p << 4)] >> 4) & 0xf);
|
||||
*sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
|
||||
*sp |= (png_byte)(g << shift);
|
||||
}
|
||||
@ -2679,7 +2680,7 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
{
|
||||
png_uint_16 v;
|
||||
|
||||
v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
|
||||
v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
|
||||
if (v == trans_values->gray)
|
||||
{
|
||||
/* background is already in screen gamma */
|
||||
@ -2702,7 +2703,7 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
{
|
||||
png_uint_16 v;
|
||||
|
||||
v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
|
||||
v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
|
||||
if (v == trans_values->gray)
|
||||
{
|
||||
*sp = (png_byte)((background->gray >> 8) & 0xff);
|
||||
@ -2766,9 +2767,9 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
sp = row;
|
||||
for (i = 0; i < row_width; i++, sp += 6)
|
||||
{
|
||||
png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
|
||||
png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
|
||||
png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
|
||||
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
|
||||
png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
|
||||
png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
|
||||
if (r == trans_values->red && g == trans_values->green &&
|
||||
b == trans_values->blue)
|
||||
{
|
||||
@ -2800,9 +2801,9 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
sp = row;
|
||||
for (i = 0; i < row_width; i++, sp += 6)
|
||||
{
|
||||
png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
|
||||
png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
|
||||
png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
|
||||
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
|
||||
png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
|
||||
png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
|
||||
|
||||
if (r == trans_values->red && g == trans_values->green &&
|
||||
b == trans_values->blue)
|
||||
@ -2886,7 +2887,7 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
dp = row;
|
||||
for (i = 0; i < row_width; i++, sp += 4, dp += 2)
|
||||
{
|
||||
png_uint_16 a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
|
||||
png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
|
||||
|
||||
if (a == (png_uint_16)0xffff)
|
||||
{
|
||||
@ -2921,7 +2922,7 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
dp = row;
|
||||
for (i = 0; i < row_width; i++, sp += 4, dp += 2)
|
||||
{
|
||||
png_uint_16 a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
|
||||
png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
|
||||
if (a == (png_uint_16)0xffff)
|
||||
{
|
||||
png_memcpy(dp, sp, 2);
|
||||
@ -2935,7 +2936,7 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
{
|
||||
png_uint_16 g, v;
|
||||
|
||||
g = ((png_uint_16)(*sp) << 8) + *(sp + 1);
|
||||
g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
|
||||
png_composite_16(v, g, a, background_1->gray);
|
||||
*dp = (png_byte)((v >> 8) & 0xff);
|
||||
*(dp + 1) = (png_byte)(v & 0xff);
|
||||
@ -3104,11 +3105,11 @@ png_do_background(png_row_infop row_info, png_bytep row,
|
||||
{
|
||||
png_uint_16 v;
|
||||
|
||||
png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
|
||||
png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8)
|
||||
+ *(sp + 3);
|
||||
png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8)
|
||||
+ *(sp + 5);
|
||||
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
|
||||
png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
|
||||
+ *(sp + 3));
|
||||
png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
|
||||
+ *(sp + 5));
|
||||
|
||||
png_composite_16(v, r, a, background->red);
|
||||
*dp = (png_byte)((v >> 8) & 0xff);
|
||||
@ -3277,10 +3278,11 @@ png_do_gamma(png_row_infop row_info, png_bytep row,
|
||||
int c = *sp & 0x0c;
|
||||
int d = *sp & 0x03;
|
||||
|
||||
*sp = ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
|
||||
*sp = (png_byte)(
|
||||
((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
|
||||
((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
|
||||
((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
|
||||
((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) );
|
||||
((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
@ -3292,8 +3294,8 @@ png_do_gamma(png_row_infop row_info, png_bytep row,
|
||||
int msb = *sp & 0xf0;
|
||||
int lsb = *sp & 0x0f;
|
||||
|
||||
*sp = (((int)gamma_table[msb | (msb >> 4)]) & 0xf0) |
|
||||
(((int)gamma_table[(lsb << 4) | lsb]) >> 4);
|
||||
*sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
|
||||
| (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
@ -3487,7 +3489,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
png_uint_16 gray = trans_value ? trans_value->gray : 0;
|
||||
png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
|
||||
|
||||
if (row_info->bit_depth < 8)
|
||||
{
|
||||
@ -3495,7 +3497,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
gray *= 0xff;
|
||||
gray = (png_uint_16)(gray*0xff);
|
||||
sp = row + (png_size_t)((row_width - 1) >> 3);
|
||||
dp = row + (png_size_t)row_width - 1;
|
||||
shift = 7 - (int)((row_width + 7) & 7);
|
||||
@ -3519,7 +3521,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
gray *= 0x55;
|
||||
gray = (png_uint_16)(gray*0x55);
|
||||
sp = row + (png_size_t)((row_width - 1) >> 2);
|
||||
dp = row + (png_size_t)row_width - 1;
|
||||
shift = (int)((3 - ((row_width + 3) & 3)) << 1);
|
||||
@ -3542,7 +3544,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
gray *= 0x11;
|
||||
gray = (png_uint_16)(gray*0x11);
|
||||
sp = row + (png_size_t)((row_width - 1) >> 1);
|
||||
dp = row + (png_size_t)row_width - 1;
|
||||
shift = (int)((1 - ((row_width + 1) & 1)) << 2);
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngrutil.c - utilities to read a PNG file
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
|
2
pngset.c
2
pngset.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngset.c - storage of image information into info struct
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngtest.c - a simple test program to test libpng
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
|
174
pngvcrd.c
174
pngvcrd.c
@ -2,7 +2,7 @@
|
||||
*
|
||||
* For Intel x86 CPU and Microsoft Visual C++ compiler
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998, Intel Corporation
|
||||
* Copyright (c) 1998, 1999 Glenn Randers-Pehrson
|
||||
@ -26,7 +26,6 @@ png_read_filter_row_c(png_structp png_ptr, png_row_infop row_info,
|
||||
static int mmxsupport()
|
||||
{
|
||||
int mmx_supported_local = 0;
|
||||
|
||||
_asm {
|
||||
pushfd //Save Eflag to stack
|
||||
pop eax //Get Eflag from stack into eax
|
||||
@ -91,19 +90,19 @@ NOT_SUPPORTED:
|
||||
void
|
||||
png_combine_row(png_structp png_ptr, png_bytep row, int mask)
|
||||
{
|
||||
#ifndef MMX_BUG_IS_FIXED
|
||||
#ifdef DISABLE_PNGVCRD_COMBINE
|
||||
int save_mmx_supported = mmx_supported;
|
||||
#endif
|
||||
|
||||
png_debug(1,"in png_combine_row_asm\n");
|
||||
|
||||
#ifndef MMX_BUG_IS_FIXED
|
||||
#ifdef DISABLE_PNGVCRD_COMBINE
|
||||
if ((png_ptr->transformations & PNG_INTERLACE) && png_ptr->pass != 6)
|
||||
mmx_supported = 0;
|
||||
else
|
||||
#endif
|
||||
if (mmx_supported == 2)
|
||||
mmx_supported = mmxsupport();
|
||||
if (mmx_supported == 2)
|
||||
mmx_supported = mmxsupport();
|
||||
|
||||
if (mask == 0xff)
|
||||
{
|
||||
@ -948,7 +947,7 @@ end48:
|
||||
} /* end switch (png_ptr->row_info.pixel_depth) */
|
||||
} /* end if (non-trivial mask) */
|
||||
|
||||
#ifndef MMX_BUG_IS_FIXED
|
||||
#ifdef DISABLE_PNGVCRD_COMBINE
|
||||
mmx_supported = save_mmx_supported;
|
||||
#endif
|
||||
|
||||
@ -961,18 +960,27 @@ void
|
||||
png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
|
||||
png_uint_32 transformations)
|
||||
{
|
||||
#ifndef MMX_BUG_IS_FIXED
|
||||
#ifdef DISABLE_PNGVCRD_INTERLACE
|
||||
int save_mmx_supported = mmx_supported;
|
||||
#endif
|
||||
|
||||
png_debug(1,"in png_do_read_interlace\n");
|
||||
|
||||
#ifndef MMX_BUG_IS_FIXED
|
||||
mmx_supported = 0;
|
||||
#else
|
||||
if (mmx_supported == 2)
|
||||
mmx_supported = mmxsupport();
|
||||
#ifdef DISABLE_PNGVCRD_INTERLACE
|
||||
/* In libpng versions 1.0.3a through 1.0.4d,
|
||||
* a sign error in the post-MMX cleanup code for each pixel_depth resulted
|
||||
* in bad pixels at the beginning of some rows of some images, and also
|
||||
* (due to out-of-range memory reads and writes) caused heap corruption
|
||||
* when compiled with MSVC 6.0. The error was fixed in version 1.0.4e,
|
||||
* and the code appears to work completely correctly, so it is enabled
|
||||
* by default.
|
||||
*/
|
||||
if (1) /* all passes caused a heap problem in the old code */
|
||||
mmx_supported = 0;
|
||||
else
|
||||
#endif
|
||||
if (mmx_supported == 2)
|
||||
mmx_supported = mmxsupport();
|
||||
|
||||
if (row != NULL && row_info != NULL)
|
||||
{
|
||||
@ -1155,21 +1163,20 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
|
||||
default: // This is the place where the routine is modified
|
||||
{
|
||||
__int64 const4 = 0x0000000000FFFFFF;
|
||||
__int64 const5 = 0x000000FFFFFF0000;
|
||||
// __int64 const5 = 0x000000FFFFFF0000; // unused...
|
||||
__int64 const6 = 0x00000000000000FF;
|
||||
//int mmx_supported = 1;
|
||||
|
||||
png_bytep sptr, dp;
|
||||
png_uint_32 i;
|
||||
png_size_t pixel_bytes;
|
||||
|
||||
int width = row_info->width;
|
||||
|
||||
pixel_bytes = (row_info->pixel_depth >> 3);
|
||||
|
||||
sptr = row + (row_info->width - 1) * pixel_bytes;
|
||||
sptr = row + (width - 1) * pixel_bytes;
|
||||
dp = row + (final_width - 1) * pixel_bytes;
|
||||
// New code by Nirav Chhatrapati - Intel Corporation
|
||||
// sign fix by GRR
|
||||
// NOTE: there is NO MMX code for 48-bit and 64-bit images
|
||||
|
||||
if (mmx_supported) // use MMX routine if machine supports it
|
||||
{
|
||||
@ -1336,16 +1343,29 @@ loop1_pass0:
|
||||
dp -= width_mmx*8;
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
|
||||
png_memcpy(v, sptr, pixel_bytes);
|
||||
/* I simplified this part in version 1.0.4e
|
||||
* here and in several other instances where
|
||||
* pixel_bytes == 1 -- GR-P
|
||||
*
|
||||
* Original code:
|
||||
*
|
||||
* png_byte v[8];
|
||||
* png_memcpy(v, sptr, pixel_bytes);
|
||||
* for (j = 0; j < png_pass_inc[pass]; j++)
|
||||
* {
|
||||
* png_memcpy(dp, v, pixel_bytes);
|
||||
* dp -= pixel_bytes;
|
||||
* }
|
||||
* sptr -= pixel_bytes;
|
||||
*
|
||||
* Replacement code is in the next three lines:
|
||||
*/
|
||||
|
||||
for (j = 0; j < png_pass_inc[pass]; j++)
|
||||
{
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
dp -= pixel_bytes;
|
||||
}
|
||||
sptr -= pixel_bytes;
|
||||
*dp-- = *sptr;
|
||||
sptr--;
|
||||
}
|
||||
}
|
||||
else if ((pass == 2) || (pass == 3))
|
||||
@ -1381,16 +1401,13 @@ loop1_pass2:
|
||||
dp -= width_mmx*4;
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
|
||||
png_memcpy(v, sptr, pixel_bytes);
|
||||
for (j = 0; j < png_pass_inc[pass]; j++)
|
||||
{
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
dp -= pixel_bytes;
|
||||
*dp-- = *sptr;
|
||||
}
|
||||
sptr -= pixel_bytes;
|
||||
sptr --;
|
||||
}
|
||||
}
|
||||
else //if ((pass == 4) || (pass == 5))
|
||||
@ -1427,16 +1444,13 @@ loop1_pass4:
|
||||
dp -= width_mmx*2;
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
|
||||
png_memcpy(v, sptr, pixel_bytes);
|
||||
for (j = 0; j < png_pass_inc[pass]; j++)
|
||||
{
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
dp -= pixel_bytes;
|
||||
*dp-- = *sptr;
|
||||
}
|
||||
sptr -= pixel_bytes;
|
||||
sptr --;
|
||||
}
|
||||
}
|
||||
} /* end of pixel_bytes == 1 */
|
||||
@ -1474,8 +1488,8 @@ loop2_pass0:
|
||||
}
|
||||
}
|
||||
|
||||
sptr -= (width_mmx*2 + 2);
|
||||
dp -= (width_mmx*16 + 2);
|
||||
sptr -= (width_mmx*2 - 2); // sign fixed
|
||||
dp -= (width_mmx*16 - 2); // sign fixed
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
@ -1486,9 +1500,7 @@ loop2_pass0:
|
||||
{
|
||||
dp -= pixel_bytes;
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
//dp -= pixel_bytes;
|
||||
}
|
||||
//sptr -= pixel_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1522,8 +1534,8 @@ loop2_pass2:
|
||||
}
|
||||
}
|
||||
|
||||
sptr -= (width_mmx*2 + 2);
|
||||
dp -= (width_mmx*8 + 2);
|
||||
sptr -= (width_mmx*2 - 2); // sign fixed
|
||||
dp -= (width_mmx*8 - 2); // sign fixed
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
@ -1534,9 +1546,7 @@ loop2_pass2:
|
||||
{
|
||||
dp -= pixel_bytes;
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
//dp -= pixel_bytes;
|
||||
}
|
||||
//sptr -= pixel_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1565,8 +1575,8 @@ loop2_pass4:
|
||||
}
|
||||
}
|
||||
|
||||
sptr -= (width_mmx*2 + 2);
|
||||
dp -= (width_mmx*4 + 2);
|
||||
sptr -= (width_mmx*2 - 2); // sign fixed
|
||||
dp -= (width_mmx*4 - 2); // sign fixed
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
@ -1577,9 +1587,7 @@ loop2_pass4:
|
||||
{
|
||||
dp -= pixel_bytes;
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
//dp -= pixel_bytes;
|
||||
}
|
||||
//sptr -= pixel_bytes;
|
||||
}
|
||||
}
|
||||
} /* end of pixel_bytes == 2 */
|
||||
@ -1620,8 +1628,8 @@ loop4_pass0:
|
||||
}
|
||||
}
|
||||
|
||||
sptr -= (width_mmx*4 + 4);
|
||||
dp -= (width_mmx*32 + 4);
|
||||
sptr -= (width_mmx*4 - 4); // sign fixed
|
||||
dp -= (width_mmx*32 - 4); // sign fixed
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
@ -1632,9 +1640,7 @@ loop4_pass0:
|
||||
{
|
||||
dp -= pixel_bytes;
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
//dp -= pixel_bytes;
|
||||
}
|
||||
//sptr -= pixel_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1668,8 +1674,8 @@ loop4_pass2:
|
||||
}
|
||||
}
|
||||
|
||||
sptr -= (width_mmx*4 + 4);
|
||||
dp -= (width_mmx*16 + 4);
|
||||
sptr -= (width_mmx*4 - 4); // sign fixed
|
||||
dp -= (width_mmx*16 - 4); // sign fixed
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
@ -1680,9 +1686,7 @@ loop4_pass2:
|
||||
{
|
||||
dp -= pixel_bytes;
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
//dp -= pixel_bytes;
|
||||
}
|
||||
//sptr -= pixel_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1714,8 +1718,8 @@ loop4_pass4:
|
||||
}
|
||||
}
|
||||
|
||||
sptr -= (width_mmx*4 + 4);
|
||||
dp -= (width_mmx*8 + 4);
|
||||
sptr -= (width_mmx*4 - 4); // sign fixed
|
||||
dp -= (width_mmx*8 - 4); // sign fixed
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
@ -1726,9 +1730,7 @@ loop4_pass4:
|
||||
{
|
||||
dp -= pixel_bytes;
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
//dp -= pixel_bytes;
|
||||
}
|
||||
//sptr -= pixel_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1736,7 +1738,7 @@ loop4_pass4:
|
||||
|
||||
else if (pixel_bytes == 6)
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
@ -1752,7 +1754,7 @@ loop4_pass4:
|
||||
|
||||
else
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
@ -1772,23 +1774,17 @@ loop4_pass4:
|
||||
{
|
||||
if (pixel_bytes == 1)
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
|
||||
png_memcpy(v, sptr, pixel_bytes);
|
||||
for (j = 0; j < png_pass_inc[pass]; j++)
|
||||
{
|
||||
png_memcpy(dp, v, pixel_bytes);
|
||||
dp -= pixel_bytes;
|
||||
}
|
||||
sptr -= pixel_bytes;
|
||||
*dp-- = *sptr;
|
||||
sptr--;
|
||||
}
|
||||
}
|
||||
else if (pixel_bytes == 3)
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
@ -1803,7 +1799,7 @@ loop4_pass4:
|
||||
}
|
||||
else if (pixel_bytes == 2)
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
@ -1818,7 +1814,7 @@ loop4_pass4:
|
||||
}
|
||||
else if (pixel_bytes == 4)
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
@ -1833,7 +1829,7 @@ loop4_pass4:
|
||||
}
|
||||
else if (pixel_bytes == 6)
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
@ -1848,7 +1844,7 @@ loop4_pass4:
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = row_info->width; i; i--)
|
||||
for (i = width; i; i--)
|
||||
{
|
||||
png_byte v[8];
|
||||
int j;
|
||||
@ -1872,7 +1868,7 @@ loop4_pass4:
|
||||
(png_uint_32)row_info->pixel_depth + 7) >> 3);
|
||||
}
|
||||
|
||||
#ifndef MMX_BUG_IS_FIXED
|
||||
#ifdef DISABLE_PNGVCRD_INTERLACE
|
||||
mmx_supported = save_mmx_supported;
|
||||
#endif
|
||||
}
|
||||
@ -3647,7 +3643,7 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
|
||||
#ifdef PNG_DEBUG
|
||||
char filnm[6];
|
||||
#endif
|
||||
#define UseMMX (1)
|
||||
#define UseMMX 1
|
||||
|
||||
if (mmx_supported == 2)
|
||||
mmx_supported = mmxsupport();
|
||||
@ -3660,7 +3656,11 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
|
||||
|
||||
#ifdef PNG_DEBUG
|
||||
png_debug(1, "in png_read_filter_row\n");
|
||||
png_debug1(0,"%s, ", (UseMMX?"MMX":"x86"));
|
||||
#if (UseMMX == 1)
|
||||
png_debug1(0,"%s, ", "MMX");
|
||||
#else
|
||||
png_debug1(0,"%s, ", "x86");
|
||||
#endif
|
||||
switch (filter)
|
||||
{
|
||||
case 0: sprintf(filnm, "None ");
|
||||
@ -3688,12 +3688,14 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
|
||||
break;
|
||||
case PNG_FILTER_VALUE_SUB:
|
||||
{
|
||||
if ( UseMMX && (row_info->pixel_depth > 8) &&
|
||||
#if (UseMMX == 1)
|
||||
if ((row_info->pixel_depth > 8) &&
|
||||
(row_info->rowbytes >= 128) )
|
||||
{
|
||||
png_read_filter_row_mmx_sub(row_info, row);
|
||||
} //end if UseMMX
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
@ -3711,12 +3713,14 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
|
||||
}
|
||||
case PNG_FILTER_VALUE_UP:
|
||||
{
|
||||
if ( UseMMX && (row_info->pixel_depth > 8) &&
|
||||
#if (UseMMX == 1)
|
||||
if ((row_info->pixel_depth > 8) &&
|
||||
(row_info->rowbytes >= 128) )
|
||||
{
|
||||
png_read_filter_row_mmx_up(row_info, row, prev_row);
|
||||
} //end if UseMMX
|
||||
else
|
||||
#endif
|
||||
{
|
||||
png_bytep rp;
|
||||
png_bytep pp;
|
||||
@ -3731,12 +3735,14 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
|
||||
}
|
||||
case PNG_FILTER_VALUE_AVG:
|
||||
{
|
||||
if ( UseMMX && (row_info->pixel_depth > 8) &&
|
||||
#if (UseMMX == 1)
|
||||
if ((row_info->pixel_depth > 8) &&
|
||||
(row_info->rowbytes >= 128) )
|
||||
{
|
||||
png_read_filter_row_mmx_avg(row_info, row, prev_row);
|
||||
} //end if UseMMX
|
||||
else
|
||||
#endif
|
||||
{
|
||||
png_uint_32 i;
|
||||
png_bytep rp = row;
|
||||
@ -3763,12 +3769,14 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
|
||||
}
|
||||
case PNG_FILTER_VALUE_PAETH:
|
||||
{
|
||||
if ( UseMMX && (row_info->pixel_depth > 8) &&
|
||||
#if (UseMMX == 1)
|
||||
if ((row_info->pixel_depth > 8) &&
|
||||
(row_info->rowbytes >= 128) )
|
||||
{
|
||||
png_read_filter_row_mmx_paeth(row_info, row, prev_row);
|
||||
} //end if UseMMX
|
||||
else
|
||||
#endif
|
||||
{
|
||||
png_uint_32 i;
|
||||
png_bytep rp = row;
|
||||
|
2
pngwio.c
2
pngwio.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngwio.c - functions for data output
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
|
10
pngwrite.c
10
pngwrite.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngwrite.c - general routines to write a PNG file
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -77,7 +77,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
int j;
|
||||
for (j=0; j<(int)info_ptr->num_trans; j++)
|
||||
info_ptr->trans[j] = 255 - info_ptr->trans[j];
|
||||
info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
|
||||
}
|
||||
#endif
|
||||
png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
|
||||
@ -799,7 +799,7 @@ png_set_filter(png_structp png_ptr, int method, int filters)
|
||||
if (png_ptr->prev_row == NULL)
|
||||
{
|
||||
png_warning(png_ptr, "Can't add Paeth filter after starting");
|
||||
png_ptr->do_filter &= ~PNG_FILTER_PAETH;
|
||||
png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -850,8 +850,8 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
|
||||
num_weights = 0;
|
||||
}
|
||||
|
||||
png_ptr->num_prev_filters = num_weights;
|
||||
png_ptr->heuristic_method = heuristic_method;
|
||||
png_ptr->num_prev_filters = (png_byte)num_weights;
|
||||
png_ptr->heuristic_method = (png_byte)heuristic_method;
|
||||
|
||||
if (num_weights > 0)
|
||||
{
|
||||
|
16
pngwtran.c
16
pngwtran.c
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngwtran.c - transforms the data in a row for PNG writers
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -311,7 +311,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||
png_uint_16 value, v;
|
||||
int j;
|
||||
|
||||
v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
|
||||
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
|
||||
value = 0;
|
||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
||||
{
|
||||
@ -438,7 +438,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = 255 - *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in RRGGBBAA */
|
||||
@ -456,8 +456,8 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = 255 - *(sp++);
|
||||
*(dp++) = 255 - *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -473,7 +473,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = 255 - *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in GGAA */
|
||||
@ -487,8 +487,8 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = 255 - *(sp++);
|
||||
*(dp++) = 255 - *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/* pngwutil.c - utilities to write a PNG file
|
||||
*
|
||||
* libpng 1.0.5 - October 5, 1999
|
||||
* libpng 1.0.5 - October 15, 1999
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
* Copyright (c) 1996, 1997 Andreas Dilger
|
||||
@ -380,7 +380,8 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
|
||||
{
|
||||
png_byte maxbits;
|
||||
|
||||
maxbits = color_type==PNG_COLOR_TYPE_PALETTE ? 8 : png_ptr->usr_bit_depth;
|
||||
maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
|
||||
png_ptr->usr_bit_depth);
|
||||
if (sbit->red == 0 || sbit->red > maxbits ||
|
||||
sbit->green == 0 || sbit->green > maxbits ||
|
||||
sbit->blue == 0 || sbit->blue > maxbits)
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
|
||||
# For conditions of distribution and use, see copyright notice in png.h
|
||||
|
||||
# This makefile requires file file ansi2knr.c, which you can get
|
||||
# This makefile requires the file ansi2knr.c, which you can get
|
||||
# from the Ghostscript ftp site at ftp://ftp.cs.wisc.edu/ghost/
|
||||
# If you have libjpeg, you probably already have ansi2knr.c in the jpeg
|
||||
# source distribution.
|
||||
|
Reference in New Issue
Block a user