]> git.imager.perl.org - imager.git/blob - t/t64copyflip.t
prefer static first
[imager.git] / t / t64copyflip.t
1 #!perl -w
2 use strict;
3 use Test::More tests => 95;
4 use Imager;
5 use Imager::Test qw(is_color3 is_image is_imaged test_image_double test_image isnt_image is_image_similar);
6
7 #$Imager::DEBUG=1;
8
9 -d "testout" or mkdir "testout";
10
11 Imager::init('log'=>'testout/t64copyflip.log');
12
13 my $img=Imager->new() or die "unable to create image object\n";
14
15 $img->open(file=>'testimg/scale.ppm',type=>'pnm');
16 my $nimg = $img->copy();
17 ok($nimg, "copy returned something");
18
19 # test if ->copy() works
20
21 my $diff = Imager::i_img_diff($img->{IMG}, $nimg->{IMG});
22 is_image($img, $nimg, "copy matches source");
23
24 {
25   my $empty = Imager->new;
26   ok(!$empty->copy, "fail to copy an empty image");
27   is($empty->errstr, "copy: empty input image", "check error message");
28 }
29
30 # test if ->flip(dir=>'h')->flip(dir=>'h') doesn't alter the image
31 $nimg->flip(dir=>"h")->flip(dir=>"h");
32 is_image($nimg, $img, "double horiz flipped matches original");
33
34 # test if ->flip(dir=>'v')->flip(dir=>'v') doesn't alter the image
35 $nimg->flip(dir=>"v")->flip(dir=>"v");
36 is_image($nimg, $img, "double vertically flipped image matches original");
37
38
39 # test if ->flip(dir=>'h')->flip(dir=>'v') is same as ->flip(dir=>'hv')
40 $nimg->flip(dir=>"v")->flip(dir=>"h")->flip(dir=>"hv");;
41 is_image($img, $nimg, "check flip with hv matches flip v then flip h");
42
43 {
44   my $empty = Imager->new;
45   ok(!$empty->flip(dir => "v"), "fail to flip an empty image");
46   is($empty->errstr, "flip: empty input image", "check error message");
47 }
48
49 {
50   my $imsrc = test_image_double;
51   my $imcp = $imsrc->copy;
52   is_imaged($imsrc, $imcp, "copy double image");
53   $imcp->flip(dir=>"v")->flip(dir=>"v");
54   is_imaged($imsrc, $imcp, "flip v twice");
55   $imcp->flip(dir=>"h")->flip(dir=>"h");
56   is_imaged($imsrc, $imcp, "flip h twice");
57   $imcp->flip(dir=>"h")->flip(dir=>"v")->flip(dir=>"hv");
58   is_imaged($imsrc, $imcp, "flip h,v,hv twice");
59 }
60
61 {
62   my $impal = test_image()->to_paletted;
63   my $imcp = $impal->copy;
64   is($impal->type, "paletted", "check paletted test image is");
65   is($imcp->type, "paletted", "check copy test image is paletted");
66   ok($impal->flip(dir => "h"), "flip paletted h");
67   isnt_image($impal, $imcp, "check it changed");
68   ok($impal->flip(dir => "v"), "flip paletted v");
69   ok($impal->flip(dir => "hv"), "flip paletted hv");
70   is_image($impal, $imcp, "should be back to original image");
71   is($impal->type, "paletted", "and still paletted");
72 }
73
74 rot_test($img, 90, 4);
75 rot_test($img, 180, 2);
76 rot_test($img, 270, 4);
77 rot_test($img, 0, 1);
78
79 my $pimg = $img->to_paletted();
80 rot_test($pimg, 90, 4);
81 rot_test($pimg, 180, 2);
82 rot_test($pimg, 270, 4);
83 rot_test($pimg, 0, 1);
84
85 my $timg = $img->rotate(right=>90)->rotate(right=>270);
86 is(Imager::i_img_diff($img->{IMG}, $timg->{IMG}), 0,
87    "check rotate 90 then 270 matches original");
88 $timg = $img->rotate(right=>90)->rotate(right=>180)->rotate(right=>90);
89 is(Imager::i_img_diff($img->{IMG}, $timg->{IMG}), 0,
90      "check rotate 90 then 180 then 90 matches original");
91
92 # this could use more tests
93 my $rimg = $img->rotate(degrees=>10);
94 ok($rimg, "rotation by 10 degrees gave us an image");
95 if (!$rimg->write(file=>"testout/t64_rot10.ppm")) {
96   print "# Cannot save: ",$rimg->errstr,"\n";
97 }
98
99 # rotate with background
100 $rimg = $img->rotate(degrees=>10, back=>Imager::Color->new(builtin=>'red'));
101 ok($rimg, "rotate with background gave us an image");
102 if (!$rimg->write(file=>"testout/t64_rot10_back.ppm")) {
103   print "# Cannot save: ",$rimg->errstr,"\n";
104 }
105
106 {
107   # rotate with text background
108   my $rimg = $img->rotate(degrees => 45, back => '#FF00FF');
109   ok($rimg, "rotate with background as text gave us an image");
110   
111   # check the color set correctly
112   my $c = $rimg->getpixel(x => 0, 'y' => 0);
113   is_deeply([ 255, 0, 255 ], [ ($c->rgba)[0, 1, 2] ],
114             "check background set correctly");
115
116   # check error handling for background color
117   $rimg = $img->rotate(degrees => 45, back => "some really unknown color");
118   ok(!$rimg, "should fail due to bad back color");
119   cmp_ok($img->errstr, '=~', "^No color named ", "check error message");
120 }
121 SKIP:
122 { # rotate in double mode
123   my $dimg = $img->to_rgb16;
124   my $rimg = $dimg->rotate(degrees => 10);
125   ok($rimg, "rotate 16-bit image gave us an image")
126     or skip("could not rotate", 3);
127   ok($rimg->write(file => "testout/t64_rotf10.ppm", pnm_write_wide_data => 1),
128      "save wide data rotated")
129     or diag($rimg->errstr);
130
131   # with a background color
132   my $rimgb = $dimg->rotate(degrees => 10, back => "#FF8000");
133   ok($rimgb, "rotate 16-bit image with back gave us an image")
134     or skip("could not rotate", 1);
135   ok($rimgb->write(file => "testout/t64_rotfb10.ppm", pnm_write_wide_data => 1),
136      "save wide data rotated")
137     or diag($rimgb->errstr);
138 }
139 { # rotate in paletted mode
140   my $rimg = $pimg->rotate(degrees => 10);
141   ok($rimg, "rotated paletted image 10 degrees");
142   ok($rimg->write(file => "testout/t64_rotp10.ppm"),
143      "save paletted rotated")
144     or diag($rimg->errstr);
145 }
146
147 my $trimg = $img->matrix_transform(matrix=>[ 1.2, 0, 0,
148                                              0,   1, 0,
149                                              0,   0, 1]);
150 ok($trimg, "matrix_transform() returned an image");
151 $trimg->write(file=>"testout/t64_trans.ppm")
152   or print "# Cannot save: ",$trimg->errstr,"\n";
153
154 $trimg = $img->matrix_transform(matrix=>[ 1.2, 0, 0,
155                                              0,   1, 0,
156                                              0,   0, 1],
157                                    back=>Imager::Color->new(builtin=>'blue'));
158 ok($trimg, "matrix_transform() with back returned an image");
159
160 $trimg->write(file=>"testout/t64_trans_back.ppm")
161   or print "# Cannot save: ",$trimg->errstr,"\n";
162
163 {
164   my $empty = Imager->new;
165   ok(!$empty->matrix_transform(matrix => [ 1, 0, 0,
166                                            0, 1, 0,
167                                            0, 0, 1 ]),
168      "can't transform an empty image");
169   is($empty->errstr, "matrix_transform: empty input image",
170      "check error message");
171 }
172
173 sub rot_test {
174   my ($src, $degrees, $count) = @_;
175
176   my $cimg = $src->copy();
177   my $in;
178   for (1..$count) {
179     $in = $cimg;
180     $cimg = $cimg->rotate(right=>$degrees)
181       or last;
182   }
183  SKIP:
184   {
185     ok($cimg, "got a rotated image")
186       or skip("no image to check", 4);
187     my $diff = Imager::i_img_diff($src->{IMG}, $cimg->{IMG});
188     is($diff, 0, "check it matches source")
189       or skip("didn't match", 3);
190
191     # check that other parameters match
192     is($src->type, $cimg->type, "type check");
193     is($src->bits, $cimg->bits, "bits check");
194     is($src->getchannels, $cimg->getchannels, "channels check");
195   }
196 }
197
198 { # http://rt.cpan.org/NoAuth/Bug.html?id=9672
199   my $warning;
200   local $SIG{__WARN__} = 
201     sub { 
202       $warning = "@_";
203       my $printed = $warning;
204       $printed =~ s/\n$//;
205       $printed =~ s/\n/\n\#/g; 
206       print "# ",$printed, "\n";
207     };
208   my $img = Imager->new(xsize=>10, ysize=>10);
209   $img->copy();
210   cmp_ok($warning, '=~', 'void', "correct warning");
211   cmp_ok($warning, '=~', 't64copyflip\\.t', "correct file");
212   $warning = '';
213   $img->rotate(degrees=>5);
214   cmp_ok($warning, '=~', 'void', "correct warning");
215   cmp_ok($warning, '=~', 't64copyflip\\.t', "correct file");
216   $warning = '';
217   $img->matrix_transform(matrix=>[1, 1, 1]);
218   cmp_ok($warning, '=~', 'void', "correct warning");
219   cmp_ok($warning, '=~', 't64copyflip\\.t', "correct file");
220 }
221
222 {
223   # 29936 - matrix_transform() should use fabs() instead of abs()
224   # range checking sz 
225
226   # this meant that when sz was < 1 (which it often is for these
227   # transformations), it treated the values out of range, producing a
228   # blank output image
229
230   my $src = Imager->new(xsize => 20, ysize => 20);
231   $src->box(filled => 1, color => 'FF0000');
232   my $out = $src->matrix_transform(matrix => [ 1, 0, 0,
233                                                0, 1, 0,
234                                                0, 0, 0.9999 ])
235     or print "# ", $src->errstr, "\n";
236   my $blank = Imager->new(xsize => 20, ysize => 20);
237   # they have to be different, surely that would be easy
238   my $diff = Imager::i_img_diff($out->{IMG}, $blank->{IMG});
239   ok($diff, "RT#29936 - check non-blank output");
240 }
241
242 {
243   my $im = Imager->new(xsize => 10, ysize => 10, channels => 4);
244   $im->box(filled => 1, color => 'FF0000');
245   my $back = Imager::Color->new(0, 0, 0, 0);
246   my $rot = $im->rotate(degrees => 10, back => $back);
247   # drop the alpha and make sure there's only 2 colors used
248   my $work = $rot->convert(preset => 'noalpha');
249   my $im_pal = $work->to_paletted(make_colors => 'mediancut');
250   my @colors = $im_pal->getcolors;
251   is(@colors, 2, "should be only 2 colors")
252     or do {
253       print "# ", join(",", $_->rgba), "\n" for @colors;
254     };
255   @colors = sort { ($a->rgba)[0] <=> ($b->rgba)[0] } @colors;
256   is_color3($colors[0], 0, 0, 0, "check we got black");
257   is_color3($colors[1], 255, 0, 0, "and red");
258 }
259
260 { # RT #77063 rotate with degrees => 270 gives a black border
261   # so be a little less strict about rounding up
262   # I've also:
263   #  - improved calculation of the rotation matrix
264   #  - added rounding to interpolation for 1/3 channel images
265   my $im = test_image;
266   $im->box(color => "#00F");
267   my $right = $im->rotate(right => 270);
268   my $deg = $im->rotate(degrees => 270, back => "#FFF");
269   is($deg->getwidth, 150, "check degrees => 270 width");
270   is($deg->getheight, 150, "check degrees => 270 height");
271   ok($deg->write(file => "testout/t64rotdeg270.ppm"), "save it");
272   $right->write(file => "testout/t64rotright270.ppm");
273   is_image($deg, $right, "check right and degrees result the same");
274   #$deg = $deg->convert(preset => "addalpha");
275   # $right = $right->convert(preset => "addalpha");
276   # my $diff = $right->difference(other => $deg, mindist => 1);
277   # $diff->write(file => "testout/t64rotdiff.png");
278 }
279
280 {
281   my $empty = Imager->new;
282   ok(!$empty->rotate(degrees => 90), "can't rotate an empty image");
283   is($empty->errstr, "rotate: empty input image",
284      "check error message");
285 }