Commit | Line | Data |
---|---|---|
d08b8f85 TC |
1 | #!perl -w |
2 | use strict; | |
3 | use Imager qw(:handy); | |
73962964 | 4 | use Test::More tests => 69; |
f1ac5027 | 5 | Imager::init_log("testout/t61filters.log", 1); |
73962964 | 6 | use Imager::Test qw(is_image_similar); |
d08b8f85 TC |
7 | # meant for testing the filters themselves |
8 | my $imbase = Imager->new; | |
9 | $imbase->open(file=>'testout/t104.ppm') or die; | |
10 | my $im_other = Imager->new(xsize=>150, ysize=>150); | |
11 | $im_other->box(xmin=>30, ymin=>60, xmax=>120, ymax=>90, filled=>1); | |
12 | ||
8c3ff7d9 | 13 | test($imbase, {type=>'autolevels'}, 'testout/t61_autolev.ppm'); |
d08b8f85 | 14 | |
8c3ff7d9 | 15 | test($imbase, {type=>'contrast', intensity=>0.5}, |
d08b8f85 TC |
16 | 'testout/t61_contrast.ppm'); |
17 | ||
18 | # this one's kind of cool | |
8c3ff7d9 | 19 | test($imbase, {type=>'conv', coef=>[ -0.5, 1, -0.5, ], }, |
d08b8f85 TC |
20 | 'testout/t61_conv.ppm'); |
21 | ||
73962964 TC |
22 | { |
23 | my $gauss = test($imbase, {type=>'gaussian', stddev=>5 }, | |
24 | 'testout/t61_gaussian.ppm'); | |
25 | ||
26 | my $imbase16 = $imbase->to_rgb16; | |
27 | my $gauss16 = test($imbase16, {type=>'gaussian', stddev=>5 }, | |
28 | 'testout/t61_gaussian16.ppm'); | |
29 | is_image_similar($gauss, $gauss16, 200000, "8 and 16 gaussian match"); | |
30 | } | |
31 | ||
d08b8f85 | 32 | |
8c3ff7d9 | 33 | test($imbase, { type=>'gradgen', dist=>1, |
d08b8f85 TC |
34 | xo=>[ 10, 10, 120 ], |
35 | yo=>[ 10, 140, 60 ], | |
36 | colors=> [ NC('#FF0000'), NC('#FFFF00'), NC('#00FFFF') ]}, | |
37 | 'testout/t61_gradgen.ppm'); | |
38 | ||
8c3ff7d9 | 39 | test($imbase, {type=>'mosaic', size=>8}, 'testout/t61_mosaic.ppm'); |
d08b8f85 | 40 | |
8c3ff7d9 | 41 | test($imbase, {type=>'hardinvert'}, 'testout/t61_hardinvert.ppm'); |
d08b8f85 | 42 | |
8c3ff7d9 | 43 | test($imbase, {type=>'noise'}, 'testout/t61_noise.ppm'); |
d08b8f85 | 44 | |
8c3ff7d9 | 45 | test($imbase, {type=>'radnoise'}, 'testout/t61_radnoise.ppm'); |
d08b8f85 | 46 | |
8c3ff7d9 | 47 | test($imbase, {type=>'turbnoise'}, 'testout/t61_turbnoise.ppm'); |
d08b8f85 | 48 | |
8c3ff7d9 | 49 | test($imbase, {type=>'bumpmap', bump=>$im_other, lightx=>30, lighty=>30}, |
d08b8f85 TC |
50 | 'testout/t61_bumpmap.ppm'); |
51 | ||
8c3ff7d9 | 52 | test($imbase, {type=>'bumpmap_complex', bump=>$im_other}, 'testout/t61_bumpmap_complex.ppm'); |
d08b8f85 | 53 | |
8c3ff7d9 | 54 | test($imbase, {type=>'postlevels', levels=>3}, 'testout/t61_postlevels.ppm'); |
b2778574 | 55 | |
8c3ff7d9 | 56 | test($imbase, {type=>'watermark', wmark=>$im_other }, |
d08b8f85 TC |
57 | 'testout/t61_watermark.ppm'); |
58 | ||
8c3ff7d9 TC |
59 | test($imbase, {type=>'fountain', xa=>75, ya=>75, xb=>85, yb=>30, |
60 | repeat=>'triangle', #ftype=>'radial', | |
61 | super_sample=>'circle', ssample_param => 16, | |
62 | }, | |
6607600c TC |
63 | 'testout/t61_fountain.ppm'); |
64 | use Imager::Fountain; | |
65 | ||
66 | my $f1 = Imager::Fountain->new; | |
67 | $f1->add(end=>0.2, c0=>NC(255, 0,0), c1=>NC(255, 255,0)); | |
68 | $f1->add(start=>0.2, c0=>NC(255,255,0), c1=>NC(0,0,255,0)); | |
8c3ff7d9 TC |
69 | test($imbase, { type=>'fountain', xa=>20, ya=>130, xb=>130, yb=>20, |
70 | #repeat=>'triangle', | |
71 | segments=>$f1 | |
72 | }, | |
6607600c TC |
73 | 'testout/t61_fountain2.ppm'); |
74 | my $f2 = Imager::Fountain->new | |
75 | ->add(end=>0.5, c0=>NC(255,0,0), c1=>NC(255,0,0), color=>'hueup') | |
76 | ->add(start=>0.5, c0=>NC(255,0,0), c1=>NC(255,0,0), color=>'huedown'); | |
77 | #use Data::Dumper; | |
78 | #print Dumper($f2); | |
8c3ff7d9 | 79 | test($imbase, { type=>'fountain', xa=>20, ya=>130, xb=>130, yb=>20, |
6607600c TC |
80 | segments=>$f2 }, |
81 | 'testout/t61_fount_hsv.ppm'); | |
8c3ff7d9 TC |
82 | my $f3 = Imager::Fountain->read(gimp=>'testimg/gimpgrad'); |
83 | ok($f3, "read gimpgrad"); | |
84 | test($imbase, { type=>'fountain', xa=>75, ya=>75, xb=>90, yb=>15, | |
6607600c | 85 | segments=>$f3, super_sample=>'grid', |
efdc2568 | 86 | ftype=>'radial_square', combine=>'color' }, |
6607600c | 87 | 'testout/t61_fount_gimp.ppm'); |
8c3ff7d9 | 88 | test($imbase, { type=>'unsharpmask', stddev=>2.0 }, |
b6381851 | 89 | 'testout/t61_unsharp.ppm'); |
8c3ff7d9 | 90 | test($imbase, {type=>'conv', coef=>[ -1, 3, -1, ], }, |
0958329a TC |
91 | 'testout/t61_conv_sharp.ppm'); |
92 | ||
9cef8440 TC |
93 | test($imbase, { type=>'nearest_color', dist=>1, |
94 | xo=>[ 10, 10, 120 ], | |
95 | yo=>[ 10, 140, 60 ], | |
96 | colors=> [ NC('#FF0000'), NC('#FFFF00'), NC('#00FFFF') ]}, | |
97 | 'testout/t61_nearest.ppm'); | |
98 | ||
4c033fd4 TC |
99 | # Regression test: the checking of the segment type was incorrect |
100 | # (the comparison was checking the wrong variable against the wrong value) | |
101 | my $f4 = [ [ 0, 0.5, 1, NC(0,0,0), NC(255,255,255), 5, 0 ] ]; | |
8c3ff7d9 TC |
102 | test($imbase, {type=>'fountain', xa=>75, ya=>75, xb=>90, yb=>15, |
103 | segments=>$f4, super_sample=>'grid', | |
104 | ftype=>'linear', combine=>'color' }, | |
4c033fd4 | 105 | 'testout/t61_regress_fount.ppm'); |
dff75dee TC |
106 | my $im2 = $imbase->copy; |
107 | $im2->box(xmin=>20, ymin=>20, xmax=>40, ymax=>40, color=>'FF0000', filled=>1); | |
108 | $im2->write(file=>'testout/t61_diff_base.ppm'); | |
109 | my $im3 = Imager->new(xsize=>150, ysize=>150, channels=>3); | |
110 | $im3->box(xmin=>20, ymin=>20, xmax=>40, ymax=>40, color=>'FF0000', filled=>1); | |
111 | my $diff = $imbase->difference(other=>$im2); | |
8c3ff7d9 TC |
112 | ok($diff, "got difference image"); |
113 | SKIP: | |
114 | { | |
115 | skip(1, "missing comp or diff image") unless $im3 && $diff; | |
116 | ||
117 | is(Imager::i_img_diff($im3->{IMG}, $diff->{IMG}), 0, | |
118 | "compare test image and diff image"); | |
dff75dee | 119 | } |
6607600c | 120 | |
817ba871 TC |
121 | # newer versions of gimp add a line to the gradient file |
122 | my $name; | |
123 | my $f5 = Imager::Fountain->read(gimp=>'testimg/newgimpgrad.ggr', | |
124 | name => \$name); | |
125 | ok($f5, "read newer gimp gradient") | |
126 | or print "# ",Imager->errstr,"\n"; | |
127 | is($name, "imager test gradient", "check name read correctly"); | |
128 | $f5 = Imager::Fountain->read(gimp=>'testimg/newgimpgrad.ggr'); | |
129 | ok($f5, "check we handle case of no name reference correctly") | |
130 | or print "# ",Imager->errstr,"\n"; | |
131 | ||
132 | # test writing of gradients | |
133 | ok($f2->write(gimp=>'testout/t61grad1.ggr'), "save a gradient") | |
134 | or print "# ",Imager->errstr,"\n"; | |
135 | undef $name; | |
136 | my $f6 = Imager::Fountain->read(gimp=>'testout/t61grad1.ggr', | |
137 | name=>\$name); | |
138 | ok($f6, "read what we wrote") | |
139 | or print "# ",Imager->errstr,"\n"; | |
140 | ok(!defined $name, "we didn't set the name, so shouldn't get one"); | |
141 | ||
142 | # try with a name | |
143 | ok($f2->write(gimp=>'testout/t61grad2.ggr', name=>'test gradient'), | |
144 | "write gradient with a name") | |
145 | or print "# ",Imager->errstr,"\n"; | |
146 | undef $name; | |
147 | my $f7 = Imager::Fountain->read(gimp=>'testout/t61grad2.ggr', name=>\$name); | |
148 | ok($f7, "read what we wrote") | |
149 | or print "# ",Imager->errstr,"\n"; | |
150 | is($name, "test gradient", "check the name matches"); | |
151 | ||
109bec2d TC |
152 | # we attempt to convert color names in segments to segments now |
153 | { | |
154 | my @segs = | |
155 | ( | |
156 | [ 0.0, 0.5, 1.0, '000000', '#FFF', 0, 0 ], | |
157 | ); | |
158 | my $im = Imager->new(xsize=>50, ysize=>50); | |
159 | ok($im->filter(type=>'fountain', segments => \@segs, | |
160 | xa=>0, ya=>30, xb=>49, yb=>30), | |
161 | "fountain with color names instead of objects in segments"); | |
162 | my $left = $im->getpixel('x'=>0, 'y'=>20); | |
163 | ok(color_close($left, Imager::Color->new(0,0,0)), | |
164 | "check black converted correctly"); | |
165 | my $right = $im->getpixel('x'=>49, 'y'=>20); | |
166 | ok(color_close($right, Imager::Color->new(255,255,255)), | |
167 | "check white converted correctly"); | |
168 | ||
169 | # check that invalid color names are handled correctly | |
170 | my @segs2 = | |
171 | ( | |
172 | [ 0.0, 0.5, 1.0, '000000', 'FxFxFx', 0, 0 ], | |
173 | ); | |
174 | ok(!$im->filter(type=>'fountain', segments => \@segs2, | |
175 | xa=>0, ya=>30, xb=>49, yb=>30), | |
176 | "fountain with invalid color name"); | |
177 | cmp_ok($im->errstr, '=~', 'No color named', "check error message"); | |
178 | } | |
179 | ||
b692658a TC |
180 | { |
181 | my $im = Imager->new(xsize=>100, ysize=>100); | |
182 | # build the gradient the hard way - linear from black to white, | |
183 | # then back again | |
184 | my @simple = | |
185 | ( | |
186 | [ 0, 0.25, 0.5, 'black', 'white', 0, 0 ], | |
187 | [ 0.5. 0.75, 1.0, 'white', 'black', 0, 0 ], | |
188 | ); | |
189 | # across | |
190 | my $linear = $im->filter(type => "fountain", | |
191 | ftype => 'linear', | |
192 | repeat => 'sawtooth', | |
193 | xa => 0, | |
194 | ya => $im->getheight / 2, | |
195 | xb => $im->getwidth - 1, | |
196 | yb => $im->getheight / 2); | |
197 | ok($linear, "linear fountain sample"); | |
198 | # around | |
199 | my $revolution = $im->filter(type => "fountain", | |
200 | ftype => 'revolution', | |
201 | xa => $im->getwidth / 2, | |
202 | ya => $im->getheight / 2, | |
203 | xb => $im->getwidth / 2, | |
204 | yb => 0); | |
205 | ok($revolution, "revolution fountain sample"); | |
206 | # out from the middle | |
207 | my $radial = $im->filter(type => "fountain", | |
208 | ftype => 'radial', | |
209 | xa => $im->getwidth / 2, | |
210 | ya => $im->getheight / 2, | |
211 | xb => $im->getwidth / 2, | |
212 | yb => 0); | |
213 | ok($radial, "radial fountain sample"); | |
214 | } | |
215 | ||
7327d4b0 TC |
216 | { |
217 | # try a simple custom filter that uses the Perl image interface | |
218 | sub perl_filt { | |
219 | my %args = @_; | |
220 | ||
221 | my $im = $args{imager}; | |
222 | ||
223 | my $channels = $args{channels}; | |
224 | unless (@$channels) { | |
225 | $channels = [ reverse(0 .. $im->getchannels-1) ]; | |
226 | } | |
227 | my @chans = @$channels; | |
228 | push @chans, 0 while @chans < 4; | |
229 | ||
230 | for my $y (0 .. $im->getheight-1) { | |
231 | my $row = $im->getsamples(y => $y, channels => \@chans); | |
232 | $im->setscanline(y => $y, pixels => $row); | |
233 | } | |
234 | } | |
235 | Imager->register_filter(type => 'perl_test', | |
236 | callsub => \&perl_filt, | |
237 | defaults => { channels => [] }, | |
238 | callseq => [ qw/imager channels/ ]); | |
239 | test($imbase, { type => 'perl_test' }, 'testout/t61perl.ppm'); | |
240 | } | |
241 | ||
d08b8f85 | 242 | sub test { |
8c3ff7d9 | 243 | my ($in, $params, $out) = @_; |
b2778574 | 244 | |
d08b8f85 | 245 | my $copy = $in->copy; |
8c3ff7d9 TC |
246 | if (ok($copy->filter(%$params), $params->{type})) { |
247 | ok($copy->write(file=>$out), "write $params->{type}") | |
248 | or print "# ",$copy->errstr,"\n"; | |
d08b8f85 TC |
249 | } |
250 | else { | |
8c3ff7d9 TC |
251 | SKIP: |
252 | { | |
253 | skip("couldn't filter", 1); | |
254 | } | |
d08b8f85 | 255 | } |
73962964 | 256 | $copy; |
d08b8f85 | 257 | } |
109bec2d TC |
258 | |
259 | sub color_close { | |
260 | my ($c1, $c2) = @_; | |
261 | ||
262 | my @c1 = $c1->rgba; | |
263 | my @c2 = $c2->rgba; | |
264 | ||
265 | for my $i (0..2) { | |
266 | if (abs($c1[$i]-$c2[$i]) > 2) { | |
267 | return 0; | |
268 | } | |
269 | } | |
270 | return 1; | |
271 | } |