[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
in the simplified APIs themselves and to some bugs in compose and rgb to
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:
(subscription required; visit

4
png.c
View File

@ -3028,7 +3028,7 @@ png_byte png_sRGB_delta[512] =
static int
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_control c;
@ -3042,7 +3042,7 @@ png_image_free_function(png_voidp argument)
# ifdef PNG_STDIO_SUPPORTED
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;
/* 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_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)
* 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);
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)
longjmp(image->opaque->error_buf, 1);
longjmp(png_control_jmp_buf(image->opaque), 1);
/* 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 */
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. */
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)
#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
/* 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
* debatable if they should be exported at all. In the future, when it
* is possible to have run-time registry of chunk-handling functions,
* 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
/* 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 */
} 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
* errors that might occur. Returns true on success, false on failure (either
* 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)
{
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)
{
@ -1384,7 +1385,7 @@ png_image_format(png_structp png_ptr, png_infop info_ptr)
static int
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_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)
{
png_imagep image = png_ptr->io_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
if (image != NULL)
{
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
* 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->png_ptr->io_ptr = image;
image->opaque->png_ptr->read_data_fn = png_image_memory_read;
@ -1581,7 +1582,8 @@ typedef struct
static int
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_structp png_ptr = image->opaque->png_ptr;
png_byte interlace_type = png_ptr->interlaced;
@ -1707,7 +1709,8 @@ png_image_read_composite(png_voidp argument)
static int
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_structp png_ptr = image->opaque->png_ptr;
png_infop info_ptr = image->opaque->info_ptr;
@ -1965,7 +1968,8 @@ png_image_read_background(png_voidp argument)
static int
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_structp png_ptr = image->opaque->png_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.
*/
{
png_bytep first_row = display->buffer;
png_bytep first_row = png_voidcast(png_bytep, display->buffer);
ptrdiff_t row_bytes = display->row_stride;
if (linear)
@ -2366,7 +2370,8 @@ png_image_read_end(png_voidp argument)
if (do_local_compose)
{
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;
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)
{
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;
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)
{
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)
{
@ -1717,12 +1718,14 @@ typedef struct
static int
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_structp png_ptr = image->opaque->png_ptr;
png_const_uint_16p input_row = display->first_row;
png_uint_16p output_row = display->local_row;
png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
display->first_row);
png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
png_uint_16p row_end;
int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
int aindex = 0;
@ -1805,7 +1808,7 @@ png_write_image_16bit(png_voidp argument)
++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));
}
@ -1819,12 +1822,14 @@ png_write_image_16bit(png_voidp argument)
static int
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_structp png_ptr = image->opaque->png_ptr;
png_const_uint_16p input_row = display->first_row;
png_bytep output_row = display->local_row;
png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
display->first_row);
png_bytep output_row = png_voidcast(png_bytep, display->local_row);
png_uint_32 y = image->height;
int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
@ -1917,7 +1922,8 @@ png_write_image_8bit(png_voidp argument)
++out_ptr;
} /* 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));
} /* while y */
}
@ -1953,7 +1959,8 @@ png_write_image_8bit(png_voidp argument)
static int
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_structp png_ptr = image->opaque->png_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_const_bytep row = display->buffer;
png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
ptrdiff_t row_bytes = display->row_stride;
if (linear)
@ -2058,7 +2065,8 @@ png_image_write_main(png_voidp argument)
*/
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;
display->local_row = row;
@ -2080,7 +2088,7 @@ png_image_write_main(png_voidp argument)
*/
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;
png_uint_32 y = image->height;