Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

WIP PNG re-work

  • Loading branch information...
commit cfb628e2d7f9916368f12f1621846ec0e60ce90b 1 parent 00cff94
@tonycoz authored
View
1  Changes
@@ -2,6 +2,7 @@ Imager release history. Older releases can be found in Changes.old
- PNG rework
- improve error reporting
+ - add png_interlace, png_bits tags
Imager 0.90 - unreleased
===========
View
2  MANIFEST
@@ -234,6 +234,8 @@ PNG/testimg/palette.png
PNG/testimg/palette_out.png
PNG/testimg/paltrans.png
PNG/testimg/rgb16.png
+PNG/testimg/rgb8.png
+PNG/testimg/rgb8i.png
pnm.c
polygon.c
ppport.h
View
72 PNG/impng.c
@@ -28,7 +28,10 @@
static int CC2C[PNG_COLOR_MASK_PALETTE|PNG_COLOR_MASK_COLOR|PNG_COLOR_MASK_ALPHA];
#define PNG_BYTES_TO_CHECK 4
-
+
+static i_img *
+read_direct8(png_structp png_ptr, png_infop info_ptr, int channels, i_img_dim width, i_img_dim height);
+
unsigned
i_png_lib_version(void) {
return png_access_version_number();
@@ -313,43 +316,72 @@ i_readpng_wiol(io_glue *ig) {
return NULL;
}
+ im = read_direct8(png_ptr, info_ptr, channels, width, height);
+
+ if (im)
+ get_png_tags(im, png_ptr, info_ptr);
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+
+ if (im) {
+ if (rs.warnings) {
+ i_tags_set(&im->tags, "png_warnings", rs.warnings, -1);
+ }
+ }
+ cleanup_read_state(&rs);
+
+ mm_log((1,"(%p) <- i_readpng_wiol\n", im));
+
+ return im;
+}
+
+static i_img *
+read_direct8(png_structp png_ptr, png_infop info_ptr, int channels,
+ i_img_dim width, i_img_dim height) {
+ i_img * volatile vim = NULL;
+ int color_type = png_get_color_type(png_ptr, info_ptr);
+ int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
+ i_img_dim y;
+ int number_passes, pass;
+ i_img *im;
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ if (vim) i_img_destroy(vim);
+
+ return NULL;
+ }
+
+ number_passes = png_set_interlace_handling(png_ptr);
+ mm_log((1,"number of passes=%d\n",number_passes));
+
png_set_strip_16(png_ptr);
png_set_packing(png_ptr);
- if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr);
+ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+ png_set_expand(png_ptr);
+
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
channels++;
mm_log((1, "image has transparency, adding alpha: channels = %d\n", channels));
png_set_expand(png_ptr);
}
- number_passes = png_set_interlace_handling(png_ptr);
- mm_log((1,"number of passes=%d\n",number_passes));
png_read_update_info(png_ptr, info_ptr);
- im = i_img_8_new(width,height,channels);
+ im = vim = i_img_8_new(width,height,channels);
if (!im) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
return NULL;
}
-
- for (pass = 0; pass < number_passes; pass++)
- for (y = 0; y < height; y++) { png_read_row(png_ptr,(png_bytep) &(im->idata[channels*width*y]), NULL); }
-
- png_read_end(png_ptr, info_ptr);
- get_png_tags(im, png_ptr, info_ptr);
-
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
-
- if (rs.warnings) {
- i_tags_set(&im->tags, "png_warnings", rs.warnings, -1);
+ for (pass = 0; pass < number_passes; pass++) {
+ for (y = 0; y < height; y++) {
+ png_read_row(png_ptr,(png_bytep) &(im->idata[channels*width*y]), NULL);
+ }
}
- cleanup_read_state(&rs);
-
- mm_log((1,"(0x%08X) <- i_readpng_scalar\n", im));
+ png_read_end(png_ptr, info_ptr);
+
return im;
}
View
34 PNG/t/10png.t
@@ -2,7 +2,7 @@
use strict;
use Imager qw(:all);
use Test::More;
-use Imager::Test qw(test_image_raw test_image);
+use Imager::Test qw(test_image_raw test_image is_image);
my $debug_writes = 1;
@@ -13,7 +13,7 @@ init_log("testout/t102png.log",1);
$Imager::formats{"png"}
or plan skip_all => "No png support";
-plan tests => 73;
+plan tests => 92;
diag("Library version " . Imager::File::PNG::i_png_lib_version());
@@ -231,6 +231,8 @@ SKIP:
is($im->getchannels, 1, "check channel count");
is($im->type, "direct", "check type");
is($im->bits, 8, "check bits");
+ local $TODO = "Not yet implemented";
+ is($im->tags(name => "png_bits"), 8, "check png_bits tag");
}
{ # test grayscale + alpha read as greyscale + alpha
@@ -240,6 +242,9 @@ SKIP:
is($im->getchannels, 2, "check channel count");
is($im->type, "direct", "check type");
is($im->bits, 8, "check bits");
+ local $TODO = "Not yet implemented";
+ is($im->tags(name => "png_bits"), 8, "check png_bits tag");
+ is($im->tags(name => "png_interlace"), 0, "check png_bits tag");
}
{ # test paletted + alpha read as paletted
@@ -249,6 +254,8 @@ SKIP:
is($im->getchannels, 4, "check channel count");
local $TODO = "Not yet implemented";
is($im->type, "paletted", "check type");
+ is($im->tags(name => "png_bits"), 8, "check png_bits tag");
+ is($im->tags(name => "png_interlace"), 0, "check png_bits tag");
}
{ # test paletted read as paletted
@@ -258,6 +265,8 @@ SKIP:
is($im->getchannels, 3, "check channel count");
local $TODO = "Not yet implemented";
is($im->type, "paletted", "check type");
+ is($im->tags(name => "png_bits"), 8, "check png_bits tag");
+ is($im->tags(name => "png_interlace"), 0, "check png_bits tag");
}
{ # test 16-bit rgb read as 16 bit
@@ -268,6 +277,8 @@ SKIP:
is($im->type, "direct", "check type");
local $TODO = "Not yet implemented";
is($im->bits, 16, "check bits");
+ is($im->tags(name => "png_bits"), 16, "check png_bits tag");
+ is($im->tags(name => "png_interlace"), 0, "check png_bits tag");
}
{ # test 1-bit grey read as mono
@@ -278,6 +289,25 @@ SKIP:
local $TODO = "Not yet implemented";
is($im->type, "paletted", "check type");
ok($im->is_bilevel, "should be bilevel");
+ is($im->tags(name => "png_bits"), 1, "check png_bits tag");
+ is($im->tags(name => "png_interlace"), 0, "check png_bits tag");
+}
+
+SKIP:
+{ # test interlaced read as interlaced and matches original
+ my $im_i = Imager->new(file => "testimg/rgb8i.png", filetype => "png");
+ ok($im_i, "read interlaced")
+ or skip("Could not read rgb8i.png: " . Imager->errstr, 7);
+ is($im_i->getchannels, 3, "check channel count");
+ is($im_i->type, "direct", "check type");
+ is($im_i->tags(name => "png_bits"), 8, "check png_bits");
+ is($im_i->tags(name => "png_interlace"), "adam7", "check png_interlace");
+
+ my $im = Imager->new(file => "testimg/rgb8.png", filetype => "png");
+ ok($im, "read non-interlaced")
+ or skip("Could not read testimg/rgb8.png: " . Imager->errstr, 2);
+ is($im->tags(name => "png_interlace"), "0", "check png_interlace");
+ is_image($im_i, $im, "compare interlaced and non-interlaced");
}
sub limited_write {
View
BIN  PNG/testimg/rgb8.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  PNG/testimg/rgb8i.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.