Permalink
Browse files

[rt #85746] add support for libpng 1.6

1.6 changed the default to ignore "benign" read errors, I now unignore
them explicitly with an option to ignore them.
  • Loading branch information...
1 parent f6966f1 commit 57520a199683befca961a772df11d7822a6a558f @tonycoz committed Jun 7, 2013
Showing with 65 additions and 9 deletions.
  1. +7 −1 PNG/Makefile.PL
  2. +5 −2 PNG/PNG.pm
  3. +9 −1 PNG/PNG.xs
  4. +3 −0 PNG/README
  5. +14 −3 PNG/impng.c
  6. +4 −1 PNG/impng.h
  7. +11 −1 PNG/t/10png.t
  8. BIN PNG/testimg/badcrc.png
  9. +12 −0 lib/Imager/Files.pod
View
@@ -68,9 +68,15 @@ else {
require Imager::Probe;
+# these are mostly needed when pkg-config isn't available
my @alts =
(
{
+ altname => "v1.6",
+ incsuffix => "libpng16",
+ libbase => "png16",
+ },
+ {
altname => "v1.5",
incsuffix => "libpng15",
libbase => "png15",
@@ -96,7 +102,7 @@ my %probe =
(
name => "PNG",
altname => "Generic",
- pkg => [ qw/libpng15 libpng14 libpng12 libpng10 libpng/ ],
+ pkg => [ qw/libpng libpng16 libpng15 libpng14 libpng12 libpng10/ ],
inccheck => sub { -e File::Spec->catfile($_[0], "png.h") },
libbase => "png",
testcode => _png_test_code(),
View
@@ -4,7 +4,7 @@ use Imager;
use vars qw($VERSION @ISA);
BEGIN {
- $VERSION = "0.87";
+ $VERSION = "0.88";
require XSLoader;
XSLoader::load('Imager::File::PNG', $VERSION);
@@ -16,7 +16,10 @@ Imager->register_reader
single =>
sub {
my ($im, $io, %hsh) = @_;
- $im->{IMG} = i_readpng_wiol($io);
+ my $flags = 0;
+ $hsh{png_ignore_benign_errors}
+ and $flags |= IMPNG_READ_IGNORE_BENIGN_ERRORS;
+ $im->{IMG} = i_readpng_wiol($io, $flags);
unless ($im->{IMG}) {
$im->_set_error(Imager->_error_as_msg);
View
@@ -14,8 +14,9 @@ DEFINE_IMAGER_CALLBACKS;
MODULE = Imager::File::PNG PACKAGE = Imager::File::PNG
Imager::ImgRaw
-i_readpng_wiol(ig)
+i_readpng_wiol(ig, flags=0)
Imager::IO ig
+ int flags
undef_int
i_writepng_wiol(im, ig)
@@ -25,5 +26,12 @@ i_writepng_wiol(im, ig)
unsigned
i_png_lib_version()
+int
+IMPNG_READ_IGNORE_BENIGN_ERRORS()
+ CODE:
+ RETVAL = IMPNG_READ_IGNORE_BENIGN_ERRORS;
+ OUTPUT:
+ RETVAL
+
BOOT:
PERL_INITIALIZE_IMAGER_CALLBACKS;
View
@@ -2,6 +2,9 @@ Imager::File::PNG provides PNG file format support for Imager.
It requires libpng, including development files, to be installed.
+libpng 1.2 or later is supported, with minor extra features with
+libpng 1.4 and libpng 1.5.3.
+
For Linux distributions this typically requires installation of the
associated -dev or -devel package.
View
@@ -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 */
@@ -270,7 +271,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 +294,17 @@ i_readpng_wiol(io_glue *ig) {
return NULL;
}
png_set_read_fn(png_ptr, (png_voidp) (ig), wiol_read_data);
-
+
+#if PNG_LIBPNG_VER >= 10400
+ png_set_benign_errors(png_ptr, (flags & IMPNG_READ_IGNORE_BENIGN_ERRORS) ? 1 : 0);
+#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 +319,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);
View
@@ -3,7 +3,10 @@
#include "imext.h"
-i_img *i_readpng_wiol(io_glue *ig);
+i_img *i_readpng_wiol(io_glue *ig, int flags);
+
+#define IMPNG_READ_IGNORE_BENIGN_ERRORS 1
+
undef_int i_writepng_wiol(i_img *im, io_glue *ig);
unsigned i_png_lib_version(void);
View
@@ -10,7 +10,7 @@ my $debug_writes = 1;
init_log("testout/t102png.log",1);
-plan tests => 248;
+plan tests => 249;
# this loads Imager::File::PNG too
ok($Imager::formats{"png"}, "must have png format");
@@ -178,6 +178,16 @@ EOS
is($im->errstr, "IHDR: CRC error", "check error message");
}
+SKIP:
+{ # ignoring "benign" errors
+ Imager::File::PNG::i_png_lib_version() > 10400
+ or skip "Cannot skip benign errors in libpng this old", 1;
+ my $im = Imager->new;
+ ok($im->read(file => "testimg/badcrc.png", type => "png",
+ png_ignore_benign_errors => 1),
+ "read bad crc with png_ignore_benign_errors");
+}
+
{ # write error reporting
my $im = test_image();
ok(!$im->write(type => "png", callback => limited_write(1), buffered => 0),
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -1473,6 +1473,18 @@ C<i_background> - set from the C<sBKG> when reading an image file.
=back
+=for stopwords
+CRC
+
+X<png_ignore_benign_errors>If you're using F<libpng> 1.4 or later, 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
+C<png_ignore_benign_errors> parameter to the read() method:
+
+ $im->read(file => "foo.png", png_ignore_benign_errors => 1)
+ or die $im->errstr;
+
=head2 ICO (Microsoft Windows Icon) and CUR (Microsoft Windows Cursor)
Icon and Cursor files are very similar, the only differences being a

0 comments on commit 57520a1

Please sign in to comment.