From: Tony Cook <tony@develop=help.com> Date: Tue, 26 Jun 2007 12:05:27 +0000 (+0000) Subject: - to avoid confusion, channels not present in the image are returned as X-Git-Tag: Imager-0.60~32 X-Git-Url: http://git.imager.perl.org/imager.git/commitdiff_plain/b3aa972f38824e5f1ac0b20b65ea89b2da7a4943 - to avoid confusion, channels not present in the image are returned as zero by getscanline(). This has no effect on the C level i_glin() and i_glinf() API functions which continue to not set the unused channels. --- diff --git a/Changes b/Changes index c4c8743c..5eae80d0 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,11 @@ Bug fixes: - fixed various memory leaks that could occur when failing to read png, jpeg, bmp or tga files. + - to avoid confusion, channels not present in the image are returned as + zero by getscanline(). This has no effect on the C level i_glin() + and i_glinf() API functions which continue to not set the unused + channels. + Imager 0.59 - 14 June 2007 =========== diff --git a/Imager.xs b/Imager.xs index 94c4325f..46f7b3e3 100644 --- a/Imager.xs +++ b/Imager.xs @@ -3966,6 +3966,7 @@ i_glin(im, l, r, y) PPCODE: if (l < r) { vals = mymalloc((r-l) * sizeof(i_color)); + memset(vals, 0, (r-l) * sizeof(i_color)); count = i_glin(im, l, r, y, vals); if (GIMME_V == G_ARRAY) { EXTEND(SP, count); @@ -3994,9 +3995,12 @@ i_glinf(im, l, r, y) PREINIT: i_fcolor *vals; int count, i; + i_fcolor zero = { 0 }; PPCODE: if (l < r) { vals = mymalloc((r-l) * sizeof(i_fcolor)); + for (i = 0; i < r-l; ++i) + vals[i] = zero; count = i_glinf(im, l, r, y, vals); if (GIMME_V == G_ARRAY) { EXTEND(SP, count); diff --git a/lib/Imager/Test.pm b/lib/Imager/Test.pm index e8f77f78..3b7d561e 100644 --- a/lib/Imager/Test.pm +++ b/lib/Imager/Test.pm @@ -4,7 +4,11 @@ use Test::Builder; require Exporter; use vars qw(@ISA @EXPORT_OK); @ISA = qw(Exporter); -@EXPORT_OK = qw(diff_text_with_nul test_image_raw test_image_16 test_image is_color3 is_color1 is_image is_image_similar image_bounds_checks); +@EXPORT_OK = qw(diff_text_with_nul test_image_raw test_image_16 test_image + is_color3 is_color1 is_color4 + is_fcolor4 + is_image is_image_similar + image_bounds_checks); sub diff_text_with_nul { my ($desc, $text1, $text2, @params) = @_; @@ -55,6 +59,79 @@ END_DIAG return 1; } +sub is_color4($$$$$$) { + my ($color, $red, $green, $blue, $alpha, $comment) = @_; + + my $builder = Test::Builder->new; + + unless (defined $color) { + $builder->ok(0, $comment); + $builder->diag("color is undef"); + return; + } + unless ($color->can('rgba')) { + $builder->ok(0, $comment); + $builder->diag("color is not a color object"); + return; + } + + my ($cr, $cg, $cb, $ca) = $color->rgba; + unless ($builder->ok($cr == $red && $cg == $green && $cb == $blue + && $ca == $alpha, $comment)) { + $builder->diag(<<END_DIAG); +Color mismatch: + Red: $red vs $cr +Green: $green vs $cg + Blue: $blue vs $cb +Alpha: $alpha vs $ca +END_DIAG + return; + } + + return 1; +} + +sub is_fcolor4($$$$$$;$) { + my ($color, $red, $green, $blue, $alpha, $comment_or_diff, $comment_or_undef) = @_; + my ($comment, $mindiff); + if (defined $comment_or_undef) { + ( $mindiff, $comment ) = ( $comment_or_diff, $comment_or_undef ) + } + else { + ( $mindiff, $comment ) = ( 0.001, $comment_or_diff ) + } + + my $builder = Test::Builder->new; + + unless (defined $color) { + $builder->ok(0, $comment); + $builder->diag("color is undef"); + return; + } + unless ($color->can('rgba')) { + $builder->ok(0, $comment); + $builder->diag("color is not a color object"); + return; + } + + my ($cr, $cg, $cb, $ca) = $color->rgba; + unless ($builder->ok(abs($cr - $red) <= $mindiff + && abs($cg - $green) <= $mindiff + && abs($cb - $blue) <= $mindiff + && abs($ca - $alpha) <= $mindiff, $comment)) { + $builder->diag(<<END_DIAG); +Color mismatch: + Red: $red vs $cr +Green: $green vs $cg + Blue: $blue vs $cb +Alpha: $alpha vs $ca +END_DIAG + return; + } + + return 1; +} + sub is_color1($$$) { my ($color, $grey, $comment) = @_; diff --git a/t/t01introvert.t b/t/t01introvert.t index 0763f1e3..947b4b3a 100644 --- a/t/t01introvert.t +++ b/t/t01introvert.t @@ -3,13 +3,13 @@ # to make sure we get expected values use strict; -use Test::More tests => 212; +use Test::More tests => 223; BEGIN { use_ok(Imager => qw(:handy :all)) } require "t/testtools.pl"; -use Imager::Test qw(image_bounds_checks); +use Imager::Test qw(image_bounds_checks is_color4 is_fcolor4); init_log("testout/t01introvert.log",1); @@ -477,6 +477,31 @@ cmp_ok(Imager->errstr, '=~', qr/channels must be between 1 and 4/, print "# end OO level scanline function tests\n"; } +{ # to avoid confusion, i_glin/i_glinf modified to return 0 in unused + # channels at the perl level + my $im = Imager->new(xsize => 4, ysize => 4, channels => 2); + my $fill = Imager::Color->new(128, 255, 0, 0); + ok($im->box(filled => 1, color => $fill), 'fill it up'); + my $data = $im->getscanline('y' => 0); + is(unpack("H*", $data), "80ff000080ff000080ff000080ff0000", + "check we get zeros"); + my @colors = $im->getscanline('y' => 0); + is_color4($colors[0], 128, 255, 0, 0, "check object interface[0]"); + is_color4($colors[1], 128, 255, 0, 0, "check object interface[1]"); + is_color4($colors[2], 128, 255, 0, 0, "check object interface[2]"); + is_color4($colors[3], 128, 255, 0, 0, "check object interface[3]"); + + my $dataf = $im->getscanline('y' => 0, type => 'float'); + is_deeply([ unpack("d*", $dataf) ], + [ ( 128.0 / 255.0, 1.0, 0, 0, ) x 4 ], + "check we get zeroes (double)"); + my @fcolors = $im->getscanline('y' => 0, type => 'float'); + is_fcolor4($fcolors[0], 128.0/255.0, 1.0, 0, 0, "check object interface[0]"); + is_fcolor4($fcolors[1], 128.0/255.0, 1.0, 0, 0, "check object interface[1]"); + is_fcolor4($fcolors[2], 128.0/255.0, 1.0, 0, 0, "check object interface[2]"); + is_fcolor4($fcolors[3], 128.0/255.0, 1.0, 0, 0, "check object interface[3]"); +} + { # check the channel mask function my $im = Imager->new(xsize => 10, ysize=>10, bits=>8);