[libzomg] Fix build with libpng versions older than 1.5.0.
authorDavid Korth <gerbilsoft@gerbilsoft.com>
Thu, 10 Sep 2015 02:21:37 +0000 (22:21 -0400)
committerDavid Korth <gerbilsoft@gerbilsoft.com>
Thu, 10 Sep 2015 02:21:37 +0000 (22:21 -0400)
Debian-based distributions still ship with libpng-1.2, so we need
to maintain compatibility. The biggest change in libpng-1.5.0 was
the constification of pointer arguments. To work around this,
we'll cast the pointers to non-const when compiling with older
versions of libpng.

libpng doesn't actually modify the contents of the data, so it's
effectively const anyway.

Also, libpng-1.4.0 changed the definition of png_uint_32 to
unsigned int. Previously, it was unsigned long, which is the same
as unsigned int on most 32-bit systems, but is 64-bit on most
64-bit systems (other than Windows).

src/libzomg/Metadata.hpp
src/libzomg/PngReader.cpp
src/libzomg/PngWriter.cpp

index 067cb20..5f4decc 100644 (file)
 // C++ includes.
 #include <string>
 
-// PNG structs.
-// NOTE: Copied fron png.h to avoid having to include it here.
-extern "C" {
-struct png_struct_def;
-typedef struct png_struct_def png_struct;
-typedef png_struct * png_structp;
-
-struct png_info_def;
-typedef struct png_info_def png_info;
-typedef png_info * png_infop;
-}
+// libpng
+// NOTE: The PNG struct definitions changed in libpng-1.5.0.
+// Instead of doing a bunch of complicated maneuvers to get
+// it working without including png.h, just include png.h.
+#include <png.h>
 
 namespace LibZomg {
 
index c89e435..a274361 100644 (file)
@@ -175,23 +175,33 @@ int PngReaderPrivate::readFromPng(png_structp png_ptr, png_infop info_ptr,
        png_read_info(png_ptr, info_ptr);
 
        // Read the PNG image header.
+       // NOTE: libpng-1.2 defines png_uint_32 as long.
+       // libpng-1.4.0beta7 appears to redefine it to unsigned int.
+       // Since we're using unsigned int in img_data, we can't
+       // save the values directly to the struct.
+       // TODO: Conditionally use temp variables for libpng <1.4?
        int bit_depth, color_type;
+       png_uint_32 img_w, img_h;
        png_get_IHDR(png_ptr, info_ptr,
-                    &img_data->w, &img_data->h,
+                    &img_w, &img_h,
                     &bit_depth, &color_type,
                     nullptr, nullptr, nullptr);
-       if (img_data->w <= 0 || img_data->h <= 0) {
+       if (img_w <= 0 || img_h <= 0) {
                // Invalid image size.
                // TODO: Better error code?
                return -EINVAL;
        }
+       // Save the image size.
+       img_data->w = (unsigned int)img_w;
+       img_data->h = (unsigned int)img_h;
 
        // Check for pHYs.
        if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
                // TODO: Only if unit_type == PNG_RESOLUTION_UNKNOWN?
-               png_get_pHYs(png_ptr, info_ptr,
-                            &img_data->phys_x, &img_data->phys_y,
-                            nullptr);
+               png_uint_32 phys_x, phys_y;
+               png_get_pHYs(png_ptr, info_ptr, &phys_x, &phys_y, nullptr);
+               img_data->phys_x = (unsigned int)phys_x;
+               img_data->phys_y = (unsigned int)phys_y;
        } else {
                // No pHYs.
                img_data->phys_x = 0;
@@ -229,7 +239,7 @@ int PngReaderPrivate::readFromPng(png_structp png_ptr, png_infop info_ptr,
        }
 
        // Get the new PNG information.
-       png_get_IHDR(png_ptr, info_ptr, &img_data->w, &img_data->h, &bit_depth, &color_type,
+       png_get_IHDR(png_ptr, info_ptr, &img_w, &img_h, &bit_depth, &color_type,
                     nullptr, nullptr, nullptr);
 
        // Check if the image has an alpha channel.
index efb8415..2370b85 100644 (file)
 using std::string;
 using std::vector;
 
+// libpng-1.5.0 marked several function parameters as const.
+// Older versions don't have them marked as const, but they're
+// effectively const anyway.
+#if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 5)
+// libpng-1.5.0: Functions have const pointer arguments.
+#define PNG_CONST_CAST(type, ptr) (ptr)
+#else
+// libpng-1.4.x or earlier: Functions do *not* have const pointer arguments.
+#define PNG_CONST_CAST(type, ptr) const_cast<type>(ptr)
+#endif
+
 namespace LibZomg {
 
 // TODO: Convert to a static class?
@@ -274,23 +285,20 @@ int PngWriterPrivate::writeToPng(png_structp png_ptr, png_infop info_ptr,
                     );
 
        // Write the sBIT chunk.
+       static const png_color_8 sBIT_15 = {5, 5, 5, 0, 0};
+       static const png_color_8 sBIT_16 = {5, 6, 5, 0, 0};
+       static const png_color_8 sBIT_32 = {8, 8, 8, 0, 0};
        switch (img_data->bpp) {
-               case 15: {
-                       static const png_color_8 sBIT_15 = {5, 5, 5, 0, 0};
-                       png_set_sBIT(png_ptr, info_ptr, &sBIT_15);
+               case 15:
+                       png_set_sBIT(png_ptr, info_ptr, PNG_CONST_CAST(png_color_8*, &sBIT_15));
                        break;
-               }
-               case 16: {
-                       static const png_color_8 sBIT_16 = {5, 6, 5, 0, 0};
-                       png_set_sBIT(png_ptr, info_ptr, &sBIT_16);
+               case 16:
+                       png_set_sBIT(png_ptr, info_ptr, PNG_CONST_CAST(png_color_8*, &sBIT_16));
                        break;
-               }
                case 32:
-               default: {
-                       static const png_color_8 sBIT_32 = {8, 8, 8, 0, 0};
-                       png_set_sBIT(png_ptr, info_ptr, &sBIT_32);
+               default:
+                       png_set_sBIT(png_ptr, info_ptr, PNG_CONST_CAST(png_color_8*, &sBIT_32));
                        break;
-               }
        }
 
        // Write the pHYs chunk.