mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
pngminus: Improve and modernize the PNG processing
Improve and modernize png2pnm.c: * Remove the explicit reading of the input PNG file signature. Libpng is now able to read it, check it, and issue an appropriate error message in case of magic number mismatch or file corruption. (See the function `png_read_sig`.) * Remove the explicit allocation and dealocation of the image data. Libpng is now able to manage all the image data automatically. (See the function `png_read_png`.) * Specify the needed image transformations without a-priori checking the image type for applicability. * Use the `png_set_expand_gray_1_2_4_to_8` transformation. Since libpng version 1.2.9, this transformation (if needed) must be enabled separately from `png_set_expand`. Improve and modernize pnm2png.c: * Modify the allocation of image data, in order to match libpng's internal allocation model. * Transfer the ownership of the image data from the `pnm2png` function to libpng, which will manage and dealocate it at the right time. (See the functions `png_set_image_rows` and `png_data_freer`.) Refactor, clean up, etc.
This commit is contained in:
parent
abb8d4a71f
commit
bdbbcaa457
@ -3,7 +3,7 @@ pnm2png / png2pnm --- conversion from PBM/PGM/PPM-file to PNG-file
|
|||||||
copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
|
copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
|
||||||
|
|
||||||
version 1.0 - 1999.10.15 - First version.
|
version 1.0 - 1999.10.15 - First version.
|
||||||
1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson)
|
1.1 - 2015.07.29 - Fix memory leaks (Glenn Randers-Pehrson)
|
||||||
1.2 - 2017.04.22 - Add buffer-size check
|
1.2 - 2017.04.22 - Add buffer-size check
|
||||||
1.3 - 2017.08.24 - Fix potential overflow in buffer-size check
|
1.3 - 2017.08.24 - Fix potential overflow in buffer-size check
|
||||||
(Glenn Randers-Pehrson)
|
(Glenn Randers-Pehrson)
|
||||||
@ -11,3 +11,4 @@ version 1.0 - 1999.10.15 - First version.
|
|||||||
1.5 - 2018.08.05 - Fix buffer overflow in tokenizer (Cosmin Truta)
|
1.5 - 2018.08.05 - Fix buffer overflow in tokenizer (Cosmin Truta)
|
||||||
1.6 - 2018.08.05 - Improve portability and fix style (Cosmin Truta)
|
1.6 - 2018.08.05 - Improve portability and fix style (Cosmin Truta)
|
||||||
1.7 - 2019.01.22 - Change license to MIT (Willem van Schaik)
|
1.7 - 2019.01.22 - Change license to MIT (Willem van Schaik)
|
||||||
|
1.8 - 2024.01.08 - Fix, improve, modernize (Cosmin Truta)
|
||||||
|
@ -20,11 +20,6 @@
|
|||||||
#define FALSE ((BOOL) 0)
|
#define FALSE ((BOOL) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make png2pnm verbose so we can find problems (needs to be before png.h) */
|
|
||||||
#ifndef PNG_DEBUG
|
|
||||||
#define PNG_DEBUG 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
@ -33,6 +28,9 @@ int main (int argc, char *argv[]);
|
|||||||
void usage ();
|
void usage ();
|
||||||
BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
||||||
BOOL raw, BOOL alpha);
|
BOOL raw, BOOL alpha);
|
||||||
|
BOOL png2pnm_internal (png_struct *png_ptr, png_info *info_ptr,
|
||||||
|
FILE *pnm_file, FILE *alpha_file,
|
||||||
|
BOOL raw, BOOL alpha);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main
|
* main
|
||||||
@ -163,35 +161,11 @@ void usage ()
|
|||||||
BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
||||||
BOOL raw, BOOL alpha)
|
BOOL raw, BOOL alpha)
|
||||||
{
|
{
|
||||||
png_struct *png_ptr = NULL;
|
png_struct *png_ptr;
|
||||||
png_info *info_ptr = NULL;
|
png_info *info_ptr;
|
||||||
png_byte buf[8];
|
BOOL ret;
|
||||||
png_byte *png_pixels = NULL;
|
|
||||||
png_byte **row_pointers = NULL;
|
|
||||||
png_byte *pix_ptr = NULL;
|
|
||||||
png_uint_32 row_bytes;
|
|
||||||
|
|
||||||
png_uint_32 width;
|
/* initialize the libpng structures for reading from png_file */
|
||||||
png_uint_32 height;
|
|
||||||
int bit_depth;
|
|
||||||
int channels;
|
|
||||||
int color_type;
|
|
||||||
int alpha_present;
|
|
||||||
int row, col;
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
long dep_16;
|
|
||||||
|
|
||||||
/* read and check signature in PNG file */
|
|
||||||
ret = fread (buf, 1, 8, png_file);
|
|
||||||
if (ret != 8)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
ret = png_sig_cmp (buf, 0, 8);
|
|
||||||
if (ret != 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* create png and info structures */
|
|
||||||
|
|
||||||
png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),
|
png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
@ -208,33 +182,49 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||||||
if (setjmp (png_jmpbuf (png_ptr)))
|
if (setjmp (png_jmpbuf (png_ptr)))
|
||||||
{
|
{
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||||
return FALSE;
|
return FALSE; /* generic libpng error */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set up the input control for C streams */
|
|
||||||
png_init_io (png_ptr, png_file);
|
png_init_io (png_ptr, png_file);
|
||||||
png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */
|
|
||||||
|
|
||||||
/* read the file information */
|
/* do the actual conversion */
|
||||||
png_read_info (png_ptr, info_ptr);
|
ret = png2pnm_internal (png_ptr, info_ptr, pnm_file, alpha_file, raw, alpha);
|
||||||
|
|
||||||
/* get size and bit-depth of the PNG-image */
|
/* clean up the libpng structures and their internally-managed data */
|
||||||
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||||
NULL, NULL, NULL);
|
|
||||||
|
|
||||||
/* set-up the transformations */
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* transform paletted images into full-color rgb */
|
/*
|
||||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
* png2pnm_internal
|
||||||
png_set_expand (png_ptr);
|
*/
|
||||||
/* expand images to bit-depth 8 (only applicable for grayscale images) */
|
|
||||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
|
||||||
png_set_expand (png_ptr);
|
|
||||||
/* transform transparency maps into full alpha-channel */
|
|
||||||
if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
|
|
||||||
png_set_expand (png_ptr);
|
|
||||||
|
|
||||||
#ifdef NJET
|
BOOL png2pnm_internal (png_struct *png_ptr, png_info *info_ptr,
|
||||||
|
FILE *pnm_file, FILE *alpha_file,
|
||||||
|
BOOL raw, BOOL alpha)
|
||||||
|
{
|
||||||
|
png_byte **row_pointers;
|
||||||
|
png_byte *pix_ptr;
|
||||||
|
png_uint_32 width;
|
||||||
|
png_uint_32 height;
|
||||||
|
int bit_depth;
|
||||||
|
int channels;
|
||||||
|
int color_type;
|
||||||
|
int alpha_present;
|
||||||
|
png_uint_32 row, col, i;
|
||||||
|
long dep_16;
|
||||||
|
|
||||||
|
/* set up the image transformations that are necessary for the PNM format */
|
||||||
|
|
||||||
|
/* set up (if applicable) the expansion of paletted images to full-color rgb,
|
||||||
|
* and the expansion of transparency maps to full alpha-channel */
|
||||||
|
png_set_expand (png_ptr);
|
||||||
|
|
||||||
|
/* set up (if applicable) the expansion of grayscale images to bit-depth 8 */
|
||||||
|
png_set_expand_gray_1_2_4_to_8 (png_ptr);
|
||||||
|
|
||||||
|
#ifdef NJET /* FIXME */
|
||||||
/* downgrade 16-bit images to 8-bit */
|
/* downgrade 16-bit images to 8-bit */
|
||||||
if (bit_depth == 16)
|
if (bit_depth == 16)
|
||||||
png_set_strip_16 (png_ptr);
|
png_set_strip_16 (png_ptr);
|
||||||
@ -247,16 +237,14 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||||||
png_set_gamma (png_ptr, (double) 2.2, file_gamma);
|
png_set_gamma (png_ptr, (double) 2.2, file_gamma);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* all transformations have been registered; now update info_ptr data,
|
/* read the image file, with all of the above image transforms applied */
|
||||||
* get rowbytes and channels, and allocate image memory */
|
png_read_png (png_ptr, info_ptr, 0, NULL);
|
||||||
|
|
||||||
png_read_update_info (png_ptr, info_ptr);
|
/* get the image size, bit-depth and color-type */
|
||||||
|
|
||||||
/* get the new color-type and bit-depth (after expansion/stripping) */
|
|
||||||
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
/* calculate new number of channels and store alpha-presence */
|
/* calculate the number of channels and store alpha-presence */
|
||||||
if (color_type == PNG_COLOR_TYPE_GRAY)
|
if (color_type == PNG_COLOR_TYPE_GRAY)
|
||||||
channels = 1;
|
channels = 1;
|
||||||
else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||||
@ -273,47 +261,12 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||||||
if (alpha && !alpha_present)
|
if (alpha && !alpha_present)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "PNG2PNM\n");
|
fprintf (stderr, "PNG2PNM\n");
|
||||||
fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n");
|
fprintf (stderr, "Warning: no alpha channel in PNG file\n");
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* row_bytes is the width x number of channels x (bit-depth / 8) */
|
|
||||||
row_bytes = png_get_rowbytes (png_ptr, info_ptr);
|
|
||||||
|
|
||||||
if ((row_bytes == 0) ||
|
|
||||||
((size_t) height > (size_t) (-1) / (size_t) row_bytes))
|
|
||||||
{
|
|
||||||
/* too big */
|
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if ((png_pixels = (png_byte *)
|
|
||||||
malloc ((size_t) row_bytes * (size_t) height)) == NULL)
|
|
||||||
{
|
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((row_pointers = (png_byte **)
|
/* get address of internally-allocated image data */
|
||||||
malloc ((size_t) height * sizeof (png_byte *))) == NULL)
|
row_pointers = png_get_rows (png_ptr, info_ptr);
|
||||||
{
|
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
|
||||||
free (png_pixels);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the individual row_pointers to point at the correct offsets */
|
|
||||||
for (i = 0; i < ((int) height); i++)
|
|
||||||
row_pointers[i] = png_pixels + i * row_bytes;
|
|
||||||
|
|
||||||
/* now we can go ahead and just read the whole image */
|
|
||||||
png_read_image (png_ptr, row_pointers);
|
|
||||||
|
|
||||||
/* read rest of file, and get additional chunks in info_ptr - REQUIRED */
|
|
||||||
png_read_end (png_ptr, info_ptr);
|
|
||||||
|
|
||||||
/* clean up after the read, and free any memory allocated - REQUIRED */
|
|
||||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
|
||||||
|
|
||||||
/* write header of PNM file */
|
/* write header of PNM file */
|
||||||
|
|
||||||
@ -344,13 +297,13 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write data to PNM file */
|
/* write data to PNM file */
|
||||||
pix_ptr = png_pixels;
|
|
||||||
|
|
||||||
for (row = 0; row < (int) height; row++)
|
for (row = 0; row < height; row++)
|
||||||
{
|
{
|
||||||
for (col = 0; col < (int) width; col++)
|
pix_ptr = row_pointers[row];
|
||||||
|
for (col = 0; col < width; col++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < (channels - alpha_present); i++)
|
for (i = 0; i < (png_uint_32) (channels - alpha_present); i++)
|
||||||
{
|
{
|
||||||
if (raw)
|
if (raw)
|
||||||
{
|
{
|
||||||
@ -416,10 +369,5 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||||||
fprintf (pnm_file, "\n");
|
fprintf (pnm_file, "\n");
|
||||||
} /* end for row */
|
} /* end for row */
|
||||||
|
|
||||||
if (row_pointers != NULL)
|
|
||||||
free (row_pointers);
|
|
||||||
if (png_pixels != NULL)
|
|
||||||
free (png_pixels);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} /* end of source */
|
} /* end of source */
|
||||||
|
@ -21,11 +21,6 @@
|
|||||||
#define FALSE ((BOOL) 0)
|
#define FALSE ((BOOL) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make pnm2png verbose so we can find problems (needs to be before png.h) */
|
|
||||||
#ifndef PNG_DEBUG
|
|
||||||
#define PNG_DEBUG 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
@ -34,6 +29,9 @@ int main (int argc, char *argv[]);
|
|||||||
void usage ();
|
void usage ();
|
||||||
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
||||||
BOOL interlace, BOOL alpha);
|
BOOL interlace, BOOL alpha);
|
||||||
|
BOOL pnm2png_internal (png_struct *png_ptr, png_info *info_ptr,
|
||||||
|
FILE *pnm_file, FILE *alpha_file,
|
||||||
|
BOOL interlace, BOOL alpha);
|
||||||
int fscan_pnm_magic (FILE *pnm_file, char *magic_buf, size_t magic_buf_size);
|
int fscan_pnm_magic (FILE *pnm_file, char *magic_buf, size_t magic_buf_size);
|
||||||
int fscan_pnm_token (FILE *pnm_file, char *token_buf, size_t token_buf_size);
|
int fscan_pnm_token (FILE *pnm_file, char *token_buf, size_t token_buf_size);
|
||||||
int fscan_pnm_uint_32 (FILE *pnm_file, png_uint_32 *num_ptr);
|
int fscan_pnm_uint_32 (FILE *pnm_file, png_uint_32 *num_ptr);
|
||||||
@ -166,11 +164,52 @@ void usage ()
|
|||||||
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
||||||
BOOL interlace, BOOL alpha)
|
BOOL interlace, BOOL alpha)
|
||||||
{
|
{
|
||||||
png_struct *png_ptr = NULL;
|
png_struct *png_ptr;
|
||||||
png_info *info_ptr = NULL;
|
png_info *info_ptr;
|
||||||
png_byte *png_pixels = NULL;
|
BOOL ret;
|
||||||
png_byte **row_pointers = NULL;
|
|
||||||
png_byte *pix_ptr = NULL;
|
/* initialize the libpng structures for writing to png_file */
|
||||||
|
|
||||||
|
png_ptr = png_create_write_struct (png_get_libpng_ver(NULL),
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
if (!png_ptr)
|
||||||
|
return FALSE; /* out of memory */
|
||||||
|
|
||||||
|
info_ptr = png_create_info_struct (png_ptr);
|
||||||
|
if (!info_ptr)
|
||||||
|
{
|
||||||
|
png_destroy_write_struct (&png_ptr, NULL);
|
||||||
|
return FALSE; /* out of memory */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp (png_jmpbuf (png_ptr)))
|
||||||
|
{
|
||||||
|
png_destroy_write_struct (&png_ptr, &info_ptr);
|
||||||
|
return FALSE; /* generic libpng error */
|
||||||
|
}
|
||||||
|
|
||||||
|
png_init_io (png_ptr, png_file);
|
||||||
|
|
||||||
|
/* do the actual conversion */
|
||||||
|
ret = pnm2png_internal (png_ptr, info_ptr,
|
||||||
|
pnm_file, alpha_file, interlace, alpha);
|
||||||
|
|
||||||
|
/* clean up the libpng structures and their internally-managed data */
|
||||||
|
png_destroy_write_struct (&png_ptr, &info_ptr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pnm2png_internal
|
||||||
|
*/
|
||||||
|
|
||||||
|
BOOL pnm2png_internal (png_struct *png_ptr, png_info *info_ptr,
|
||||||
|
FILE *pnm_file, FILE *alpha_file,
|
||||||
|
BOOL interlace, BOOL alpha)
|
||||||
|
{
|
||||||
|
png_byte **row_pointers;
|
||||||
|
png_byte *pix_ptr;
|
||||||
int bit_depth;
|
int bit_depth;
|
||||||
int color_type;
|
int color_type;
|
||||||
int channels;
|
int channels;
|
||||||
@ -336,18 +375,27 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||||||
/* too big */
|
/* too big */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ((png_pixels = (png_byte *)
|
|
||||||
malloc ((size_t) row_bytes * (size_t) height)) == NULL)
|
/* allocate the rows using the same memory layout as libpng, and transfer
|
||||||
|
* their ownership to libpng, with the responsibility to clean everything up;
|
||||||
|
* please note the use of png_calloc instead of png_malloc */
|
||||||
|
row_pointers = (png_byte **)
|
||||||
|
png_calloc (png_ptr, height * sizeof (png_byte *));
|
||||||
|
png_set_rows (png_ptr, info_ptr, row_pointers);
|
||||||
|
png_data_freer (png_ptr, info_ptr, PNG_DESTROY_WILL_FREE_DATA, PNG_FREE_ALL);
|
||||||
|
for (row = 0; row < height; row++)
|
||||||
{
|
{
|
||||||
/* out of memory */
|
/* the individual rows should only be allocated after all the previous
|
||||||
return FALSE;
|
* steps completed successfully, because libpng must handle correctly
|
||||||
|
* any image allocation left incomplete after an out-of-memory error */
|
||||||
|
row_pointers[row] = (png_byte *) png_malloc (png_ptr, row_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read data from PNM file */
|
/* read the data from PNM file */
|
||||||
pix_ptr = png_pixels;
|
|
||||||
|
|
||||||
for (row = 0; row < height; row++)
|
for (row = 0; row < height; row++)
|
||||||
{
|
{
|
||||||
|
pix_ptr = row_pointers[row];
|
||||||
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||||
if (packed_bitmap)
|
if (packed_bitmap)
|
||||||
{
|
{
|
||||||
@ -413,21 +461,10 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||||||
} /* end for col */
|
} /* end for col */
|
||||||
} /* end for row */
|
} /* end for row */
|
||||||
|
|
||||||
/* prepare the standard PNG structures */
|
/* we're going to write more or less the same PNG as the input file */
|
||||||
png_ptr = png_create_write_struct (png_get_libpng_ver(NULL),
|
png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,
|
||||||
NULL, NULL, NULL);
|
(!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,
|
||||||
if (!png_ptr)
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||||
{
|
|
||||||
free (png_pixels);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
info_ptr = png_create_info_struct (png_ptr);
|
|
||||||
if (!info_ptr)
|
|
||||||
{
|
|
||||||
png_destroy_write_struct (&png_ptr, NULL);
|
|
||||||
free (png_pixels);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||||
if (packed_bitmap == TRUE)
|
if (packed_bitmap == TRUE)
|
||||||
@ -437,54 +474,15 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (setjmp (png_jmpbuf (png_ptr)))
|
|
||||||
{
|
|
||||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
|
||||||
free (png_pixels);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the png structure */
|
|
||||||
png_init_io (png_ptr, png_file);
|
|
||||||
|
|
||||||
/* we're going to write more or less the same PNG as the input file */
|
|
||||||
png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,
|
|
||||||
(!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,
|
|
||||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
|
||||||
|
|
||||||
/* write the file header information */
|
/* write the file header information */
|
||||||
png_write_info (png_ptr, info_ptr);
|
png_write_info (png_ptr, info_ptr);
|
||||||
|
|
||||||
/* if needed we will allocate memory for an new array of row-pointers */
|
|
||||||
if (row_pointers == NULL)
|
|
||||||
{
|
|
||||||
if ((row_pointers = (png_byte **)
|
|
||||||
malloc (height * sizeof (png_byte *))) == NULL)
|
|
||||||
{
|
|
||||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
|
||||||
free (png_pixels);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the individual row_pointers to point at the correct offsets */
|
|
||||||
for (i = 0; i < height; i++)
|
|
||||||
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 chunks 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 */
|
|
||||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
|
||||||
|
|
||||||
if (row_pointers != NULL)
|
|
||||||
free (row_pointers);
|
|
||||||
if (png_pixels != NULL)
|
|
||||||
free (png_pixels);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} /* end of pnm2png */
|
} /* end of pnm2png */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user