summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Bowler <jbowler@acm.org>2011-11-16 16:39:16 -0600
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2011-11-16 16:39:16 -0600
commit4fa96a42f752bd70958eaf2635de7e0a875f13a2 (patch)
treed55d23c534d5811f9702c1bc6df5c90c71399ff0
parentc2d8399581bc3b2b87172e223835cbfd1fd2555e (diff)
downloadlibpng-4fa96a42f752bd70958eaf2635de7e0a875f13a2.tar.gz
[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.
-rw-r--r--ANNOUNCE6
-rw-r--r--png.c4
-rw-r--r--pngerror.c11
-rw-r--r--pngpriv.h26
-rw-r--r--pngread.c26
-rw-r--r--pngwrite.c34
6 files changed, 76 insertions, 31 deletions
diff --git a/ANNOUNCE b/ANNOUNCE
index 83fb03a63..661151a88 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -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
diff --git a/png.c b/png.c
index b55eae9a1..14ab048bd 100644
--- a/png.c
+++ b/png.c
@@ -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. */
diff --git a/pngerror.c b/pngerror.c
index 74f8cc845..d09bcba24 100644
--- a/pngerror.c
+++ b/pngerror.c
@@ -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)
diff --git a/pngpriv.h b/pngpriv.h
index 04cf55234..6f6a85af8 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -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.)
diff --git a/pngread.c b/pngread.c
index 01dc75291..e55ec73fa 100644
--- a/pngread.c
+++ b/pngread.c
@@ -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);
diff --git a/pngwrite.c b/pngwrite.c
index fad6cc670..41cba812b 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -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;