3 # this tests both the Inline interface and the API
6 eval "require Inline::C;";
7 plan skip_all => "Inline required for testing API" if $@;
9 eval "require Parse::RecDescent;";
10 plan skip_all => "Could not load Parse::RecDescent" if $@;
13 plan skip_all => "Inline won't work in directories with spaces"
16 plan skip_all => "perl 5.005_04, 5.005_05 too buggy"
17 if $] =~ /^5\.005_0[45]$/;
19 -d "testout" or mkdir "testout";
23 Inline->import(with => 'Imager');
24 Inline->import("FORCE"); # force rebuild
26 Inline->bind(C => <<'EOS');
29 int pixel_count(Imager::ImgRaw im) {
30 return im->xsize * im->ysize;
33 int count_color(Imager::ImgRaw im, Imager::Color c) {
34 int count = 0, x, y, chan;
37 for (x = 0; x < im->xsize; ++x) {
38 for (y = 0; y < im->ysize; ++y) {
40 i_gpix(im, x, y, &read_c);
41 for (chan = 0; chan < im->channels; ++chan) {
42 if (read_c.channel[chan] != c->channel[chan]) {
56 i_img *im = i_img_8_new(10, 10, 3);
58 c.channel[0] = c.channel[1] = c.channel[2] = 255;
59 i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &c);
64 /* tests that all of the APIs are visible - most of them anyway */
65 Imager do_lots(Imager src) {
66 i_img *im = i_img_8_new(100, 100, 3);
67 i_img *fill_im = i_img_8_new(5, 5, 3);
69 i_color red, blue, green, black, temp_color;
71 i_fill_t *hatch, *fhatch_fill;
73 i_fill_t *solid_fill, *fsolid_fill;
76 double matrix[9] = /* 30 degree rotation */
87 red.channel[0] = 255; red.channel[1] = 0; red.channel[2] = 0;
89 blue.channel[0] = 0; blue.channel[1] = 0; blue.channel[2] = 255;
90 blue.channel[3] = 255;
91 green.channel[0] = 0; green.channel[1] = 255; green.channel[2] = 0;
92 green.channel[3] = 255;
93 black.channel[0] = black.channel[1] = black.channel[2] = 0;
94 black.channel[3] = 255;
95 hatch = i_new_fill_hatch(&red, &blue, 0, 1, NULL, 0, 0);
97 i_box(im, 0, 0, 9, 9, &red);
98 i_box_filled(im, 10, 0, 19, 9, &blue);
99 i_box_cfill(im, 20, 0, 29, 9, hatch);
101 /* make an image fill, and try it */
102 i_box_cfill(fill_im, 0, 0, 4, 4, hatch);
103 im_fill = i_new_fill_image(fill_im, matrix, 2, 2, 0);
105 i_box_cfill(im, 30, 0, 39, 9, im_fill);
107 /* make a solid fill and try it */
108 solid_fill = i_new_fill_solid(&red, 0);
109 i_box_cfill(im, 40, 0, 49, 9, solid_fill);
112 redf.channel[0] = 1.0; redf.channel[1] = 0; redf.channel[2] = 0;
113 redf.channel[3] = 1.0;
114 bluef.channel[0] = 0; bluef.channel[1] = 0; bluef.channel[2] = 1.0;
115 bluef.channel[3] = 1.0;
117 fsolid_fill = i_new_fill_solidf(&redf, 0);
118 i_box_cfill(im, 50, 0, 59, 9, fsolid_fill);
120 fhatch_fill = i_new_fill_hatchf(&redf, &bluef, 0, 2, NULL, 0, 0);
121 i_box_cfill(im, 60, 0, 69, 9, fhatch_fill);
129 fseg.type = i_fst_linear;
130 fseg.color = i_fc_hue_down;
131 fount_fill = i_new_fill_fount(70, 0, 80, 0, i_ft_linear, i_fr_triangle, 0, i_fts_none, 1, 1, &fseg);
133 i_box_cfill(im, 70, 0, 79, 9, fount_fill);
135 i_line(im, 0, 10, 10, 15, &blue, 1);
136 i_line_aa(im, 0, 19, 10, 15, &red, 1);
138 i_arc(im, 15, 15, 4, 45, 160, &blue);
139 i_arc_aa(im, 25, 15, 4, 75, 280, &red);
140 i_arc_cfill(im, 35, 15, 4, 0, 215, hatch);
141 i_arc_aa_cfill(im, 45, 15, 4, 30, 210, hatch);
142 i_circle_aa(im, 55, 15, 4, &red);
144 i_box(im, 61, 11, 68, 18, &red);
145 i_flood_fill(im, 65, 15, &blue);
146 i_box(im, 71, 11, 78, 18, &red);
147 i_flood_cfill(im, 75, 15, hatch);
149 i_box_filled(im, 1, 21, 9, 24, &red);
150 i_box_filled(im, 1, 25, 9, 29, &blue);
151 i_flood_fill_border(im, 5, 25, &green, &black);
153 i_box_filled(im, 11, 21, 19, 24, &red);
154 i_box_filled(im, 11, 25, 19, 29, &blue);
155 i_flood_cfill_border(im, 15, 25, hatch, &black);
157 i_fill_destroy(fount_fill);
158 i_fill_destroy(fhatch_fill);
159 i_fill_destroy(solid_fill);
160 i_fill_destroy(fsolid_fill);
161 i_fill_destroy(hatch);
162 i_fill_destroy(im_fill);
163 i_img_destroy(fill_im);
165 /* make sure we can make each image type */
166 testim = i_img_16_new(100, 100, 3);
167 i_img_destroy(testim);
168 testim = i_img_double_new(100, 100, 3);
169 i_img_destroy(testim);
170 testim = i_img_pal_new(100, 100, 3, 256);
171 i_img_destroy(testim);
172 testim = i_sametype(im, 50, 50);
173 i_img_destroy(testim);
174 testim = i_sametype_chans(im, 50, 50, 4);
175 i_img_destroy(testim);
178 i_push_error(0, "Hello");
179 i_push_errorf(0, "%s", "World");
181 /* make sure tags create/destroy work */
183 i_tags_destroy(&tags);
185 block = mymalloc(20);
186 block = myrealloc(block, 50);
189 i_tags_set(&im->tags, "lots_string", "foo", -1);
190 i_tags_setn(&im->tags, "lots_number", 101);
192 if (!i_tags_find(&im->tags, "lots_number", 0, &entry)) {
193 i_push_error(0, "lots_number tag not found");
197 i_tags_delete(&im->tags, entry);
199 /* these won't delete anything, but it makes sure the macros and function
200 pointers are correct */
201 i_tags_delbyname(&im->tags, "unknown");
202 i_tags_delbycode(&im->tags, 501);
203 i_tags_set_float(&im->tags, "lots_float", 0, 3.14);
204 if (!i_tags_get_float(&im->tags, "lots_float", 0, &temp_double)) {
205 i_push_error(0, "lots_float not found");
209 if (fabs(temp_double - 3.14) > 0.001) {
210 i_push_errorf(0, "lots_float incorrect %g", temp_double);
214 i_tags_set_float2(&im->tags, "lots_float2", 0, 100 * sqrt(2.0), 5);
215 if (!i_tags_get_int(&im->tags, "lots_float2", 0, &entry)) {
216 i_push_error(0, "lots_float2 not found as int");
221 i_push_errorf(0, "lots_float2 unexpected value %d", entry);
226 i_tags_set_color(&im->tags, "lots_color", 0, &red);
227 if (!i_tags_get_color(&im->tags, "lots_color", 0, &temp_color)) {
228 i_push_error(0, "lots_color not found as color");
238 my $im = Imager->new(xsize=>50, ysize=>50);
239 is(pixel_count($im), 2500, "pixel_count");
241 my $black = Imager::Color->new(0,0,0);
242 is(count_color($im, $black), 2500, "count_color black on black image");
244 my $im2 = make_10x10();
245 my $white = Imager::Color->new(255, 255, 255);
246 is(count_color($im2, $white), 100, "check new image white count");
247 ok($im2->box(filled=>1, xmin=>1, ymin=>1, xmax => 8, ymax=>8, color=>$black),
249 is(count_color($im2, $black), 64, "check modified black count");
250 is(count_color($im2, $white), 36, "check modified white count");
252 my $im3 = do_lots($im2);
253 ok($im3, "do_lots()")
254 or print "# ", Imager->_error_as_msg, "\n";
255 ok($im3->write(file=>'testout/t82lots.ppm'), "write t82lots.ppm");
258 # the T_IMAGER_FULL_IMAGE typemap entry was returning a blessed
259 # hash with an extra ref, causing memory leaks
261 my $im = make_10x10();
262 my $im2 = Imager->new(xsize => 10, ysize => 10);
264 my $imb = B::svref_2object($im);
265 my $im2b = B::svref_2object($im2);
266 is ($imb->REFCNT, $im2b->REFCNT,
267 "check refcnt of imager object hash between normal and typemap generated");