Commit | Line | Data |
---|---|---|
92bda632 TC |
1 | #!perl -w |
2 | # | |
3 | # this tests both the Inline interface and the API | |
4 | use strict; | |
92bda632 | 5 | use Test::More; |
d8d215e3 | 6 | use Imager::Test qw(is_color3 is_color4); |
92bda632 | 7 | eval "require Inline::C;"; |
85071ac0 | 8 | plan skip_all => "Inline required for testing API" if $@; |
92bda632 | 9 | |
c045de59 TC |
10 | eval "require Parse::RecDescent;"; |
11 | plan skip_all => "Could not load Parse::RecDescent" if $@; | |
12 | ||
89e3c0aa TC |
13 | use Cwd 'getcwd'; |
14 | plan skip_all => "Inline won't work in directories with spaces" | |
15 | if getcwd() =~ / /; | |
16 | ||
3d3fc93b TC |
17 | plan skip_all => "perl 5.005_04, 5.005_05 too buggy" |
18 | if $] =~ /^5\.005_0[45]$/; | |
19 | ||
40e78f96 TC |
20 | -d "testout" or mkdir "testout"; |
21 | ||
43cc769f TC |
22 | print STDERR "Inline version $Inline::VERSION\n"; |
23 | ||
fc02e376 | 24 | plan tests => 117; |
92bda632 TC |
25 | require Inline; |
26 | Inline->import(with => 'Imager'); | |
22f9ca48 | 27 | Inline->import("FORCE"); # force rebuild |
6d5c85a2 | 28 | #Inline->import(C => Config => OPTIMIZE => "-g"); |
92bda632 TC |
29 | |
30 | Inline->bind(C => <<'EOS'); | |
31 | #include <math.h> | |
32 | ||
33 | int pixel_count(Imager::ImgRaw im) { | |
34 | return im->xsize * im->ysize; | |
35 | } | |
36 | ||
37 | int count_color(Imager::ImgRaw im, Imager::Color c) { | |
38 | int count = 0, x, y, chan; | |
39 | i_color read_c; | |
40 | ||
41 | for (x = 0; x < im->xsize; ++x) { | |
42 | for (y = 0; y < im->ysize; ++y) { | |
43 | int match = 1; | |
44 | i_gpix(im, x, y, &read_c); | |
45 | for (chan = 0; chan < im->channels; ++chan) { | |
46 | if (read_c.channel[chan] != c->channel[chan]) { | |
47 | match = 0; | |
48 | break; | |
49 | } | |
50 | } | |
51 | if (match) | |
52 | ++count; | |
53 | } | |
54 | } | |
55 | ||
56 | return count; | |
57 | } | |
58 | ||
59 | Imager make_10x10() { | |
60 | i_img *im = i_img_8_new(10, 10, 3); | |
61 | i_color c; | |
62 | c.channel[0] = c.channel[1] = c.channel[2] = 255; | |
63 | i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &c); | |
64 | ||
65 | return im; | |
66 | } | |
67 | ||
68 | /* tests that all of the APIs are visible - most of them anyway */ | |
69 | Imager do_lots(Imager src) { | |
70 | i_img *im = i_img_8_new(100, 100, 3); | |
71 | i_img *fill_im = i_img_8_new(5, 5, 3); | |
72 | i_img *testim; | |
3efb0915 | 73 | i_color red, blue, green, black, temp_color; |
92bda632 TC |
74 | i_fcolor redf, bluef; |
75 | i_fill_t *hatch, *fhatch_fill; | |
76 | i_fill_t *im_fill; | |
77 | i_fill_t *solid_fill, *fsolid_fill; | |
78 | i_fill_t *fount_fill; | |
79 | void *block; | |
80 | double matrix[9] = /* 30 degree rotation */ | |
81 | { | |
82 | 0.866025, -0.5, 0, | |
83 | 0.5, 0.866025, 0, | |
84 | 0, 0, 1, | |
85 | }; | |
86 | i_fountain_seg fseg; | |
87 | i_img_tags tags; | |
88 | int entry; | |
89 | double temp_double; | |
90 | ||
91 | red.channel[0] = 255; red.channel[1] = 0; red.channel[2] = 0; | |
92 | red.channel[3] = 255; | |
93 | blue.channel[0] = 0; blue.channel[1] = 0; blue.channel[2] = 255; | |
94 | blue.channel[3] = 255; | |
3efb0915 TC |
95 | green.channel[0] = 0; green.channel[1] = 255; green.channel[2] = 0; |
96 | green.channel[3] = 255; | |
97 | black.channel[0] = black.channel[1] = black.channel[2] = 0; | |
98 | black.channel[3] = 255; | |
92bda632 TC |
99 | hatch = i_new_fill_hatch(&red, &blue, 0, 1, NULL, 0, 0); |
100 | ||
101 | i_box(im, 0, 0, 9, 9, &red); | |
102 | i_box_filled(im, 10, 0, 19, 9, &blue); | |
103 | i_box_cfill(im, 20, 0, 29, 9, hatch); | |
104 | ||
105 | /* make an image fill, and try it */ | |
106 | i_box_cfill(fill_im, 0, 0, 4, 4, hatch); | |
107 | im_fill = i_new_fill_image(fill_im, matrix, 2, 2, 0); | |
108 | ||
109 | i_box_cfill(im, 30, 0, 39, 9, im_fill); | |
110 | ||
111 | /* make a solid fill and try it */ | |
112 | solid_fill = i_new_fill_solid(&red, 0); | |
113 | i_box_cfill(im, 40, 0, 49, 9, solid_fill); | |
114 | ||
115 | /* floating fills */ | |
116 | redf.channel[0] = 1.0; redf.channel[1] = 0; redf.channel[2] = 0; | |
117 | redf.channel[3] = 1.0; | |
118 | bluef.channel[0] = 0; bluef.channel[1] = 0; bluef.channel[2] = 1.0; | |
119 | bluef.channel[3] = 1.0; | |
120 | ||
121 | fsolid_fill = i_new_fill_solidf(&redf, 0); | |
122 | i_box_cfill(im, 50, 0, 59, 9, fsolid_fill); | |
123 | ||
124 | fhatch_fill = i_new_fill_hatchf(&redf, &bluef, 0, 2, NULL, 0, 0); | |
125 | i_box_cfill(im, 60, 0, 69, 9, fhatch_fill); | |
126 | ||
127 | /* fountain fill */ | |
128 | fseg.start = 0; | |
129 | fseg.middle = 0.5; | |
130 | fseg.end = 1.0; | |
131 | fseg.c[0] = redf; | |
132 | fseg.c[1] = bluef; | |
133 | fseg.type = i_fst_linear; | |
134 | fseg.color = i_fc_hue_down; | |
135 | fount_fill = i_new_fill_fount(70, 0, 80, 0, i_ft_linear, i_fr_triangle, 0, i_fts_none, 1, 1, &fseg); | |
136 | ||
137 | i_box_cfill(im, 70, 0, 79, 9, fount_fill); | |
138 | ||
139 | i_line(im, 0, 10, 10, 15, &blue, 1); | |
140 | i_line_aa(im, 0, 19, 10, 15, &red, 1); | |
141 | ||
142 | i_arc(im, 15, 15, 4, 45, 160, &blue); | |
143 | i_arc_aa(im, 25, 15, 4, 75, 280, &red); | |
144 | i_arc_cfill(im, 35, 15, 4, 0, 215, hatch); | |
145 | i_arc_aa_cfill(im, 45, 15, 4, 30, 210, hatch); | |
146 | i_circle_aa(im, 55, 15, 4, &red); | |
147 | ||
148 | i_box(im, 61, 11, 68, 18, &red); | |
149 | i_flood_fill(im, 65, 15, &blue); | |
150 | i_box(im, 71, 11, 78, 18, &red); | |
151 | i_flood_cfill(im, 75, 15, hatch); | |
152 | ||
3efb0915 TC |
153 | i_box_filled(im, 1, 21, 9, 24, &red); |
154 | i_box_filled(im, 1, 25, 9, 29, &blue); | |
155 | i_flood_fill_border(im, 5, 25, &green, &black); | |
156 | ||
157 | i_box_filled(im, 11, 21, 19, 24, &red); | |
158 | i_box_filled(im, 11, 25, 19, 29, &blue); | |
159 | i_flood_cfill_border(im, 15, 25, hatch, &black); | |
160 | ||
0d80f37e TC |
161 | { |
162 | double x[3]; | |
163 | double y[3]; | |
164 | i_polygon_t poly; | |
165 | x[0] = 55; | |
166 | y[0] = 25; | |
167 | x[1] = 55; | |
168 | y[1] = 50; | |
169 | x[2] = 70; | |
170 | y[2] = 50; | |
171 | i_poly_aa_m(im, 3, x, y, i_pfm_evenodd, &red); | |
172 | x[2] = 40; | |
173 | i_poly_aa_cfill_m(im, 3, x, y, i_pfm_evenodd, hatch); | |
174 | y[0] = 65; | |
175 | poly.x = x; | |
176 | poly.y = y; | |
177 | poly.count = 3; | |
178 | i_poly_poly_aa(im, 1, &poly, i_pfm_nonzero, &green); | |
179 | x[2] = 70; | |
180 | i_poly_poly_aa_cfill(im, 1, &poly, i_pfm_nonzero, hatch); | |
181 | } | |
182 | ||
92bda632 TC |
183 | i_fill_destroy(fount_fill); |
184 | i_fill_destroy(fhatch_fill); | |
185 | i_fill_destroy(solid_fill); | |
186 | i_fill_destroy(fsolid_fill); | |
187 | i_fill_destroy(hatch); | |
188 | i_fill_destroy(im_fill); | |
189 | i_img_destroy(fill_im); | |
190 | ||
191 | /* make sure we can make each image type */ | |
192 | testim = i_img_16_new(100, 100, 3); | |
193 | i_img_destroy(testim); | |
194 | testim = i_img_double_new(100, 100, 3); | |
195 | i_img_destroy(testim); | |
196 | testim = i_img_pal_new(100, 100, 3, 256); | |
197 | i_img_destroy(testim); | |
198 | testim = i_sametype(im, 50, 50); | |
199 | i_img_destroy(testim); | |
200 | testim = i_sametype_chans(im, 50, 50, 4); | |
201 | i_img_destroy(testim); | |
202 | ||
203 | i_clear_error(); | |
204 | i_push_error(0, "Hello"); | |
205 | i_push_errorf(0, "%s", "World"); | |
206 | ||
207 | /* make sure tags create/destroy work */ | |
208 | i_tags_new(&tags); | |
209 | i_tags_destroy(&tags); | |
210 | ||
211 | block = mymalloc(20); | |
212 | block = myrealloc(block, 50); | |
213 | myfree(block); | |
214 | ||
215 | i_tags_set(&im->tags, "lots_string", "foo", -1); | |
216 | i_tags_setn(&im->tags, "lots_number", 101); | |
217 | ||
218 | if (!i_tags_find(&im->tags, "lots_number", 0, &entry)) { | |
219 | i_push_error(0, "lots_number tag not found"); | |
220 | i_img_destroy(im); | |
221 | return NULL; | |
222 | } | |
223 | i_tags_delete(&im->tags, entry); | |
224 | ||
225 | /* these won't delete anything, but it makes sure the macros and function | |
226 | pointers are correct */ | |
227 | i_tags_delbyname(&im->tags, "unknown"); | |
228 | i_tags_delbycode(&im->tags, 501); | |
229 | i_tags_set_float(&im->tags, "lots_float", 0, 3.14); | |
230 | if (!i_tags_get_float(&im->tags, "lots_float", 0, &temp_double)) { | |
231 | i_push_error(0, "lots_float not found"); | |
232 | i_img_destroy(im); | |
233 | return NULL; | |
234 | } | |
235 | if (fabs(temp_double - 3.14) > 0.001) { | |
236 | i_push_errorf(0, "lots_float incorrect %g", temp_double); | |
237 | i_img_destroy(im); | |
238 | return NULL; | |
239 | } | |
240 | i_tags_set_float2(&im->tags, "lots_float2", 0, 100 * sqrt(2.0), 5); | |
241 | if (!i_tags_get_int(&im->tags, "lots_float2", 0, &entry)) { | |
242 | i_push_error(0, "lots_float2 not found as int"); | |
243 | i_img_destroy(im); | |
244 | return NULL; | |
245 | } | |
246 | if (entry != 141) { | |
247 | i_push_errorf(0, "lots_float2 unexpected value %d", entry); | |
248 | i_img_destroy(im); | |
249 | return NULL; | |
250 | } | |
251 | ||
252 | i_tags_set_color(&im->tags, "lots_color", 0, &red); | |
253 | if (!i_tags_get_color(&im->tags, "lots_color", 0, &temp_color)) { | |
254 | i_push_error(0, "lots_color not found as color"); | |
255 | i_img_destroy(im); | |
256 | return NULL; | |
257 | } | |
0d80f37e | 258 | |
92bda632 TC |
259 | return im; |
260 | } | |
261 | ||
6d5c85a2 TC |
262 | void |
263 | io_fd(int fd) { | |
264 | Imager::IO io = io_new_fd(fd); | |
265 | i_io_write(io, "test", 4); | |
266 | i_io_close(io); | |
267 | io_glue_destroy(io); | |
268 | } | |
269 | ||
270 | int | |
271 | io_bufchain_test() { | |
272 | Imager::IO io = io_new_bufchain(); | |
273 | unsigned char *result; | |
274 | size_t size; | |
275 | if (i_io_write(io, "test2", 5) != 5) { | |
276 | fprintf(stderr, "write failed\n"); | |
277 | return 0; | |
278 | } | |
279 | if (!i_io_flush(io)) { | |
280 | fprintf(stderr, "flush failed\n"); | |
281 | return 0; | |
282 | } | |
283 | if (i_io_close(io) != 0) { | |
284 | fprintf(stderr, "close failed\n"); | |
285 | return 0; | |
286 | } | |
287 | size = io_slurp(io, &result); | |
288 | if (size != 5) { | |
289 | fprintf(stderr, "wrong size\n"); | |
290 | return 0; | |
291 | } | |
292 | if (memcmp(result, "test2", 5)) { | |
293 | fprintf(stderr, "data mismatch\n"); | |
294 | return 0; | |
295 | } | |
296 | if (i_io_seek(io, 0, 0) != 0) { | |
297 | fprintf(stderr, "seek failure\n"); | |
298 | return 0; | |
299 | } | |
300 | myfree(result); | |
301 | io_glue_destroy(io); | |
302 | ||
303 | return 1; | |
304 | } | |
305 | ||
306 | const char * | |
307 | io_buffer_test(SV *in) { | |
308 | STRLEN len; | |
309 | const char *in_str = SvPV(in, len); | |
310 | static char buf[100]; | |
311 | Imager::IO io = io_new_buffer(in_str, len, NULL, NULL); | |
312 | ssize_t read_size; | |
313 | ||
314 | read_size = i_io_read(io, buf, sizeof(buf)-1); | |
315 | io_glue_destroy(io); | |
316 | if (read_size < 0 || read_size >= sizeof(buf)) { | |
317 | return ""; | |
318 | } | |
319 | ||
320 | buf[read_size] = '\0'; | |
321 | ||
322 | return buf; | |
323 | } | |
324 | ||
325 | const char * | |
326 | io_peekn_test(SV *in) { | |
327 | STRLEN len; | |
328 | const char *in_str = SvPV(in, len); | |
329 | static char buf[100]; | |
330 | Imager::IO io = io_new_buffer(in_str, len, NULL, NULL); | |
331 | ssize_t read_size; | |
332 | ||
333 | read_size = i_io_peekn(io, buf, sizeof(buf)-1); | |
334 | io_glue_destroy(io); | |
335 | if (read_size < 0 || read_size >= sizeof(buf)) { | |
336 | return ""; | |
337 | } | |
338 | ||
339 | buf[read_size] = '\0'; | |
340 | ||
341 | return buf; | |
342 | } | |
343 | ||
344 | const char * | |
345 | io_gets_test(SV *in) { | |
346 | STRLEN len; | |
347 | const char *in_str = SvPV(in, len); | |
348 | static char buf[100]; | |
349 | Imager::IO io = io_new_buffer(in_str, len, NULL, NULL); | |
350 | ssize_t read_size; | |
351 | ||
352 | read_size = i_io_gets(io, buf, sizeof(buf), 's'); | |
353 | io_glue_destroy(io); | |
354 | if (read_size < 0 || read_size >= sizeof(buf)) { | |
355 | return ""; | |
356 | } | |
357 | ||
358 | return buf; | |
359 | } | |
360 | ||
361 | int | |
362 | io_getc_test(SV *in) { | |
363 | STRLEN len; | |
364 | const char *in_str = SvPV(in, len); | |
365 | static char buf[100]; | |
366 | Imager::IO io = io_new_buffer(in_str, len, NULL, NULL); | |
367 | int result; | |
368 | ||
369 | result = i_io_getc(io); | |
370 | io_glue_destroy(io); | |
371 | ||
372 | return result; | |
373 | } | |
374 | ||
375 | int | |
376 | io_peekc_test(SV *in) { | |
377 | STRLEN len; | |
378 | const char *in_str = SvPV(in, len); | |
379 | static char buf[100]; | |
380 | Imager::IO io = io_new_buffer(in_str, len, NULL, NULL); | |
381 | int result; | |
382 | ||
383 | i_io_set_buffered(io, 0); | |
384 | ||
385 | result = i_io_peekc(io); | |
386 | io_glue_destroy(io); | |
387 | ||
388 | return result; | |
389 | } | |
390 | ||
d8d215e3 TC |
391 | |
392 | ||
393 | int | |
394 | test_render_color(Imager work_8) { | |
395 | i_render *r8; | |
396 | i_color c; | |
397 | unsigned char render_coverage[3]; | |
398 | ||
399 | render_coverage[0] = 0; | |
400 | render_coverage[1] = 128; | |
401 | render_coverage[2] = 255; | |
402 | ||
403 | r8 = i_render_new(work_8, 10); | |
404 | c.channel[0] = 128; | |
405 | c.channel[1] = 255; | |
406 | c.channel[2] = 0; | |
407 | c.channel[3] = 255; | |
408 | i_render_color(r8, 0, 0, sizeof(render_coverage), render_coverage, &c); | |
409 | ||
410 | c.channel[3] = 128; | |
411 | i_render_color(r8, 0, 1, sizeof(render_coverage), render_coverage, &c); | |
412 | ||
413 | c.channel[3] = 0; | |
414 | i_render_color(r8, 0, 2, sizeof(render_coverage), render_coverage, &c); | |
415 | ||
416 | i_render_delete(r8); | |
417 | ||
418 | return 1; | |
419 | } | |
420 | ||
23c6bf56 TC |
421 | int |
422 | raw_psamp(Imager im, int chan_count) { | |
423 | static i_sample_t samps[] = { 0, 127, 255 }; | |
424 | ||
425 | i_clear_error(); | |
426 | return i_psamp(im, 0, 1, 0, samps, NULL, chan_count); | |
427 | } | |
428 | ||
429 | int | |
430 | raw_psampf(Imager im, int chan_count) { | |
431 | static i_fsample_t samps[] = { 0, 0.5, 1.0 }; | |
432 | ||
433 | i_clear_error(); | |
434 | return i_psampf(im, 0, 1, 0, samps, NULL, chan_count); | |
435 | } | |
436 | ||
24c9233d TC |
437 | int |
438 | test_mutex() { | |
439 | i_mutex_t m; | |
440 | ||
441 | m = i_mutex_new(); | |
442 | i_mutex_lock(m); | |
443 | i_mutex_unlock(m); | |
444 | i_mutex_destroy(m); | |
445 | ||
446 | return 1; | |
447 | } | |
448 | ||
fc02e376 TC |
449 | int |
450 | test_slots() { | |
451 | im_slot_t slot = im_context_slot_new(NULL); | |
452 | ||
453 | if (im_context_slot_get(aIMCTX, slot)) { | |
454 | fprintf(stderr, "slots should default to NULL\n"); | |
455 | return 0; | |
456 | } | |
457 | if (!im_context_slot_set(aIMCTX, slot, &slot)) { | |
458 | fprintf(stderr, "set slot failed\n"); | |
459 | return 0; | |
460 | } | |
461 | ||
462 | if (im_context_slot_get(aIMCTX, slot) != &slot) { | |
463 | fprintf(stderr, "get slot didn't match\n"); | |
464 | return 0; | |
465 | } | |
466 | ||
467 | return 1; | |
468 | } | |
469 | ||
92bda632 TC |
470 | EOS |
471 | ||
472 | my $im = Imager->new(xsize=>50, ysize=>50); | |
473 | is(pixel_count($im), 2500, "pixel_count"); | |
474 | ||
475 | my $black = Imager::Color->new(0,0,0); | |
476 | is(count_color($im, $black), 2500, "count_color black on black image"); | |
477 | ||
478 | my $im2 = make_10x10(); | |
479 | my $white = Imager::Color->new(255, 255, 255); | |
480 | is(count_color($im2, $white), 100, "check new image white count"); | |
481 | ok($im2->box(filled=>1, xmin=>1, ymin=>1, xmax => 8, ymax=>8, color=>$black), | |
482 | "try new image"); | |
483 | is(count_color($im2, $black), 64, "check modified black count"); | |
484 | is(count_color($im2, $white), 36, "check modified white count"); | |
485 | ||
486 | my $im3 = do_lots($im2); | |
487 | ok($im3, "do_lots()") | |
488 | or print "# ", Imager->_error_as_msg, "\n"; | |
489 | ok($im3->write(file=>'testout/t82lots.ppm'), "write t82lots.ppm"); | |
b340c629 TC |
490 | |
491 | { # RT #24992 | |
492 | # the T_IMAGER_FULL_IMAGE typemap entry was returning a blessed | |
493 | # hash with an extra ref, causing memory leaks | |
494 | ||
495 | my $im = make_10x10(); | |
496 | my $im2 = Imager->new(xsize => 10, ysize => 10); | |
3d3fc93b | 497 | require B; |
b340c629 TC |
498 | my $imb = B::svref_2object($im); |
499 | my $im2b = B::svref_2object($im2); | |
500 | is ($imb->REFCNT, $im2b->REFCNT, | |
501 | "check refcnt of imager object hash between normal and typemap generated"); | |
502 | } | |
6d5c85a2 TC |
503 | |
504 | SKIP: | |
505 | { | |
506 | use IO::File; | |
507 | my $fd_filename = "testout/t82fd.txt"; | |
508 | { | |
509 | my $fh = IO::File->new($fd_filename, "w") | |
510 | or skip("Can't create file: $!", 1); | |
511 | io_fd(fileno($fh)); | |
512 | $fh->close; | |
513 | } | |
514 | { | |
515 | my $fh = IO::File->new($fd_filename, "r") | |
516 | or skip("Can't open file: $!", 1); | |
517 | my $data = <$fh>; | |
518 | is($data, "test", "make sure data written to fd"); | |
519 | } | |
520 | unlink $fd_filename; | |
521 | } | |
522 | ||
523 | ok(io_bufchain_test(), "check bufchain functions"); | |
524 | ||
525 | is(io_buffer_test("test3"), "test3", "check io_new_buffer() and i_io_read"); | |
526 | ||
527 | is(io_peekn_test("test5"), "test5", "check i_io_peekn"); | |
528 | ||
529 | is(io_gets_test("test"), "tes", "check i_io_gets()"); | |
530 | ||
531 | is(io_getc_test("ABC"), ord "A", "check i_io_getc(_imp)?"); | |
532 | ||
533 | is(io_getc_test("XYZ"), ord "X", "check i_io_peekc(_imp)?"); | |
d8d215e3 TC |
534 | |
535 | for my $bits (8, 16) { | |
536 | print "# bits: $bits\n"; | |
537 | ||
538 | # the floating point processing is a little more accurate | |
539 | my $bump = $bits == 16 ? 1 : 0; | |
540 | { | |
541 | my $im = Imager->new(xsize => 10, ysize => 10, channels => 3, bits => $bits); | |
542 | ok($im->box(filled => 1, color => '#808080'), "fill work image with gray"); | |
543 | ok(test_render_color($im), | |
544 | "call render_color on 3 channel image"); | |
545 | is_color3($im->getpixel(x => 0, y => 0), 128, 128, 128, | |
546 | "check zero coverage, alpha 255 color, bits $bits"); | |
547 | is_color3($im->getpixel(x => 1, y => 0), 128, 191+$bump, 63+$bump, | |
548 | "check 128 coverage, alpha 255 color, bits $bits"); | |
549 | is_color3($im->getpixel(x => 2, y => 0), 128, 255, 0, | |
550 | "check 255 coverage, alpha 255 color, bits $bits"); | |
551 | ||
552 | is_color3($im->getpixel(x => 0, y => 1), 128, 128, 128, | |
553 | "check zero coverage, alpha 128 color, bits $bits"); | |
554 | is_color3($im->getpixel(x => 1, y => 1), 128, 159+$bump, 95+$bump, | |
555 | "check 128 coverage, alpha 128 color, bits $bits"); | |
556 | is_color3($im->getpixel(x => 2, y => 1), 128, 191+$bump, 63+$bump, | |
557 | "check 255 coverage, alpha 128 color, bits $bits"); | |
558 | ||
559 | is_color3($im->getpixel(x => 0, y => 2), 128, 128, 128, | |
560 | "check zero coverage, alpha 0 color, bits $bits"); | |
561 | is_color3($im->getpixel(x => 1, y => 2), 128, 128, 128, | |
562 | "check 128 coverage, alpha 0 color, bits $bits"); | |
563 | is_color3($im->getpixel(x => 2, y => 2), 128, 128, 128, | |
564 | "check 255 coverage, alpha 0 color, bits $bits"); | |
565 | } | |
566 | { | |
567 | my $im = Imager->new(xsize => 10, ysize => 10, channels => 4, bits => $bits); | |
568 | ok($im->box(filled => 1, color => '#808080'), "fill work image with opaque gray"); | |
569 | ok(test_render_color($im), | |
570 | "call render_color on 4 channel image"); | |
571 | is_color4($im->getpixel(x => 0, y => 0), 128, 128, 128, 255, | |
572 | "check zero coverage, alpha 255 color, bits $bits"); | |
573 | is_color4($im->getpixel(x => 1, y => 0), 128, 191+$bump, 63+$bump, 255, | |
574 | "check 128 coverage, alpha 255 color, bits $bits"); | |
575 | is_color4($im->getpixel(x => 2, y => 0), 128, 255, 0, 255, | |
576 | "check 255 coverage, alpha 255 color, bits $bits"); | |
577 | ||
578 | is_color4($im->getpixel(x => 0, y => 1), 128, 128, 128, 255, | |
579 | "check zero coverage, alpha 128 color, bits $bits"); | |
580 | is_color4($im->getpixel(x => 1, y => 1), 128, 159+$bump, 95+$bump, 255, | |
581 | "check 128 coverage, alpha 128 color, bits $bits"); | |
582 | is_color4($im->getpixel(x => 2, y => 1), 128, 191+$bump, 63+$bump, 255, | |
583 | "check 255 coverage, alpha 128 color, bits $bits"); | |
584 | ||
585 | is_color4($im->getpixel(x => 0, y => 2), 128, 128, 128, 255, | |
586 | "check zero coverage, alpha 0 color, bits $bits"); | |
587 | is_color4($im->getpixel(x => 1, y => 2), 128, 128, 128, 255, | |
588 | "check 128 coverage, alpha 0 color, bits $bits"); | |
589 | is_color4($im->getpixel(x => 2, y => 2), 128, 128, 128, 255, | |
590 | "check 255 coverage, alpha 0 color, bits $bits"); | |
591 | } | |
592 | ||
593 | { | |
594 | my $im = Imager->new(xsize => 10, ysize => 10, channels => 4, bits => $bits); | |
595 | ok($im->box(filled => 1, color => Imager::Color->new(128, 128, 128, 64)), "fill work image with translucent gray"); | |
596 | ok(test_render_color($im), | |
597 | "call render_color on 4 channel image"); | |
598 | is_color4($im->getpixel(x => 0, y => 0), 128, 128, 128, 64, | |
599 | "check zero coverage, alpha 255 color, bits $bits"); | |
600 | is_color4($im->getpixel(x => 1, y => 0), 128, 230, 25+$bump, 159+$bump, | |
601 | "check 128 coverage, alpha 255 color, bits $bits"); | |
602 | is_color4($im->getpixel(x => 2, y => 0), 128, 255, 0, 255, | |
603 | "check 255 coverage, alpha 255 color, bits $bits"); | |
604 | ||
605 | is_color4($im->getpixel(x => 0, y => 1), 128, 128, 128, 64, | |
606 | "check zero coverage, alpha 128 color, bits $bits"); | |
607 | is_color4($im->getpixel(x => 1, y => 1), 129-$bump, 202-$bump, 55, 111+$bump, | |
608 | "check 128 coverage, alpha 128 color, bits $bits"); | |
609 | is_color4($im->getpixel(x => 2, y => 1), 128, 230, 25+$bump, 159+$bump, | |
610 | "check 255 coverage, alpha 128 color, bits $bits"); | |
611 | ||
612 | is_color4($im->getpixel(x => 0, y => 2), 128, 128, 128, 64, | |
613 | "check zero coverage, alpha 0 color, bits $bits"); | |
614 | is_color4($im->getpixel(x => 1, y => 2), 128, 128, 128, 64, | |
615 | "check 128 coverage, alpha 0 color, bits $bits"); | |
616 | is_color4($im->getpixel(x => 2, y => 2), 128, 128, 128, 64, | |
617 | "check 255 coverage, alpha 0 color, bits $bits"); | |
618 | } | |
619 | } | |
23c6bf56 TC |
620 | |
621 | { | |
622 | my $im = Imager->new(xsize => 10, ysize => 10); | |
623 | is(raw_psamp($im, 4), -1, "bad channel list (4) for psamp should fail"); | |
624 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
625 | "check message"); | |
626 | is(raw_psamp($im, 0), -1, "bad channel list (0) for psamp should fail"); | |
627 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
628 | "check message"); | |
629 | is(raw_psampf($im, 4), -1, "bad channel list (4) for psampf should fail"); | |
630 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
631 | "check message"); | |
632 | is(raw_psampf($im, 0), -1, "bad channel list (0) for psampf should fail"); | |
633 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
634 | "check message"); | |
635 | } | |
636 | ||
637 | { | |
638 | my $im = Imager->new(xsize => 10, ysize => 10, bits => 16); | |
639 | is(raw_psamp($im, 4), -1, "bad channel list (4) for psamp should fail (16-bit)"); | |
640 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
641 | "check message"); | |
642 | is(raw_psamp($im, 0), -1, "bad channel list (0) for psamp should fail (16-bit)"); | |
643 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
644 | "check message"); | |
645 | is(raw_psampf($im, 4), -1, "bad channel list (4) for psampf should fail (16-bit)"); | |
646 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
647 | "check message"); | |
648 | is(raw_psampf($im, 0), -1, "bad channel list (0) for psampf should fail (16-bit)"); | |
649 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
650 | "check message"); | |
651 | } | |
652 | ||
653 | { | |
654 | my $im = Imager->new(xsize => 10, ysize => 10, bits => 'double'); | |
655 | is(raw_psamp($im, 4), -1, "bad channel list (4) for psamp should fail (double)"); | |
656 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
657 | "check message"); | |
658 | is(raw_psamp($im, 0), -1,, "bad channel list (0) for psamp should fail (double)"); | |
659 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
660 | "check message"); | |
661 | is(raw_psampf($im, 4), -1, "bad channel list (4) for psampf should fail (double)"); | |
662 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
663 | "check message"); | |
664 | is(raw_psampf($im, 0), -1, "bad channel list (0) for psampf should fail (double)"); | |
665 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
666 | "check message"); | |
667 | } | |
668 | ||
669 | { | |
670 | my $im = Imager->new(xsize => 10, ysize => 10, type => "paletted"); | |
671 | is(raw_psamp($im, 4), -1, "bad channel list (4) for psamp should fail (paletted)"); | |
672 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
673 | "check message"); | |
674 | is(raw_psamp($im, 0), -1, "bad channel list (0) for psamp should fail (paletted)"); | |
675 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
676 | "check message"); | |
677 | is(raw_psampf($im, 4), -1, "bad channel list (4) for psampf should fail (paletted)"); | |
678 | is(_get_error(), "chan_count 4 out of range, must be >0, <= channels", | |
679 | "check message"); | |
680 | is(raw_psampf($im, 0), -1, "bad channel list (0) for psampf should fail (paletted)"); | |
681 | is(_get_error(), "chan_count 0 out of range, must be >0, <= channels", | |
682 | "check message"); | |
683 | is($im->type, "paletted", "make sure we kept the image type"); | |
684 | } | |
685 | ||
24c9233d TC |
686 | ok(test_mutex(), "call mutex APIs"); |
687 | ||
fc02e376 TC |
688 | ok(test_slots(), "call slot APIs"); |
689 | ||
23c6bf56 TC |
690 | sub _get_error { |
691 | my @errors = Imager::i_errors(); | |
692 | return join(": ", map $_->[0], @errors); | |
693 | } |