[rt #86659] PNG benign error support is more complex than a version check
authorTony Cook <tony@develop-help.com>
Tue, 9 Jul 2013 13:30:48 +0000 (23:30 +1000)
committerTony Cook <tony@develop-help.com>
Tue, 9 Jul 2013 13:30:48 +0000 (23:30 +1000)
PNG/PNG.xs
PNG/impng.c
PNG/impng.h
PNG/t/10png.t
lib/Imager/Files.pod

index 1048b44..242c77d 100644 (file)
@@ -26,6 +26,20 @@ i_writepng_wiol(im, ig)
 unsigned
 i_png_lib_version()
 
+MODULE = Imager::File::PNG  PACKAGE = Imager::File::PNG PREFIX=i_png_
+
+void
+i_png_features(...)
+  PREINIT:
+    const char * const *p;
+  PPCODE:
+    p = i_png_features();
+    while (*p) {
+      EXTEND(SP, 1);
+      PUSHs(sv_2mortal(newSVpv(*p, 0)));
+      ++p;
+    }
+
 int
 IMPNG_READ_IGNORE_BENIGN_ERRORS()
   CODE:
index dcc8524..ac3f9fe 100644 (file)
@@ -48,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);
@@ -295,8 +324,14 @@ i_readpng_wiol(io_glue *ig, int flags) {
   }
   png_set_read_fn(png_ptr, (png_voidp) (ig), wiol_read_data);
 
-#if PNG_LIBPNG_VER >= 10400
+#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");
index af8225a..f27a825 100644 (file)
@@ -10,4 +10,7 @@ i_img    *i_readpng_wiol(io_glue *ig, int flags);
 undef_int i_writepng_wiol(i_img *im, io_glue *ig);
 unsigned i_png_lib_version(void);
 
+extern const char * const *
+i_png_features(void);
+
 #endif
index 4cabe53..bc109d7 100644 (file)
@@ -17,6 +17,8 @@ ok($Imager::formats{"png"}, "must have png format");
 
 diag("Library version " . Imager::File::PNG::i_png_lib_version());
 
+my %png_feat = map { $_ => 1 } Imager::File::PNG->features;
+
 my $green  = i_color_new(0,   255, 0,   255);
 my $blue   = i_color_new(0,   0,   255, 255);
 my $red    = i_color_new(255, 0,   0,   255);
@@ -180,8 +182,8 @@ EOS
 
 SKIP:
 { # ignoring "benign" errors
-  Imager::File::PNG::i_png_lib_version() > 10400
-      or skip "Cannot skip benign errors in libpng this old", 1;
+  $png_feat{"benign-errors"}
+      or skip "libpng not configured for benign error support", 1;
   my $im = Imager->new;
   ok($im->read(file => "testimg/badcrc.png", type => "png",
               png_ignore_benign_errors => 1),
index 88f5dc6..a00a0d5 100644 (file)
@@ -1476,7 +1476,8 @@ C<i_background> - set from the C<sBKG> when reading an image file.
 =for stopwords
 CRC
 
-X<png_ignore_benign_errors>If you're using F<libpng> 1.4 or later, you
+X<png_ignore_benign_errors>If you're using F<libpng> 1.6 or later, or
+an earlier release configured with C<PNG_BENIGN_ERRORS_SUPPORTED>, you
 can choose to ignore file format errors the authors of F<libpng>
 consider I<benign>, this includes at least CRC errors and palette
 index overflows.  Do this by supplying a true value for the