]> git.imager.perl.org - imager.git/blobdiff - PNG/impng.c
[rt #86659] PNG benign error support is more complex than a version check
[imager.git] / PNG / impng.c
index 477a49199ae6400de42823b4907e66545eeb8fbe..ac3f9fe1d61f29962cd8b1a7ebf0fb4d9b847dd2 100644 (file)
@@ -1,6 +1,7 @@
 #include "impng.h"
 #include "png.h"
 #include <stdlib.h>
+#include <string.h>
 
 /* this is a way to get number of channels from color space 
  * Color code to channel number */
@@ -47,6 +48,35 @@ i_png_lib_version(void) {
   return png_access_version_number();
 }
 
+static char const * const
+features[] =
+  {
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+    "benign-errors",
+#endif
+#ifdef PNG_READ_SUPPORTED
+    "read",
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+    "write",
+#endif
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+    "mng-features",
+#endif
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+    "check-cHRM",
+#endif
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+    "user-limits",
+#endif
+    NULL
+  };
+
+const char * const *
+i_png_features(void) {
+  return features;
+}
+
 static void
 wiol_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
   io_glue *ig = png_get_io_ptr(png_ptr);
@@ -270,7 +300,7 @@ static void
 cleanup_read_state(i_png_read_statep);
 
 i_img*
-i_readpng_wiol(io_glue *ig) {
+i_readpng_wiol(io_glue *ig, int flags) {
   i_img *im = NULL;
   png_structp png_ptr;
   png_infop info_ptr;
@@ -293,7 +323,23 @@ i_readpng_wiol(io_glue *ig) {
     return NULL;
   }
   png_set_read_fn(png_ptr, (png_voidp) (ig), wiol_read_data);
-  
+
+#if defined(PNG_BENIGN_ERRORS_SUPPORTED)
+  png_set_benign_errors(png_ptr, (flags & IMPNG_READ_IGNORE_BENIGN_ERRORS) ? 1 : 0);
+#elif PNG_LIBPNG_VER >= 10400
+  if (flags & IMPNG_READ_IGNORE_BENIGN_ERRORS) {
+    i_push_error(0, "libpng not configured to ignore benign errors");
+    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+    return NULL;
+  }
+#else
+  if (flags & IMPNG_READ_IGNORE_BENIGN_ERRORS) {
+    i_push_error(0, "libpng too old to ignore benign errors");
+    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+    return NULL;
+  }
+#endif
+
   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL) {
     png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
@@ -308,7 +354,7 @@ i_readpng_wiol(io_glue *ig) {
     cleanup_read_state(&rs);
     return NULL;
   }
-  
+
   /* we do our own limit checks */
   png_set_user_limits(png_ptr, PNG_DIM_MAX, PNG_DIM_MAX);
 
@@ -316,9 +362,8 @@ i_readpng_wiol(io_glue *ig) {
   png_read_info(png_ptr, info_ptr);
   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
   
-  mm_log((1,
-         "png_get_IHDR results: width %d, height %d, bit_depth %d, color_type %d, interlace_type %d\n",
-         width,height,bit_depth,color_type,interlace_type));
+  mm_log((1, "png_get_IHDR results: width %u, height %u, bit_depth %d, color_type %d, interlace_type %d\n",
+         (unsigned)width, (unsigned)height, bit_depth,color_type,interlace_type));
   
   CC2C[PNG_COLOR_TYPE_GRAY]=1;
   CC2C[PNG_COLOR_TYPE_PALETTE]=3;
@@ -687,7 +732,7 @@ get_png_tags(i_img *im, png_structp png_ptr, png_infop info_ptr,
 
   i_tags_set(&im->tags, "i_format", "png", -1);
   if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) {
-    mm_log((1,"pHYs (%d, %d) %d\n", xres, yres, unit_type));
+    mm_log((1,"pHYs (%u, %u) %d\n", (unsigned)xres, (unsigned)yres, unit_type));
     if (unit_type == PNG_RESOLUTION_METER) {
       i_tags_set_float2(&im->tags, "i_xres", 0, xres * 0.0254, 5);
       i_tags_set_float2(&im->tags, "i_yres", 0, yres * 0.0254, 5);