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",
(
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(),
use vars qw($VERSION @ISA);
BEGIN {
- $VERSION = "0.87";
+ $VERSION = "0.88";
require XSLoader;
XSLoader::load('Imager::File::PNG', $VERSION);
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);
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)
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;
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.
#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 */
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;
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);
cleanup_read_state(&rs);
return NULL;
}
-
+
/* we do our own limit checks */
png_set_user_limits(png_ptr, PNG_DIM_MAX, PNG_DIM_MAX);
#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);
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");
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),
=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