39f7f7eeefacc780edd8374693ccf3ed9ebc70ad
[imager.git] / t / t58trans2.t
1 #!perl -w
2 use strict;
3 use Test::More tests => 36;
4 BEGIN { use_ok('Imager'); }
5 use Imager::Test qw(is_color3);
6
7 Imager::init('log'=>'testout/t58trans2.log');
8
9 my $im1 = Imager->new();
10 $im1->open(file=>'testimg/penguin-base.ppm', type=>'pnm')
11          || die "Cannot read image";
12 my $im2 = Imager->new();
13 $im2->open(file=>'testimg/scale.ppm',type=>'pnm')
14         || die "Cannot read testimg/scale.ppm";
15
16 # error handling
17 my $opts = { rpnexpr=>'x x 10 / sin 10 * y + get1' };
18 my $im3 = Imager::transform2($opts);
19 ok(!$im3, "returned an image on error");
20 ok(defined($Imager::ERRSTR), "No error message on failure");
21
22 # image synthesis
23 my $im4 = Imager::transform2({
24         width=>300, height=>300,
25         rpnexpr=>'x y cx cy distance !d y cy - x cx - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a2 cy * 3.1416 / 1 @a2 sin 1 + 2 / hsv'});
26 ok($im4, "synthesis failed");
27
28 if ($im4) {
29   $im4->write(type=>'pnm', file=>'testout/t56a.ppm')
30     || die "Cannot write testout/t56a.ppm";
31 }
32
33 # image distortion
34 my $im5 = Imager::transform2({
35         rpnexpr=>'x x 10 / sin 10 * y + getp1'
36 }, $im1);
37 ok($im5, "image distortion");
38 if ($im5) {
39   $im5->write(type=>'pnm', file=>'testout/t56b.ppm')
40     || die "Cannot write testout/t56b.ppm";
41 }
42
43 # image combination
44 $opts = {
45 rpnexpr=>'x h / !rat x w2 % y h2 % getp2 !pat x y getp1 @rat * @pat 1 @rat - * +'
46 };
47 my $im6 = Imager::transform2($opts,$im1,$im2);
48 ok($im6, "image combination");
49 if ($im6) {
50   $im6->write(type=>'pnm', file=>'testout/t56c.ppm')
51     || die "Cannot write testout/t56c.ppm";
52 }
53
54 # alpha
55 $opts = 
56   {
57    rpnexpr => '0 0 255 x y + w h + 2 - / 255 * rgba',
58    channels => 4,
59    width => 50,
60    height => 50,
61   };
62 my $im8 = Imager::transform2($opts);
63 ok($im8, "alpha output");
64 my $c = $im8->getpixel(x=>0, 'y'=>0);
65 is(($c->rgba)[3], 0, "zero alpha");
66 $c = $im8->getpixel(x=>49, 'y'=>49);
67 is(($c->rgba)[3], 255, "max alpha");
68
69 $opts = { rpnexpr => 'x 1 + log 50 * y 1 + log 50 * getp1' };
70 my $im9 = Imager::transform2($opts, $im1);
71 ok($im9, "log function");
72 if ($im9) {
73   $im9->write(type=>'pnm', file=>'testout/t56-9.ppm');
74 }
75
76 # op tests
77 sub op_test($$$$$$);
78 print "# op tests\n";
79 op_test('7F0000', <<EOS, 0, 127, 0, 'value hsv getp1');
80 120 1.0
81 0 0 getp1 value
82 hsv
83 EOS
84 op_test("7F0000", <<EOS, 255, 0, 0, 'hue');
85 0 0 getp1 hue
86 1.0 1.0 hsv
87 EOS
88 op_test("7F0000", <<EOS, 0, 255, 0, 'sat');
89 120 0 0 getp1 sat 1.0 hsv
90 EOS
91 op_test("4060A0", <<'EOS', 128, 128, 128, "add mult sub rgb red green blue");
92 0 0 getp1 !p @p red 2 * @p green 32 + @p blue 32 - rgb
93 EOS
94 op_test('806040', <<'EOS', 64, 64, 64, "div uminus");
95 0 0 getp1 !p @p red 2 / @p green 32 uminus add @p blue rgb
96 EOS
97 op_test('40087f', <<'EOS', 8, 64, 31, 'pow mod');
98 0 0 getp1 !p @p red 0.5 pow @p green 2 pow @p blue 32 mod rgb
99 EOS
100 op_test('202122', '0 0 getp1 4 *', 128, 132, 136, 'multp');
101 op_test('404040', '0 0 getp1 1 2 3 rgb +', 65, 66, 67, 'addp');
102 op_test('414243', '0 0 getp1 3 2 1 rgb -', 62, 64, 66, 'subp');
103 op_test('808040', <<'EOS', 64, 64, 8, 'sin cos pi sqrt');
104 0 0 getp1 !p pi 6 / sin @p red * 0.1 + pi 3 / cos @p green * 0.1 + 
105 @p blue sqrt rgb
106 EOS
107 op_test('008080', <<'EOS', 0, 0, 0, 'atan2');
108 0 0 0 0 getp1 !p @p red 128 / @p green 128 / atan2 hsv
109 EOS
110 op_test('000000', <<'EOS', 150, 150, 150, 'distance');
111 0 100 120 10 distance !d @d @d @d rgb
112 EOS
113 op_test('000000', <<'EOS', 100, 100, 100, 'int');
114 50.75 int 2 * !i @i @i @i rgb
115 EOS
116 op_test('000100', <<'EOS', 128, 0, 0, 'if');
117 0 0 getp1 !p @p red 0 128 if @p green 0 128 if 0 rgb
118 EOS
119 op_test('FF0000', <<'EOS', 0, 255, 0, 'ifp');
120 0 0 0 getp1 0 255 0 rgb ifp
121 EOS
122 op_test('000000', <<'EOS', 1, 0, 1, 'le lt gt');
123 0 1 le 1 0 lt 1 0 gt rgb
124 EOS
125 op_test('000000', <<'EOS', 0, 1, 0, 'ge eq ne');
126 0 1 ge 0 0 eq 0 0 ne rgb
127 EOS
128 op_test('000000', <<'EOS', 0, 1, 1, 'and or not');
129 1 0 and 1 0 or 0 not rgb
130 EOS
131 op_test('000000', <<'EOS', 255, 0, 255, 'abs');
132 -255 abs 0 abs 255 abs rgb
133 EOS
134 op_test('000000', <<'EOS', 50, 82, 0, 'exp log');
135 1 exp log 50 * 0.5 + 0.5 exp 50 * 0 rgb
136 EOS
137
138 use Imager::Transform;
139
140 # some simple tests
141 print "# Imager::Transform\n";
142 my @funcs = Imager::Transform->list;
143 ok(@funcs, "funcs");
144
145 my $tran = Imager::Transform->new($funcs[0]);
146 ok($tran, "got tranform");
147 ok($tran->describe() eq Imager::Transform->describe($funcs[0]),
148    "description");
149 # look for a function that takes inputs (at least one does)
150 my @needsinputs = grep Imager::Transform->new($_)->inputs, @funcs;
151 # make sure they're 
152 my @inputs = Imager::Transform->new($needsinputs[0])->inputs;
153 ok($inputs[0]{desc}, "input description");
154 # at some point I might want to test the actual transformations
155
156 # check lower level error handling
157 my $im7 = Imager::transform2({rpnexpr=>'x y getp2', width=>100, height=>100});
158 ok(!$im7, "expected failure on accessing invalid image");
159 print "# ", Imager->errstr, "\n";
160 ok(Imager->errstr =~ /not enough images/, "didn't get expected error");
161
162 sub op_test ($$$$$$) {
163   my ($in_color, $code, $r, $g, $b, $comment) = @_;
164
165   my $im = Imager->new(xsize => 1, ysize => 1);
166   $im->setpixel(x => 0, y => 0, color => $in_color);
167  SKIP:
168   {
169     my $out = Imager::transform2({ rpnexpr => $code }, $im);
170     unless ($out) {
171       fail("$comment: coult not compile $code - ".Imager->errstr);
172       return;
173     }
174     my $found = $out->getpixel(x => 0, y => 0);
175     is_color3($found, $r, $g, $b, $comment);
176   }
177 }