[libpng15] Fixes for C++ compilation using g++ When libpng source is compiled

using g++. The compiler imposes C++ rules on the C source; thus it
    is desireable to make the source work with either C or C++ rules
    without throwing away useful error information.  This change adds
    png_voidcast to allow C semantic (void*) cases or the corresponding
    C++ static_cast operation, as appropriate.
This commit is contained in:
John Bowler 2011-11-16 16:39:16 -06:00 committed by Glenn Randers-Pehrson
parent c2d8399581
commit 4fa96a42f7
6 changed files with 76 additions and 31 deletions

View File

@ -78,6 +78,12 @@ Version 1.5.7beta03 [November 16, 2011]
libpng transform code. This check-in also contains fixes to various bugs libpng transform code. This check-in also contains fixes to various bugs
in the simplified APIs themselves and to some bugs in compose and rgb to in the simplified APIs themselves and to some bugs in compose and rgb to
gray (on palette) itself. gray (on palette) itself.
Fixes for C++ compilation using g++ When libpng source is compiled
using g++. The compiler imposes C++ rules on the C source; thus it
is desireable to make the source work with either C or C++ rules
without throwing away useful error information. This change adds
png_voidcast to allow C semantic (void*) cases or the corresponding
C++ static_cast operation, as appropriate.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net: Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
(subscription required; visit (subscription required; visit

4
png.c
View File

@ -3028,7 +3028,7 @@ png_byte png_sRGB_delta[512] =
static int static int
png_image_free_function(png_voidp argument) png_image_free_function(png_voidp argument)
{ {
png_imagep image = argument; png_imagep image = png_voidcast(png_imagep, argument);
png_controlp cp = image->opaque; png_controlp cp = image->opaque;
png_control c; png_control c;
@ -3042,7 +3042,7 @@ png_image_free_function(png_voidp argument)
# ifdef PNG_STDIO_SUPPORTED # ifdef PNG_STDIO_SUPPORTED
if (cp->owned_file) if (cp->owned_file)
{ {
FILE *fp = cp->png_ptr->io_ptr; FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
cp->owned_file = 0; cp->owned_file = 0;
/* Ignore errors here. */ /* Ignore errors here. */

View File

@ -684,7 +684,7 @@ PNG_FUNCTION(void /* PRIVATE */,
png_safe_error,(png_structp png_ptr, png_const_charp error_message), png_safe_error,(png_structp png_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
png_imagep image = png_ptr->error_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
/* An error is always logged here, overwriting anything (typically a warning) /* An error is always logged here, overwriting anything (typically a warning)
* that is already there: * that is already there:
@ -694,9 +694,12 @@ png_safe_error,(png_structp png_ptr, png_const_charp error_message),
png_safecat(image->message, sizeof image->message, 0, error_message); png_safecat(image->message, sizeof image->message, 0, error_message);
image->warning_or_error = 1; image->warning_or_error = 1;
/* Retrieve the jmp_buf from within the png_control */ /* Retrieve the jmp_buf from within the png_control, making this work for
* C++ compilation too is pretty tricky: C++ wants a pointer to the first
* element of a jmp_buf, but C doesn't tell us the type of that.
*/
if (image->opaque != NULL && image->opaque->error_buf != NULL) if (image->opaque != NULL && image->opaque->error_buf != NULL)
longjmp(image->opaque->error_buf, 1); longjmp(png_control_jmp_buf(image->opaque), 1);
/* Missing longjmp buffer, the following is to help debugging: */ /* Missing longjmp buffer, the following is to help debugging: */
{ {
@ -714,7 +717,7 @@ png_safe_error,(png_structp png_ptr, png_const_charp error_message),
void /* PRIVATE */ void /* PRIVATE */
png_safe_warning(png_structp png_ptr, png_const_charp warning_message) png_safe_warning(png_structp png_ptr, png_const_charp warning_message)
{ {
png_imagep image = png_ptr->error_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
/* A warning is only logged if there is no prior warning or error. */ /* A warning is only logged if there is no prior warning or error. */
if (image->warning_or_error == 0) if (image->warning_or_error == 0)

View File

@ -234,15 +234,28 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
# define png_fixed_error(s1,s2) png_err(s1) # define png_fixed_error(s1,s2) png_err(s1)
#endif #endif
/* C allows up-casts from (void*) to any pointer and (const void*) to any
* pointer to a const object. C++ regards this as a type error and requires an
* explicit, static, cast and provides the static_cast<> rune to ensure that
* const is not cast away.
*/
#ifdef __cplusplus
# define png_voidcast(type, value) static_cast<type>(value)
#else
# define png_voidcast(type, value) (value)
#endif /* __cplusplus */
#ifndef PNG_EXTERN #ifndef PNG_EXTERN
/* The functions exported by PNG_EXTERN are internal functions, which /* The functions exported by PNG_EXTERN are internal functions, which
* aren't usually used outside the library (as far as I know), so it is * aren't usually used outside the library (as far as I know), so it is
* debatable if they should be exported at all. In the future, when it * debatable if they should be exported at all. In the future, when it
* is possible to have run-time registry of chunk-handling functions, * is possible to have run-time registry of chunk-handling functions,
* some of these might be made available again. * some of these might be made available again.
# define PNG_EXTERN extern *
* 1.5.7: turned the use of 'extern' back on, since it is localized to pngpriv.h
* it should be safe now (it is unclear why it was turned off.)
*/ */
# define PNG_EXTERN # define PNG_EXTERN extern
#endif #endif
/* Some fixed point APIs are still required even if not exported because /* Some fixed point APIs are still required even if not exported because
@ -1642,6 +1655,15 @@ typedef struct png_control
unsigned int owned_file :1; /* We own the file in io_ptr */ unsigned int owned_file :1; /* We own the file in io_ptr */
} png_control; } png_control;
/* Return the pointer to the jmp_buf from a png_control: necessary because C
* does not reveal the type of the elements of jmp_buf.
*/
#ifdef __cplusplus
# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0])
#else
# define png_control_jmp_buf(pc) ((pc)->error_buf)
#endif
/* Utility to safely execute a piece of libpng code catching and logging any /* Utility to safely execute a piece of libpng code catching and logging any
* errors that might occur. Returns true on success, false on failure (either * errors that might occur. Returns true on success, false on failure (either
* of the function or as a result of a png_error.) * of the function or as a result of a png_error.)

View File

@ -1332,7 +1332,8 @@ png_image_read_init(png_imagep image)
if (info_ptr != NULL) if (info_ptr != NULL)
{ {
png_controlp control = png_malloc_warn(png_ptr, sizeof *control); png_controlp control = png_voidcast(png_controlp,
png_malloc_warn(png_ptr, sizeof *control));
if (control != NULL) if (control != NULL)
{ {
@ -1384,7 +1385,7 @@ png_image_format(png_structp png_ptr, png_infop info_ptr)
static int static int
png_image_read_header(png_voidp argument) png_image_read_header(png_voidp argument)
{ {
png_imagep image = argument; png_imagep image = png_voidcast(png_imagep, argument);
png_structp png_ptr = image->opaque->png_ptr; png_structp png_ptr = image->opaque->png_ptr;
png_infop info_ptr = image->opaque->info_ptr; png_infop info_ptr = image->opaque->info_ptr;
@ -1508,7 +1509,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
{ {
if (png_ptr != NULL) if (png_ptr != NULL)
{ {
png_imagep image = png_ptr->io_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
if (image != NULL) if (image != NULL)
{ {
png_controlp cp = image->opaque; png_controlp cp = image->opaque;
@ -1546,7 +1547,7 @@ int PNGAPI png_image_begin_read_from_memory(png_imagep image,
* store it into io_ptr. Again do this in-place to avoid calling a * store it into io_ptr. Again do this in-place to avoid calling a
* libpng function that requires error handling. * libpng function that requires error handling.
*/ */
image->opaque->memory = memory; image->opaque->memory = png_voidcast(png_const_bytep, memory);
image->opaque->size = size; image->opaque->size = size;
image->opaque->png_ptr->io_ptr = image; image->opaque->png_ptr->io_ptr = image;
image->opaque->png_ptr->read_data_fn = png_image_memory_read; image->opaque->png_ptr->read_data_fn = png_image_memory_read;
@ -1581,7 +1582,8 @@ typedef struct
static int static int
png_image_read_composite(png_voidp argument) png_image_read_composite(png_voidp argument)
{ {
png_image_read_control *display = argument; png_image_read_control *display = png_voidcast(png_image_read_control*,
argument);
png_imagep image = display->image; png_imagep image = display->image;
png_structp png_ptr = image->opaque->png_ptr; png_structp png_ptr = image->opaque->png_ptr;
png_byte interlace_type = png_ptr->interlaced; png_byte interlace_type = png_ptr->interlaced;
@ -1707,7 +1709,8 @@ png_image_read_composite(png_voidp argument)
static int static int
png_image_read_background(png_voidp argument) png_image_read_background(png_voidp argument)
{ {
png_image_read_control *display = argument; png_image_read_control *display = png_voidcast(png_image_read_control*,
argument);
png_imagep image = display->image; png_imagep image = display->image;
png_structp png_ptr = image->opaque->png_ptr; png_structp png_ptr = image->opaque->png_ptr;
png_infop info_ptr = image->opaque->info_ptr; png_infop info_ptr = image->opaque->info_ptr;
@ -1965,7 +1968,8 @@ png_image_read_background(png_voidp argument)
static int static int
png_image_read_end(png_voidp argument) png_image_read_end(png_voidp argument)
{ {
png_image_read_control *display = argument; png_image_read_control *display = png_voidcast(png_image_read_control*,
argument);
png_imagep image = display->image; png_imagep image = display->image;
png_structp png_ptr = image->opaque->png_ptr; png_structp png_ptr = image->opaque->png_ptr;
png_infop info_ptr = image->opaque->info_ptr; png_infop info_ptr = image->opaque->info_ptr;
@ -2347,7 +2351,7 @@ png_image_read_end(png_voidp argument)
* display acts as a flag. * display acts as a flag.
*/ */
{ {
png_bytep first_row = display->buffer; png_bytep first_row = png_voidcast(png_bytep, display->buffer);
ptrdiff_t row_bytes = display->row_stride; ptrdiff_t row_bytes = display->row_stride;
if (linear) if (linear)
@ -2366,7 +2370,8 @@ png_image_read_end(png_voidp argument)
if (do_local_compose) if (do_local_compose)
{ {
int result; int result;
png_bytep row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
png_get_rowbytes(png_ptr, info_ptr)));
display->local_row = row; display->local_row = row;
result = png_safe_execute(image, png_image_read_composite, display); result = png_safe_execute(image, png_image_read_composite, display);
@ -2379,7 +2384,8 @@ png_image_read_end(png_voidp argument)
else if (do_local_background == 2) else if (do_local_background == 2)
{ {
int result; int result;
png_bytep row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
png_get_rowbytes(png_ptr, info_ptr)));
display->local_row = row; display->local_row = row;
result = png_safe_execute(image, png_image_read_background, display); result = png_safe_execute(image, png_image_read_background, display);

View File

@ -1672,7 +1672,8 @@ png_image_write_init(png_imagep image)
if (info_ptr != NULL) if (info_ptr != NULL)
{ {
png_controlp control = png_malloc_warn(png_ptr, sizeof *control); png_controlp control = png_voidcast(png_controlp,
png_malloc_warn(png_ptr, sizeof *control));
if (control != NULL) if (control != NULL)
{ {
@ -1717,12 +1718,14 @@ typedef struct
static int static int
png_write_image_16bit(png_voidp argument) png_write_image_16bit(png_voidp argument)
{ {
png_image_write_control *display = argument; png_image_write_control *display = png_voidcast(png_image_write_control*,
argument);
png_imagep image = display->image; png_imagep image = display->image;
png_structp png_ptr = image->opaque->png_ptr; png_structp png_ptr = image->opaque->png_ptr;
png_const_uint_16p input_row = display->first_row; png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
png_uint_16p output_row = display->local_row; display->first_row);
png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
png_uint_16p row_end; png_uint_16p row_end;
int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1; int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
int aindex = 0; int aindex = 0;
@ -1805,7 +1808,7 @@ png_write_image_16bit(png_voidp argument)
++out_ptr; ++out_ptr;
} }
png_write_row(png_ptr, display->local_row); png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
input_row += display->row_bytes/(sizeof (png_uint_16)); input_row += display->row_bytes/(sizeof (png_uint_16));
} }
@ -1819,12 +1822,14 @@ png_write_image_16bit(png_voidp argument)
static int static int
png_write_image_8bit(png_voidp argument) png_write_image_8bit(png_voidp argument)
{ {
png_image_write_control *display = argument; png_image_write_control *display = png_voidcast(png_image_write_control*,
argument);
png_imagep image = display->image; png_imagep image = display->image;
png_structp png_ptr = image->opaque->png_ptr; png_structp png_ptr = image->opaque->png_ptr;
png_const_uint_16p input_row = display->first_row; png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
png_bytep output_row = display->local_row; display->first_row);
png_bytep output_row = png_voidcast(png_bytep, display->local_row);
png_uint_32 y = image->height; png_uint_32 y = image->height;
int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1; int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
@ -1917,7 +1922,8 @@ png_write_image_8bit(png_voidp argument)
++out_ptr; ++out_ptr;
} /* while out_ptr < row_end */ } /* while out_ptr < row_end */
png_write_row(png_ptr, display->local_row); png_write_row(png_ptr, png_voidcast(png_const_bytep,
display->local_row));
input_row += display->row_bytes/(sizeof (png_uint_16)); input_row += display->row_bytes/(sizeof (png_uint_16));
} /* while y */ } /* while y */
} }
@ -1953,7 +1959,8 @@ png_write_image_8bit(png_voidp argument)
static int static int
png_image_write_main(png_voidp argument) png_image_write_main(png_voidp argument)
{ {
png_image_write_control *display = argument; png_image_write_control *display = png_voidcast(png_image_write_control*,
argument);
png_imagep image = display->image; png_imagep image = display->image;
png_structp png_ptr = image->opaque->png_ptr; png_structp png_ptr = image->opaque->png_ptr;
png_infop info_ptr = image->opaque->info_ptr; png_infop info_ptr = image->opaque->info_ptr;
@ -2039,7 +2046,7 @@ png_image_write_main(png_voidp argument)
png_error(png_ptr, "png_write_image: unsupported transformation"); png_error(png_ptr, "png_write_image: unsupported transformation");
{ {
png_const_bytep row = display->buffer; png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
ptrdiff_t row_bytes = display->row_stride; ptrdiff_t row_bytes = display->row_stride;
if (linear) if (linear)
@ -2058,7 +2065,8 @@ png_image_write_main(png_voidp argument)
*/ */
if ((linear && alpha) || display->convert_to_8bit) if ((linear && alpha) || display->convert_to_8bit)
{ {
png_bytep row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
png_get_rowbytes(png_ptr, info_ptr)));
int result; int result;
display->local_row = row; display->local_row = row;
@ -2080,7 +2088,7 @@ png_image_write_main(png_voidp argument)
*/ */
else else
{ {
png_const_bytep row = display->first_row; png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
ptrdiff_t row_bytes = display->row_bytes; ptrdiff_t row_bytes = display->row_bytes;
png_uint_32 y = image->height; png_uint_32 y = image->height;