[libpng14] Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7+

Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c
    because usleep() is deprecated (port from libpng16).
  Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
  Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
This commit is contained in:
Glenn Randers-Pehrson
2015-07-30 16:24:34 -05:00
parent eff804c744
commit 6a88a77216
7 changed files with 217 additions and 96 deletions

View File

@@ -1,5 +1,5 @@
Libpng 1.4.17beta01 - May 15, 2015 Libpng 1.4.17beta01 - July 30, 2015
This is not intended to be a public release. It will be replaced This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version. within a few weeks by a public version or by another test version.
@@ -27,12 +27,18 @@ Other information:
Changes since the last public release (1.4.16): Changes since the last public release (1.4.16):
version 1.4.17beta01 [May 15, 2015] version 1.4.17beta01 [July 30, 2015]
Fix typecast in a png_debug2() statement in png_set_text_2() to Fix typecast in a png_debug2() statement in png_set_text_2() to
avoid a compiler warning in PNG_DEBUG builds. avoid a compiler warning in PNG_DEBUG builds.
Avoid Coverity issues 80855, 80856, and 80857 (PRINTF_ARG_MISMATCH) Avoid Coverity issues 80855, 80856, and 80857 (PRINTF_ARG_MISMATCH)
in pngtest.c PNG_DEBUG builds. in pngtest.c PNG_DEBUG builds.
Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds. Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds.
Removed WRITE_WEIGHTED_FILTERED code.
Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7+
Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c
because usleep() is deprecated (port from libpng16).
Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
Send comments/corrections/commendations to glennrp at users.sourceforge.net Send comments/corrections/commendations to glennrp at users.sourceforge.net
or to png-mng-implement at lists.sf.net (subscription required; visit or to png-mng-implement at lists.sf.net (subscription required; visit

11
CHANGES
View File

@@ -469,7 +469,7 @@ version 1.0.3d [September 4, 1999]
Added new png_expand functions to scripts/pngdef.pas and pngos2.def Added new png_expand functions to scripts/pngdef.pas and pngos2.def
Added a demo read_user_transform_fn that examines the row filters in pngtest.c Added a demo read_user_transform_fn that examines the row filters in pngtest.c
version 1.0.4 [September 24, 1999] Version 1.0.4 [September 24, 1999, not distributed publicly]
Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h
Made several minor corrections to pngtest.c Made several minor corrections to pngtest.c
@@ -493,6 +493,7 @@ version 1.0.4c [October 1, 1999]
Added a "png_check_version" function in png.c and pngtest.c that will generate 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. a helpful compiler error if an old png.h is found in the search path.
Changed type of png_user_transform_depth|channels from int to png_byte. Changed type of png_user_transform_depth|channels from int to png_byte.
Added "Libpng is OSI Certified Open Source Software" statement to png.h
version 1.0.4d [October 6, 1999] version 1.0.4d [October 6, 1999]
Changed 0.45 to 0.45455 in png_set_sRGB() Changed 0.45 to 0.45455 in png_set_sRGB()
Removed unused PLTE entries from pngnow.png Removed unused PLTE entries from pngnow.png
@@ -2956,12 +2957,18 @@ version 1.4.16rc01 [March 4, 2015]
version 1.4.16 [March 19, 2015] version 1.4.16 [March 19, 2015]
No changes. No changes.
version 1.4.17beta01 [May 15, 2015] version 1.4.17beta01 [July 30, 2015]
Fix typecast in a png_debug2() statement in png_set_text_2() to Fix typecast in a png_debug2() statement in png_set_text_2() to
avoid a compiler warning in PNG_DEBUG builds. avoid a compiler warning in PNG_DEBUG builds.
Avoid Coverity issues 80855, 80856, and 80857 (PRINTF_ARG_MISMATCH) Avoid Coverity issues 80855, 80856, and 80857 (PRINTF_ARG_MISMATCH)
in pngtest.c PNG_DEBUG builds. in pngtest.c PNG_DEBUG builds.
Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds. Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds.
Removed WRITE_WEIGHTED_FILTERED code.
Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7+
Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c
because usleep() is deprecated (port from libpng16).
Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
Send comments/corrections/commendations to glennrp at users.sourceforge.net Send comments/corrections/commendations to glennrp at users.sourceforge.net
or to png-mng-implement at lists.sf.net (subscription required; visit or to png-mng-implement at lists.sf.net (subscription required; visit

View File

@@ -41,10 +41,12 @@
unexpected-EOF and file-read-error cases; fixed Trace() cut-and- unexpected-EOF and file-read-error cases; fixed Trace() cut-and-
paste bugs paste bugs
- 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options - 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options
- 2.04: Added "void(foo);" statements to quiet pedantic compiler warnings
about unused variables (GR-P)
- 2.05: Use nanosleep() instead of usleep(), which is deprecated (GR-P).
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. Copyright (c) 1998-2010, 2014-2015 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind, This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors express or implied. In no event shall the author or contributors
@@ -95,9 +97,9 @@
#define PROGNAME "rpng2-x" #define PROGNAME "rpng2-x"
#define LONGNAME "Progressive PNG Viewer for X" #define LONGNAME "Progressive PNG Viewer for X"
#define VERSION "2.03 of 25 February 2010" #define VERSION "2.04 of 15 June 2014"
#define RESNAME "rpng2" /* our X resource application name */ #define RESNAME "rpng2" /* our X resource application name */
#define RESCLASS "Rpng" /* our X resource class name */ #define RESCLASS "Rpng" /* our X resource class name */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -111,6 +113,19 @@
#include <X11/Xos.h> #include <X11/Xos.h>
#include <X11/keysym.h> /* defines XK_* macros */ #include <X11/keysym.h> /* defines XK_* macros */
#if _POSIX_C_SOURCE >= 199309L /* have nanosleep() */
# undef usleep
# define usleep(usec) { \
struct timespec ts; \
ts.tv_sec = 0; \
ts.tv_nsec = (usec) * 1000; \
nanosleep(&ts, NULL); }
# endif
#ifndef usleep /* have neither nanosleep() nor usleep() */
# define usleep(x) sleep(((x)+499999)/1000000)
#endif
#ifdef VMS #ifdef VMS
# include <unistd.h> # include <unistd.h>
#endif #endif
@@ -132,7 +147,7 @@
(e.type == KeyPress && /* v--- or 1 for shifted keys */ \ (e.type == KeyPress && /* v--- or 1 for shifted keys */ \
((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape))) ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape)))
#define NO_24BIT_MASKS /* undef case not fully written--only for redisplay() */ #define NO_24BIT_MASKS /* undef case not fully written--only for redisplay() */
#define rgb1_max bg_freq #define rgb1_max bg_freq
#define rgb1_min bg_gray #define rgb1_min bg_gray
@@ -302,7 +317,7 @@ int main(int argc, char **argv)
int have_bg = FALSE; int have_bg = FALSE;
#ifdef FEATURE_LOOP #ifdef FEATURE_LOOP
int loop = FALSE; int loop = FALSE;
long loop_interval = -1; /* seconds (100,000 max) */ long loop_interval = -1; /* seconds (100,000 max) */
#endif #endif
double LUT_exponent; /* just the lookup table */ double LUT_exponent; /* just the lookup table */
double CRT_exponent = 2.2; /* just the monitor */ double CRT_exponent = 2.2; /* just the monitor */
@@ -456,43 +471,47 @@ int main(int argc, char **argv)
fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
readpng2_version_info(); readpng2_version_info();
fprintf(stderr, "\n" fprintf(stderr, "\n"
"Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n" "Usage: ");
fprintf(stderr,
"%s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
" %*s [-usleep dur | -timing] [-pause]\n",
PROGNAME, (int)strlen(PROGNAME), " ");
fprintf(stderr,
#ifdef FEATURE_LOOP #ifdef FEATURE_LOOP
" %*s [-usleep dur | -timing] [-pause] [-loop [sec]] file.png\n\n" " [-loop [sec]]"
#else
" %*s [-usleep dur | -timing] [-pause] file.png\n\n"
#endif #endif
" file.png\n\n");
fprintf(stderr,
" xdpy\tname of the target X display (e.g., ``hostname:0'')\n" " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
" exp \ttransfer-function exponent (``gamma'') of the display\n" " exp \ttransfer-function exponent (``gamma'') of the display\n"
"\t\t system in floating-point format (e.g., ``%.1f''); equal\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 to the product of the lookup-table exponent (varies)\n",
default_display_exponent);
fprintf(stderr,
"\t\t and the CRT exponent (usually 2.2); must be positive\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" " bg \tdesired background color in 7-character hex RGB format\n"
"\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
"\t\t used with transparent images; overrides -bgpat\n" "\t\t used with transparent images; overrides -bgpat\n"
" pat \tdesired background pattern number (0-%d); used with\n" " pat \tdesired background pattern number (0-%d); used with\n"
"\t\t transparent images; overrides -bgcolor\n" "\t\t transparent images; overrides -bgcolor\n",
num_bgpat-1);
#ifdef FEATURE_LOOP #ifdef FEATURE_LOOP
fprintf(stderr,
" -loop\tloops through background images after initial display\n" " -loop\tloops through background images after initial display\n"
"\t\t is complete (depends on -bgpat)\n" "\t\t is complete (depends on -bgpat)\n"
" sec \tseconds to display each background image (default = 2)\n" " sec \tseconds to display each background image (default = 2)\n");
#endif #endif
fprintf(stderr,
" dur \tduration in microseconds to wait after displaying each\n" " dur \tduration in microseconds to wait after displaying each\n"
"\t\t row (for demo purposes)\n" "\t\t row (for demo purposes)\n"
" -timing\tenables delay for every block read, to simulate modem\n" " -timing\tenables delay for every block read, to simulate modem\n"
"\t\t download of image (~36 Kbps)\n" "\t\t download of image (~36 Kbps)\n"
" -pause\tpauses after displaying each pass until mouse clicked\n" " -pause\tpauses after displaying each pass until mouse clicked\n"
"\nPress Q, Esc or mouse button 1 (within image window, after image\n" "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
"is displayed) to quit.\n" "is displayed) to quit.\n");
"\n", PROGNAME,
#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__))
(int)strlen(PROGNAME), " ",
#endif
(int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat-1);
exit(1); exit(1);
} }
if (!(infile = fopen(filename, "rb"))) { if (!(infile = fopen(filename, "rb"))) {
fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
++error; ++error;
@@ -594,7 +613,7 @@ int main(int argc, char **argv)
"(unexpectedly) while reading PNG image file\n"); "(unexpectedly) while reading PNG image file\n");
exit(3); exit(3);
} else /* if (error) */ { } else /* if (error) */ {
// will print error message below /* will print error message below */
} }
break; break;
} }
@@ -738,6 +757,8 @@ int main(int argc, char **argv)
Trace((stderr, "about to call rpng2_x_cleanup()\n")) Trace((stderr, "about to call rpng2_x_cleanup()\n"))
rpng2_x_cleanup(); rpng2_x_cleanup();
(void)argc; /* Unused */
return 0; return 0;
} }
@@ -784,8 +805,9 @@ static void rpng2_x_init(void)
if (rpng2_x_create_window()) { if (rpng2_x_create_window()) {
/* GRR TEMPORARY HACK: this is fundamentally no different from cases /* GRR TEMPORARY HACK: this is fundamentally no different from cases
* above; libpng should longjmp() back to us when png_ptr goes away. * above; libpng should call our error handler to longjmp() back to us
* If we/it segfault instead, seems like a libpng bug... */ * when png_ptr goes away. If we/it segfault instead, seems like a
* libpng bug... */
/* we're here via libpng callback, so if window fails, clean and bail */ /* we're here via libpng callback, so if window fails, clean and bail */
readpng2_cleanup(&rpng2_info); readpng2_cleanup(&rpng2_info);
@@ -1279,7 +1301,7 @@ static int rpng2_x_load_bg_image(void)
for (row = 0; row < rpng2_info.height; ++row) { for (row = 0; row < rpng2_info.height; ++row) {
src = bg_data + row*bg_rowbytes; src = bg_data + row*bg_rowbytes;
dest = ximage->data + row*ximage_rowbytes; dest = ximage->data + row*ximage_rowbytes;
if (bpp == 32) { /* slightly optimized version */ if (bpp == 32) { /* slightly optimized version */
for (i = rpng2_info.width; i > 0; --i) { for (i = rpng2_info.width; i > 0; --i) {
red = *src++; red = *src++;
green = *src++; green = *src++;
@@ -1828,6 +1850,9 @@ static void rpng2_x_redisplay_image(ulg startcol, ulg startrow,
XFlush(display); XFlush(display);
} }
(void)startcol;
(void)width;
} /* end function rpng2_x_redisplay_image() */ } /* end function rpng2_x_redisplay_image() */

View File

@@ -7,7 +7,7 @@ LD=$(CC)
RM=rm -f RM=rm -f
CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP \ CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP -DZ_SOLO \
-DdeflateParams\(a,b,c\)=Z_OK -I. -O1 -DdeflateParams\(a,b,c\)=Z_OK -I. -O1
C=.c C=.c

View File

@@ -7,7 +7,7 @@ LD=$(CC)
RM=rm -f RM=rm -f
CFLAGS=-DPNG_USER_CONFIG -DNO_GZIP -I. -O1 CFLAGS=-DPNG_USER_CONFIG -DNO_GZIP -DZ_SOLO -I. -O1
C=.c C=.c
O=.o O=.o

View File

@@ -23,7 +23,7 @@ XLIB = -L/usr/X11R6/lib -lX11
#LIBS = $(XLIB) #LIBS = $(XLIB)
LIBS = $(XLIB) -lm #platforms that need libm LIBS = $(XLIB) -lm #platforms that need libm
CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP \ CFLAGS=-DPNG_USER_CONFIG -DNO_GZCOMPRESS -DNO_GZIP -DZ_SOLO \
-DdeflateParams\(a,b,c\)=Z_OK -I. $(XINC) -O1 -DdeflateParams\(a,b,c\)=Z_OK -I. $(XINC) -O1
C=.c C=.c

View File

@@ -3,6 +3,7 @@
* copyright (C) 1999 by Willem van Schaik <willem@schaik.com> * copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
* *
* version 1.0 - 1999.10.15 - First version. * version 1.0 - 1999.10.15 - First version.
* version 1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson)
* *
* Permission to use, copy, modify, and distribute this software and * Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted, * its documentation for any purpose and without fee is hereby granted,
@@ -18,6 +19,7 @@
#include <mem.h> #include <mem.h>
#include <fcntl.h> #include <fcntl.h>
#endif #endif
#include <zlib.h>
#ifndef BOOL #ifndef BOOL
#define BOOL unsigned char #define BOOL unsigned char
@@ -49,7 +51,8 @@
int main (int argc, char *argv[]); int main (int argc, char *argv[]);
void usage (); void usage ();
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha); BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
BOOL alpha);
void get_token(FILE *pnm_file, char *token); void get_token(FILE *pnm_file, char *token);
png_uint_32 get_data (FILE *pnm_file, int depth); png_uint_32 get_data (FILE *pnm_file, int depth);
png_uint_32 get_value (FILE *pnm_file, int depth); png_uint_32 get_value (FILE *pnm_file, int depth);
@@ -175,7 +178,8 @@ void usage()
fprintf (stderr, " or: ... | pnm2png [options]\n"); fprintf (stderr, " or: ... | pnm2png [options]\n");
fprintf (stderr, "Options:\n"); fprintf (stderr, "Options:\n");
fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n"); fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n");
fprintf (stderr, " -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n"); fprintf (stderr,
" -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n");
fprintf (stderr, " -h | -? print this help-information\n"); fprintf (stderr, " -h | -? print this help-information\n");
} }
@@ -183,29 +187,36 @@ void usage()
* pnm2png * pnm2png
*/ */
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha) BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
BOOL alpha)
{ {
png_struct *png_ptr = NULL; png_struct *png_ptr = NULL;
png_info *info_ptr = NULL; png_info *info_ptr = NULL;
png_byte *png_pixels = NULL; png_byte *png_pixels = NULL;
png_byte **row_pointers = NULL; png_byte **row_pointers = NULL;
png_byte *pix_ptr = NULL; png_byte *pix_ptr = NULL;
png_uint_32 row_bytes; volatile png_uint_32 row_bytes;
char type_token[16]; char type_token[16];
char width_token[16]; char width_token[16];
char height_token[16]; char height_token[16];
char maxval_token[16]; char maxval_token[16];
int color_type; volatile int color_type=1;
png_uint_32 width, alpha_width; unsigned long ul_width=0, ul_alpha_width=0;
png_uint_32 height, alpha_height; unsigned long ul_height=0, ul_alpha_height=0;
unsigned long ul_maxval=0;
volatile png_uint_32 width=0, height=0;
volatile png_uint_32 alpha_width=0, alpha_height=0;
png_uint_32 maxval; png_uint_32 maxval;
int bit_depth = 0; volatile int bit_depth = 0;
int channels; int channels=0;
int alpha_depth = 0; int alpha_depth = 0;
int alpha_present; int alpha_present=0;
int row, col; int row, col;
BOOL raw, alpha_raw = FALSE; BOOL raw, alpha_raw = FALSE;
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
BOOL packed_bitmap = FALSE;
#endif
png_uint_32 tmp16; png_uint_32 tmp16;
int i; int i;
@@ -218,20 +229,36 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
} }
else if ((type_token[1] == '1') || (type_token[1] == '4')) else if ((type_token[1] == '1') || (type_token[1] == '4'))
{ {
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
raw = (type_token[1] == '4'); raw = (type_token[1] == '4');
color_type = PNG_COLOR_TYPE_GRAY; color_type = PNG_COLOR_TYPE_GRAY;
get_token(pnm_file, width_token);
sscanf (width_token, "%lu", &ul_width);
width = (png_uint_32) ul_width;
get_token(pnm_file, height_token);
sscanf (height_token, "%lu", &ul_height);
height = (png_uint_32) ul_height;
bit_depth = 1; bit_depth = 1;
packed_bitmap = TRUE;
#else
fprintf (stderr, "PNM2PNG built without PNG_WRITE_INVERT_SUPPORTED and \n");
fprintf (stderr, "PNG_WRITE_PACK_SUPPORTED can't read PBM (P1,P4) files\n");
#endif
} }
else if ((type_token[1] == '2') || (type_token[1] == '5')) else if ((type_token[1] == '2') || (type_token[1] == '5'))
{ {
raw = (type_token[1] == '5'); raw = (type_token[1] == '5');
color_type = PNG_COLOR_TYPE_GRAY; color_type = PNG_COLOR_TYPE_GRAY;
get_token(pnm_file, width_token); get_token(pnm_file, width_token);
sscanf (width_token, "%lu", &width); sscanf (width_token, "%lu", &ul_width);
width = (png_uint_32) ul_width;
get_token(pnm_file, height_token); get_token(pnm_file, height_token);
sscanf (height_token, "%lu", &height); sscanf (height_token, "%lu", &ul_height);
height = (png_uint_32) ul_height;
get_token(pnm_file, maxval_token); get_token(pnm_file, maxval_token);
sscanf (maxval_token, "%lu", &maxval); sscanf (maxval_token, "%lu", &ul_maxval);
maxval = (png_uint_32) ul_maxval;
if (maxval <= 1) if (maxval <= 1)
bit_depth = 1; bit_depth = 1;
else if (maxval <= 3) else if (maxval <= 3)
@@ -248,11 +275,14 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
raw = (type_token[1] == '6'); raw = (type_token[1] == '6');
color_type = PNG_COLOR_TYPE_RGB; color_type = PNG_COLOR_TYPE_RGB;
get_token(pnm_file, width_token); get_token(pnm_file, width_token);
sscanf (width_token, "%lu", &width); sscanf (width_token, "%lu", &ul_width);
width = (png_uint_32) ul_width;
get_token(pnm_file, height_token); get_token(pnm_file, height_token);
sscanf (height_token, "%lu", &height); sscanf (height_token, "%lu", &ul_height);
height = (png_uint_32) ul_height;
get_token(pnm_file, maxval_token); get_token(pnm_file, maxval_token);
sscanf (maxval_token, "%lu", &maxval); sscanf (maxval_token, "%lu", &ul_maxval);
maxval = (png_uint_32) ul_maxval;
if (maxval <= 1) if (maxval <= 1)
bit_depth = 1; bit_depth = 1;
else if (maxval <= 3) else if (maxval <= 3)
@@ -287,15 +317,18 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
{ {
alpha_raw = (type_token[1] == '5'); alpha_raw = (type_token[1] == '5');
get_token(alpha_file, width_token); get_token(alpha_file, width_token);
sscanf (width_token, "%lu", &alpha_width); sscanf (width_token, "%lu", &ul_alpha_width);
alpha_width=(png_uint_32) ul_alpha_width;
if (alpha_width != width) if (alpha_width != width)
return FALSE; return FALSE;
get_token(alpha_file, height_token); get_token(alpha_file, height_token);
sscanf (height_token, "%lu", &alpha_height); sscanf (height_token, "%lu", &ul_alpha_height);
alpha_height = (png_uint_32) ul_alpha_height;
if (alpha_height != height) if (alpha_height != height)
return FALSE; return FALSE;
get_token(alpha_file, maxval_token); get_token(alpha_file, maxval_token);
sscanf (maxval_token, "%lu", &maxval); sscanf (maxval_token, "%lu", &ul_maxval);
maxval = (png_uint_32) ul_maxval;
if (maxval <= 1) if (maxval <= 1)
alpha_depth = 1; alpha_depth = 1;
else if (maxval <= 3) else if (maxval <= 3)
@@ -324,76 +357,108 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
channels = 3; channels = 3;
else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
channels = 4; channels = 4;
#if 0
else else
channels = 0; /* should not happen */ channels = 0; /* cannot happen */
#endif
alpha_present = (channels - 1) % 2; alpha_present = (channels - 1) % 2;
/* row_bytes is the width x number of channels x (bit-depth / 8) */ #if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); if (packed_bitmap)
/* row data is as many bytes as can fit width x channels x bit_depth */
row_bytes = (width * channels * bit_depth + 7) / 8;
else
#endif
/* row_bytes is the width x number of channels x (bit-depth / 8) */
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) if ((png_pixels = (png_byte *)
malloc (row_bytes * height * sizeof (png_byte))) == NULL)
return FALSE; return FALSE;
/* read data from PNM file */ /* read data from PNM file */
pix_ptr = png_pixels; pix_ptr = png_pixels;
for (row = 0; row < height; row++) for (row = 0; row < (int) height; row++)
{ {
for (col = 0; col < width; col++) #if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
if (packed_bitmap) {
for (i = 0; i < (int) row_bytes; i++)
/* png supports this format natively so no conversion is needed */
*pix_ptr++ = get_data (pnm_file, 8);
} else
#endif
{ {
for (i = 0; i < (channels - alpha_present); i++) for (col = 0; col < (int) width; col++)
{ {
if (raw) for (i = 0; i < (channels - alpha_present); i++)
*pix_ptr++ = get_data (pnm_file, bit_depth); {
else if (raw)
if (bit_depth <= 8) *pix_ptr++ = get_data (pnm_file, bit_depth);
*pix_ptr++ = get_value (pnm_file, bit_depth);
else else
{ if (bit_depth <= 8)
tmp16 = get_value (pnm_file, bit_depth); *pix_ptr++ = get_value (pnm_file, bit_depth);
*pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF); else
pix_ptr++; {
*pix_ptr = (png_byte) (tmp16 & 0xFF); tmp16 = get_value (pnm_file, bit_depth);
pix_ptr++; *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
} pix_ptr++;
} *pix_ptr = (png_byte) (tmp16 & 0xFF);
pix_ptr++;
}
}
if (alpha) /* read alpha-channel from pgm file */ if (alpha) /* read alpha-channel from pgm file */
{ {
if (alpha_raw) if (alpha_raw)
*pix_ptr++ = get_data (alpha_file, alpha_depth); *pix_ptr++ = get_data (alpha_file, alpha_depth);
else
if (alpha_depth <= 8)
*pix_ptr++ = get_value (alpha_file, bit_depth);
else else
{ if (alpha_depth <= 8)
tmp16 = get_value (alpha_file, bit_depth); *pix_ptr++ = get_value (alpha_file, bit_depth);
*pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF); else
*pix_ptr++ = (png_byte) (tmp16 & 0xFF); {
} tmp16 = get_value (alpha_file, bit_depth);
} /* if alpha */ *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
*pix_ptr++ = (png_byte) (tmp16 & 0xFF);
}
} /* if alpha */
} /* if packed_bitmap */
} /* end for col */ } /* end for col */
} /* end for row */ } /* end for row */
/* prepare the standard PNG structures */ /* prepare the standard PNG structures */
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_ptr = png_create_write_struct (png_get_libpng_ver(NULL), NULL, NULL,
NULL);
if (!png_ptr) if (!png_ptr)
{ {
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
info_ptr = png_create_info_struct (png_ptr); info_ptr = png_create_info_struct (png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
if (packed_bitmap == TRUE)
{
png_set_packing (png_ptr);
png_set_invert_mono (png_ptr);
}
#endif
/* setjmp() must be called in every function that calls a PNG-reading libpng function */ /* setjmp() must be called in every function that calls a PNG-reading libpng function */
if (setjmp (png_jmpbuf(png_ptr))) if (setjmp (png_jmpbuf(png_ptr)))
{ {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, &info_ptr);
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
@@ -411,25 +476,28 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
/* if needed we will allocate memory for an new array of row-pointers */ /* if needed we will allocate memory for an new array of row-pointers */
if (row_pointers == (unsigned char**) NULL) if (row_pointers == (unsigned char**) NULL)
{ {
if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) if ((row_pointers = (png_byte **)
malloc (height * sizeof (png_bytep))) == NULL)
{ {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, &info_ptr);
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
} }
/* set the individual row_pointers to point at the correct offsets */ /* set the individual row_pointers to point at the correct offsets */
for (i = 0; i < (height); i++) for (i = 0; i < (int) height; i++)
row_pointers[i] = png_pixels + i * row_bytes; row_pointers[i] = png_pixels + i * row_bytes;
/* write out the entire image data in one call */ /* write out the entire image data in one call */
png_write_image (png_ptr, row_pointers); png_write_image (png_ptr, row_pointers);
/* write the additional chuncks to the PNG file (not really needed) */ /* write the additional chunks to the PNG file (not really needed) */
png_write_end (png_ptr, info_ptr); png_write_end (png_ptr, info_ptr);
/* clean up after the write, and free any memory allocated */ /* clean up after the write, and free any memory allocated */
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, &info_ptr);
if (row_pointers != (unsigned char**) NULL) if (row_pointers != (unsigned char**) NULL)
free (row_pointers); free (row_pointers);
@@ -446,19 +514,32 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
void get_token(FILE *pnm_file, char *token) void get_token(FILE *pnm_file, char *token)
{ {
int i = 0; int i = 0;
int ret;
/* remove white-space */ /* remove white-space and comment lines */
do do
{ {
token[i] = (unsigned char) fgetc (pnm_file); ret = fgetc(pnm_file);
if (ret == '#') {
/* the rest of this line is a comment */
do
{
ret = fgetc(pnm_file);
}
while ((ret != '\n') && (ret != '\r') && (ret != EOF));
}
if (ret == EOF) break;
token[i] = (unsigned char) ret;
} }
while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' ')); while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' '));
/* read string */ /* read string */
do do
{ {
ret = fgetc(pnm_file);
if (ret == EOF) break;
i++; i++;
token[i] = (unsigned char) fgetc (pnm_file); token[i] = (unsigned char) ret;
} }
while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' ')); while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' '));
@@ -510,6 +591,7 @@ png_uint_32 get_value (FILE *pnm_file, int depth)
{ {
static png_uint_32 mask = 0; static png_uint_32 mask = 0;
png_byte token[16]; png_byte token[16];
unsigned long ul_ret_value;
png_uint_32 ret_value; png_uint_32 ret_value;
int i = 0; int i = 0;
@@ -518,7 +600,8 @@ png_uint_32 get_value (FILE *pnm_file, int depth)
mask = (mask << 1) | 0x01; mask = (mask << 1) | 0x01;
get_token (pnm_file, (char *) token); get_token (pnm_file, (char *) token);
sscanf ((const char *) token, "%lu", &ret_value); sscanf ((const char *) token, "%lu", &ul_ret_value);
ret_value = (png_uint_32) ul_ret_value;
ret_value &= mask; ret_value &= mask;