17 typedef io_glue* Imager__IO;
18 typedef i_color* Imager__Color;
19 typedef i_fcolor* Imager__Color__Float;
20 typedef i_img* Imager__ImgRaw;
24 typedef TT_Fonthandle* Imager__TTHandle;
28 typedef FT2_Fonthandle* Imager__Font__FT2;
32 void my_SvREFCNT_dec(void *p) {
36 typedef struct i_reader_data_tag
38 /* presumably a CODE ref or name of a sub */
42 /* used by functions that want callbacks */
43 static int read_callback(char *userdata, char *buffer, int need, int want) {
44 i_reader_data *rd = (i_reader_data *)userdata;
48 dSP; dTARG = sv_newmortal();
49 /* thanks to Simon Cozens for help with the dTARG above */
59 count = perl_call_sv(rd->sv, G_SCALAR);
64 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
70 char *ptr = SvPV(data, len);
72 croak("Too much data returned in reader callback");
74 memcpy(buffer, ptr, len);
90 SV *sv; /* a coderef or sub name */
93 /* used by functions that want callbacks */
94 static int write_callback(char *userdata, char const *data, int size) {
95 i_writer_data *wd = (i_writer_data *)userdata;
105 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
108 count = perl_call_sv(wd->sv, G_SCALAR);
113 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
116 success = SvTRUE(sv);
130 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
133 for (i = 0; i < count; ++i)
134 if (strEQ(names[i].name, name))
135 return names[i].value;
139 static struct value_name transp_names[] =
142 { "threshold", tr_threshold },
143 { "errdiff", tr_errdiff },
144 { "ordered", tr_ordered, },
147 static struct value_name make_color_names[] =
149 { "none", mc_none, },
150 { "webmap", mc_web_map, },
151 { "addi", mc_addi, },
154 static struct value_name translate_names[] =
157 { "giflib", pt_giflib, },
159 { "closest", pt_closest, },
160 { "perturb", pt_perturb, },
161 { "errdiff", pt_errdiff, },
164 static struct value_name errdiff_names[] =
166 { "floyd", ed_floyd, },
167 { "jarvis", ed_jarvis, },
168 { "stucki", ed_stucki, },
169 { "custom", ed_custom, },
172 static struct value_name orddith_names[] =
174 { "random", od_random, },
175 { "dot8", od_dot8, },
176 { "dot4", od_dot4, },
177 { "hline", od_hline, },
178 { "vline", od_vline, },
179 { "/line", od_slashline, },
180 { "slashline", od_slashline, },
181 { "\\line", od_backline, },
182 { "backline", od_backline, },
183 { "tiny", od_tiny, },
184 { "custom", od_custom, },
188 hv_fetch_bool(HV *hv, char *name, int def) {
191 sv = hv_fetch(hv, name, strlen(name), 0);
200 hv_fetch_int(HV *hv, char *name, int def) {
203 sv = hv_fetch(hv, name, strlen(name), 0);
211 /* look through the hash for quantization options */
212 static void handle_quant_opts(i_quantize *quant, HV *hv)
214 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
220 sv = hv_fetch(hv, "transp", 6, 0);
221 if (sv && *sv && (str = SvPV(*sv, len))) {
223 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
225 if (quant->transp != tr_none) {
226 quant->tr_threshold = 127;
227 sv = hv_fetch(hv, "tr_threshold", 12, 0);
229 quant->tr_threshold = SvIV(*sv);
231 if (quant->transp == tr_errdiff) {
232 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
233 if (sv && *sv && (str = SvPV(*sv, len)))
234 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
236 if (quant->transp == tr_ordered) {
237 quant->tr_orddith = od_tiny;
238 sv = hv_fetch(hv, "tr_orddith", 10, 0);
239 if (sv && *sv && (str = SvPV(*sv, len)))
240 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
242 if (quant->tr_orddith == od_custom) {
243 sv = hv_fetch(hv, "tr_map", 6, 0);
244 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
245 AV *av = (AV*)SvRV(*sv);
246 len = av_len(av) + 1;
247 if (len > sizeof(quant->tr_custom))
248 len = sizeof(quant->tr_custom);
249 for (i = 0; i < len; ++i) {
250 SV **sv2 = av_fetch(av, i, 0);
252 quant->tr_custom[i] = SvIV(*sv2);
255 while (i < sizeof(quant->tr_custom))
256 quant->tr_custom[i++] = 0;
261 quant->make_colors = mc_addi;
262 sv = hv_fetch(hv, "make_colors", 11, 0);
263 if (sv && *sv && (str = SvPV(*sv, len))) {
265 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
267 sv = hv_fetch(hv, "colors", 6, 0);
268 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
269 /* needs to be an array of Imager::Color
270 note that the caller allocates the mc_color array and sets mc_size
272 AV *av = (AV *)SvRV(*sv);
273 quant->mc_count = av_len(av)+1;
274 if (quant->mc_count > quant->mc_size)
275 quant->mc_count = quant->mc_size;
276 for (i = 0; i < quant->mc_count; ++i) {
277 SV **sv1 = av_fetch(av, i, 0);
278 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
279 i_color *col = (i_color *)SvIV((SV*)SvRV(*sv1));
280 quant->mc_colors[i] = *col;
284 sv = hv_fetch(hv, "max_colors", 10, 0);
287 if (i <= quant->mc_size && i >= quant->mc_count)
291 quant->translate = pt_closest;
292 sv = hv_fetch(hv, "translate", 9, 0);
293 if (sv && *sv && (str = SvPV(*sv, len))) {
294 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
296 sv = hv_fetch(hv, "errdiff", 7, 0);
297 if (sv && *sv && (str = SvPV(*sv, len))) {
298 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
300 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
301 /* get the error diffusion map */
302 sv = hv_fetch(hv, "errdiff_width", 13, 0);
304 quant->ed_width = SvIV(*sv);
305 sv = hv_fetch(hv, "errdiff_height", 14, 0);
307 quant->ed_height = SvIV(*sv);
308 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
310 quant->ed_orig = SvIV(*sv);
311 if (quant->ed_width > 0 && quant->ed_height > 0) {
313 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
314 sv = hv_fetch(hv, "errdiff_map", 11, 0);
315 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
316 AV *av = (AV*)SvRV(*sv);
317 len = av_len(av) + 1;
318 if (len > quant->ed_width * quant->ed_height)
319 len = quant->ed_width * quant->ed_height;
320 for (i = 0; i < len; ++i) {
321 SV **sv2 = av_fetch(av, i, 0);
323 quant->ed_map[i] = SvIV(*sv2);
324 sum += quant->ed_map[i];
330 myfree(quant->ed_map);
332 quant->errdiff = ed_floyd;
336 sv = hv_fetch(hv, "perturb", 7, 0);
338 quant->perturb = SvIV(*sv);
341 /* look through the hash for options to add to opts */
342 static void handle_gif_opts(i_gif_opts *opts, HV *hv)
346 /**((char *)0) = '\0';*/
347 opts->each_palette = hv_fetch_bool(hv, "gif_each_palette", 0);
348 opts->interlace = hv_fetch_bool(hv, "interlace", 0);
350 sv = hv_fetch(hv, "gif_delays", 10, 0);
351 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
352 AV *av = (AV*)SvRV(*sv);
353 opts->delay_count = av_len(av)+1;
354 opts->delays = mymalloc(sizeof(int) * opts->delay_count);
355 for (i = 0; i < opts->delay_count; ++i) {
356 SV *sv1 = *av_fetch(av, i, 0);
357 opts->delays[i] = SvIV(sv1);
360 sv = hv_fetch(hv, "gif_user_input", 14, 0);
361 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
362 AV *av = (AV*)SvRV(*sv);
363 opts->user_input_count = av_len(av)+1;
364 opts->user_input_flags = mymalloc(opts->user_input_count);
365 for (i = 0; i < opts->user_input_count; ++i) {
366 SV *sv1 = *av_fetch(av, i, 0);
367 opts->user_input_flags[i] = SvIV(sv1) != 0;
370 sv = hv_fetch(hv, "gif_disposal", 12, 0);
371 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
372 AV *av = (AV*)SvRV(*sv);
373 opts->disposal_count = av_len(av)+1;
374 opts->disposal = mymalloc(opts->disposal_count);
375 for (i = 0; i < opts->disposal_count; ++i) {
376 SV *sv1 = *av_fetch(av, i, 0);
377 opts->disposal[i] = SvIV(sv1);
380 sv = hv_fetch(hv, "gif_tran_color", 14, 0);
381 if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
382 i_color *col = (i_color *)SvIV((SV *)SvRV(*sv));
383 opts->tran_color = *col;
385 sv = hv_fetch(hv, "gif_positions", 13, 0);
386 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
387 AV *av = (AV *)SvRV(*sv);
388 opts->position_count = av_len(av) + 1;
389 opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
390 for (i = 0; i < opts->position_count; ++i) {
391 SV **sv2 = av_fetch(av, i, 0);
392 opts->positions[i].x = opts->positions[i].y = 0;
393 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
394 AV *av2 = (AV*)SvRV(*sv2);
396 sv3 = av_fetch(av2, 0, 0);
398 opts->positions[i].x = SvIV(*sv3);
399 sv3 = av_fetch(av2, 1, 0);
401 opts->positions[i].y = SvIV(*sv3);
405 /* Netscape2.0 loop count extension */
406 opts->loop_count = hv_fetch_int(hv, "gif_loop_count", 0);
408 opts->eliminate_unused = hv_fetch_bool(hv, "gif_eliminate_unused", 1);
411 /* copies the color map from the hv into the colors member of the HV */
412 static void copy_colors_back(HV *hv, i_quantize *quant) {
418 sv = hv_fetch(hv, "colors", 6, 0);
419 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
422 ref = newRV_inc((SV*) av);
423 sv = hv_store(hv, "colors", 6, ref, 0);
426 av = (AV *)SvRV(*sv);
428 av_extend(av, quant->mc_count+1);
429 for (i = 0; i < quant->mc_count; ++i) {
430 i_color *in = quant->mc_colors+i;
431 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
432 work = sv_newmortal();
433 sv_setref_pv(work, "Imager::Color", (void *)c);
435 if (!av_store(av, i, work)) {
441 /* loads the segments of a fountain fill into an array */
442 i_fountain_seg *load_fount_segs(AV *asegs, int *count) {
443 /* Each element of segs must contain:
444 [ start, middle, end, c0, c1, segtype, colortrans ]
445 start, middle, end are doubles from 0 to 1
446 c0, c1 are Imager::Color::Float or Imager::Color objects
447 segtype, colortrans are ints
452 i_fountain_seg *segs;
456 *count = av_len(asegs)+1;
458 croak("i_fountain must have at least one segment");
459 segs = mymalloc(sizeof(i_fountain_seg) * *count);
460 for(i = 0; i < *count; i++) {
461 SV **sv1 = av_fetch(asegs, i, 0);
462 if (!sv1 || !*sv1 || !SvROK(*sv1)
463 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
465 croak("i_fountain: segs must be an arrayref of arrayrefs");
467 aseg = (AV *)SvRV(*sv1);
468 if (av_len(aseg) != 7-1) {
470 croak("i_fountain: a segment must have 7 members");
472 for (j = 0; j < 3; ++j) {
473 SV **sv2 = av_fetch(aseg, j, 0);
476 croak("i_fountain: XS error");
478 work[j] = SvNV(*sv2);
480 segs[i].start = work[0];
481 segs[i].middle = work[1];
482 segs[i].end = work[2];
483 for (j = 0; j < 2; ++j) {
484 SV **sv3 = av_fetch(aseg, 3+j, 0);
485 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
486 (!sv_derived_from(*sv3, "Imager::Color")
487 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
489 croak("i_fountain: segs must contain colors in elements 3 and 4");
491 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
492 segs[i].c[j] = *(i_fcolor *)SvIV((SV *)SvRV(*sv3));
495 i_color c = *(i_color *)SvIV((SV *)SvRV(*sv3));
497 for (ch = 0; ch < MAXCHANNELS; ++ch) {
498 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
502 for (j = 0; j < 2; ++j) {
503 SV **sv2 = av_fetch(aseg, j+5, 0);
506 croak("i_fountain: XS error");
508 worki[j] = SvIV(*sv2);
510 segs[i].type = worki[0];
511 segs[i].color = worki[1];
517 /* I don't think ICLF_* names belong at the C interface
518 this makes the XS code think we have them, to let us avoid
519 putting function bodies in the XS code
521 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
522 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
524 /* for the fill objects
525 Since a fill object may later have dependent images, (or fills!)
526 we need perl wrappers - oh well
528 #define IFILL_DESTROY(fill) i_fill_destroy(fill);
529 typedef i_fill_t* Imager__FillHandle;
531 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
534 ICL_new_internal(r,g,b,a)
546 ICL_set_internal(cl,r,g,b,a)
553 ICL_set_internal(cl, r, g, b, a);
567 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
568 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
569 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
570 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
576 RETVAL = mymalloc(sizeof(i_color));
578 i_hsv_to_rgb(RETVAL);
586 RETVAL = mymalloc(sizeof(i_color));
588 i_rgb_to_hsv(RETVAL);
594 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
597 ICLF_new_internal(r, g, b, a)
605 Imager::Color::Float cl
609 Imager::Color::Float cl
613 EXTEND(SP, MAXCHANNELS);
614 for (ch = 0; ch < MAXCHANNELS; ++ch) {
615 /* printf("%d: %g\n", ch, cl->channel[ch]); */
616 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
620 ICLF_set_internal(cl,r,g,b,a)
621 Imager::Color::Float cl
636 Imager::Color::Float c
638 RETVAL = mymalloc(sizeof(i_fcolor));
640 i_hsv_to_rgbf(RETVAL);
646 Imager::Color::Float c
648 RETVAL = mymalloc(sizeof(i_fcolor));
650 i_rgb_to_hsvf(RETVAL);
655 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
669 MODULE = Imager PACKAGE = Imager
691 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
704 tlength = io_slurp(ig, &data);
706 PUSHs(sv_2mortal(newSVpv(data,tlength)));
710 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
717 MODULE = Imager PACKAGE = Imager
730 while( (item=i_format_list[i++]) != NULL ) {
732 PUSHs(sv_2mortal(newSVpv(item,0)));
749 i_img_empty_ch(im,x,y,ch)
776 PUSHs(sv_2mortal(newSViv(info[0])));
777 PUSHs(sv_2mortal(newSViv(info[1])));
778 PUSHs(sv_2mortal(newSViv(info[2])));
779 PUSHs(sv_2mortal(newSViv(info[3])));
785 i_img_setmask(im,ch_mask)
794 i_img_getchannels(im)
802 PUSHs(im->idata ? sv_2mortal(newSVpv(im->idata, im->bytes))
807 i_draw(im,x1,y1,x2,y2,val)
816 i_line_aa(im,x1,y1,x2,y2,val)
825 i_box(im,x1,y1,x2,y2,val)
834 i_box_filled(im,x1,y1,x2,y2,val)
843 i_box_cfill(im,x1,y1,x2,y2,fill)
849 Imager::FillHandle fill
852 i_arc(im,x,y,rad,d1,d2,val)
862 i_arc_cfill(im,x,y,rad,d1,d2,fill)
869 Imager::FillHandle fill
874 i_circle_aa(im,x,y,rad,val)
884 i_bezier_multi(im,xc,yc,val)
897 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
898 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
899 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
900 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
901 av1=(AV*)SvRV(ST(1));
902 av2=(AV*)SvRV(ST(2));
903 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
905 x=mymalloc( len*sizeof(double) );
906 y=mymalloc( len*sizeof(double) );
908 sv1=(*(av_fetch(av1,i,0)));
909 sv2=(*(av_fetch(av2,i,0)));
910 x[i]=(double)SvNV(sv1);
911 y[i]=(double)SvNV(sv2);
913 i_bezier_multi(im,len,x,y,val);
919 i_poly_aa(im,xc,yc,val)
932 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
933 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
934 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
935 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
936 av1=(AV*)SvRV(ST(1));
937 av2=(AV*)SvRV(ST(2));
938 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
940 x=mymalloc( len*sizeof(double) );
941 y=mymalloc( len*sizeof(double) );
943 sv1=(*(av_fetch(av1,i,0)));
944 sv2=(*(av_fetch(av2,i,0)));
945 x[i]=(double)SvNV(sv1);
946 y[i]=(double)SvNV(sv2);
948 i_poly_aa(im,len,x,y,val);
955 i_flood_fill(im,seedx,seedy,dcol)
962 i_flood_cfill(im,seedx,seedy,fill)
966 Imager::FillHandle fill
970 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
982 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1000 i_rubthru(im,src,tx,ty)
1007 i_flipxy(im, direction)
1012 i_rotate90(im, degrees)
1017 i_rotate_exact(im, amount)
1022 i_matrix_transform(im, xsize, ysize, matrix)
1033 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1034 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1035 av=(AV*)SvRV(ST(3));
1039 for (i = 0; i < len; ++i) {
1040 sv1=(*(av_fetch(av,i,0)));
1041 matrix[i] = SvNV(sv1);
1045 RETVAL = i_matrix_transform(im, xsize, ysize, matrix);
1050 i_gaussian(im,stdev)
1055 i_unsharp_mask(im,stdev,scale)
1070 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1071 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1072 av=(AV*)SvRV(ST(1));
1074 coeff=mymalloc( len*sizeof(float) );
1075 for(i=0;i<len;i++) {
1076 sv1=(*(av_fetch(av,i,0)));
1077 coeff[i]=(float)SvNV(sv1);
1079 i_conv(im,coeff,len);
1083 i_convert(im, src, coeff)
1097 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1098 croak("i_convert: parameter 3 must be an arrayref\n");
1099 avmain = (AV*)SvRV(ST(2));
1100 outchan = av_len(avmain)+1;
1101 /* find the biggest */
1103 for (j=0; j < outchan; ++j) {
1104 temp = av_fetch(avmain, j, 0);
1105 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1106 avsub = (AV*)SvRV(*temp);
1107 len = av_len(avsub)+1;
1112 coeff = mymalloc(sizeof(float) * outchan * inchan);
1113 for (j = 0; j < outchan; ++j) {
1114 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1115 len = av_len(avsub)+1;
1116 for (i = 0; i < len; ++i) {
1117 temp = av_fetch(avsub, i, 0);
1119 coeff[i+j*inchan] = SvNV(*temp);
1121 coeff[i+j*inchan] = 0;
1124 coeff[i++ + j*inchan] = 0;
1126 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1136 unsigned int mask = 0;
1142 unsigned char (*maps)[256];
1144 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1145 croak("i_map: parameter 2 must be an arrayref\n");
1146 avmain = (AV*)SvRV(ST(1));
1147 len = av_len(avmain)+1;
1148 if (im->channels < len) len = im->channels;
1150 maps = mymalloc( len * sizeof(unsigned char [256]) );
1152 for (j=0; j<len ; j++) {
1153 temp = av_fetch(avmain, j, 0);
1154 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1155 avsub = (AV*)SvRV(*temp);
1156 if(av_len(avsub) != 255) continue;
1158 for (i=0; i<256 ; i++) {
1160 temp = av_fetch(avsub, i, 0);
1161 val = temp ? SvIV(*temp) : 0;
1163 if (val>255) val = 255;
1168 i_map(im, maps, mask);
1190 i_t1_new(pfb,afm=NULL)
1195 i_t1_destroy(font_id)
1200 i_t1_cp(im,xb,yb,channel,fontnum,points,str,len,align)
1212 i_t1_bbox(fontnum,point,str,len)
1220 i_t1_bbox(fontnum,point,str,len,cords);
1222 PUSHs(sv_2mortal(newSViv(cords[0])));
1223 PUSHs(sv_2mortal(newSViv(cords[1])));
1224 PUSHs(sv_2mortal(newSViv(cords[2])));
1225 PUSHs(sv_2mortal(newSViv(cords[3])));
1226 PUSHs(sv_2mortal(newSViv(cords[4])));
1227 PUSHs(sv_2mortal(newSViv(cords[5])));
1232 i_t1_text(im,xb,yb,cl,fontnum,points,str,len,align)
1253 i_tt_destroy(handle)
1254 Imager::TTHandle handle
1259 i_tt_text(handle,im,xb,yb,cl,points,str,len,smooth)
1260 Imager::TTHandle handle
1272 i_tt_cp(handle,im,xb,yb,channel,points,str,len,smooth)
1273 Imager::TTHandle handle
1286 i_tt_bbox(handle,point,str,len)
1287 Imager::TTHandle handle
1294 if ((rc=i_tt_bbox(handle,point,str,len,cords))) {
1296 PUSHs(sv_2mortal(newSViv(cords[0])));
1297 PUSHs(sv_2mortal(newSViv(cords[1])));
1298 PUSHs(sv_2mortal(newSViv(cords[2])));
1299 PUSHs(sv_2mortal(newSViv(cords[3])));
1300 PUSHs(sv_2mortal(newSViv(cords[4])));
1301 PUSHs(sv_2mortal(newSViv(cords[5])));
1312 i_writejpeg_wiol(im, ig, qfactor)
1328 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
1329 if (iptc_itext == NULL) {
1332 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1337 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1339 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1352 i_readtiff_wiol(ig, length)
1358 i_writetiff_wiol(im, ig)
1363 i_writetiff_wiol_faxable(im, ig, fine)
1369 #endif /* HAVE_LIBTIFF */
1378 i_readpng_wiol(ig, length)
1384 i_writepng_wiol(im, ig)
1397 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
1400 i_writegif(im,fd,colors,pixdev,fixed)
1407 Imager__Color fixed;
1414 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
1415 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1416 av=(AV*)SvRV(ST(4));
1417 fixedlen=av_len(av)+1;
1418 fixed=mymalloc( fixedlen*sizeof(i_color) );
1419 for(i=0;i<fixedlen;i++) {
1420 sv1=(*(av_fetch(av,i,0)));
1421 if (sv_derived_from(sv1, "Imager::Color")) {
1422 Itmp = SvIV((SV*)SvRV(sv1));
1423 tmp = (i_color*) Itmp;
1424 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
1427 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
1429 ST(0) = sv_newmortal();
1430 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1431 else sv_setiv(ST(0), (IV)RETVAL);
1437 i_writegifmc(im,fd,colors)
1444 i_writegif_gen(fd, ...)
1450 i_img **imgs = NULL;
1456 croak("Usage: i_writegif_gen(fd,hashref, images...)");
1457 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1458 croak("i_writegif_gen: Second argument must be a hash ref");
1459 hv = (HV *)SvRV(ST(1));
1460 memset(&quant, 0, sizeof(quant));
1461 quant.mc_size = 256;
1462 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
1463 memset(&opts, 0, sizeof(opts));
1464 handle_quant_opts(&quant, hv);
1465 handle_gif_opts(&opts, hv);
1466 img_count = items - 2;
1468 if (img_count < 1) {
1471 i_push_error(0, "You need to specify images to save");
1474 imgs = mymalloc(sizeof(i_img *) * img_count);
1475 for (i = 0; i < img_count; ++i) {
1478 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1479 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1483 i_push_error(0, "Only images can be saved");
1489 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count, &opts);
1493 copy_colors_back(hv, &quant);
1496 ST(0) = sv_newmortal();
1497 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1498 else sv_setiv(ST(0), (IV)RETVAL);
1501 i_writegif_callback(cb, maxbuffer,...)
1506 i_img **imgs = NULL;
1513 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
1514 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1515 croak("i_writegif_callback: Second argument must be a hash ref");
1516 hv = (HV *)SvRV(ST(2));
1517 memset(&quant, 0, sizeof(quant));
1518 quant.mc_size = 256;
1519 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
1520 memset(&opts, 0, sizeof(opts));
1521 handle_quant_opts(&quant, hv);
1522 handle_gif_opts(&opts, hv);
1523 img_count = items - 3;
1525 if (img_count < 1) {
1529 imgs = mymalloc(sizeof(i_img *) * img_count);
1530 for (i = 0; i < img_count; ++i) {
1533 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1534 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1543 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count, &opts);
1547 copy_colors_back(hv, &quant);
1550 ST(0) = sv_newmortal();
1551 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1552 else sv_setiv(ST(0), (IV)RETVAL);
1565 colour_table = NULL;
1568 if(GIMME_V == G_ARRAY) {
1569 rimg = i_readgif(fd,&colour_table,&colours);
1571 /* don't waste time with colours if they aren't wanted */
1572 rimg = i_readgif(fd,NULL,NULL);
1575 if (colour_table == NULL) {
1578 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1581 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1582 /* I don't know if I have the reference counts right or not :( */
1583 /* Neither do I :-) */
1584 /* No Idea here either */
1587 av_extend(ct, colours);
1588 for(q=0; q<colours; q++) {
1590 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1591 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1593 myfree(colour_table);
1597 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1599 PUSHs(newRV_noinc((SV*)ct));
1607 i_readgif_scalar(...)
1611 unsigned int length;
1619 data = (char *)SvPV(ST(0), length);
1623 if(GIMME_V == G_ARRAY) {
1624 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
1626 /* don't waste time with colours if they aren't wanted */
1627 rimg=i_readgif_scalar(data,length,NULL,NULL);
1630 if (colour_table == NULL) {
1633 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1636 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1637 /* I don't know if I have the reference counts right or not :( */
1638 /* Neither do I :-) */
1640 av_extend(ct, colours);
1641 for(q=0; q<colours; q++) {
1643 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1644 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1646 myfree(colour_table);
1650 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1652 PUSHs(newRV_noinc((SV*)ct));
1656 i_readgif_callback(...)
1673 if(GIMME_V == G_ARRAY) {
1674 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
1676 /* don't waste time with colours if they aren't wanted */
1677 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
1680 if (colour_table == NULL) {
1683 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1686 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1687 /* I don't know if I have the reference counts right or not :( */
1688 /* Neither do I :-) */
1689 /* Neither do I - maybe I'll move this somewhere */
1691 av_extend(ct, colours);
1692 for(q=0; q<colours; q++) {
1694 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1695 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1697 myfree(colour_table);
1701 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1703 PUSHs(newRV_noinc((SV*)ct));
1714 imgs = i_readgif_multi(fd, &count);
1717 for (i = 0; i < count; ++i) {
1718 SV *sv = sv_newmortal();
1719 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1726 i_readgif_multi_scalar(data)
1731 unsigned int length;
1734 data = (char *)SvPV(ST(0), length);
1735 imgs = i_readgif_multi_scalar(data, length, &count);
1738 for (i = 0; i < count; ++i) {
1739 SV *sv = sv_newmortal();
1740 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1747 i_readgif_multi_callback(cb)
1755 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
1758 for (i = 0; i < count; ++i) {
1759 SV *sv = sv_newmortal();
1760 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1771 i_readpnm_wiol(ig, length)
1777 i_writeppm_wiol(im, ig)
1783 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
1792 i_writeraw_wiol(im,ig)
1797 i_writebmp_wiol(im,ig)
1807 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
1818 idlen = SvCUR(ST(4));
1819 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
1825 i_readtga_wiol(ig, length)
1831 i_scaleaxis(im,Value,Axis)
1837 i_scale_nn(im,scx,scy)
1847 i_count_colors(im,maxc)
1853 i_transform(im,opx,opy,parm)
1866 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1867 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
1868 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
1869 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1870 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
1871 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
1872 av=(AV*)SvRV(ST(1));
1874 opx=mymalloc( opxl*sizeof(int) );
1875 for(i=0;i<opxl;i++) {
1876 sv1=(*(av_fetch(av,i,0)));
1877 opx[i]=(int)SvIV(sv1);
1879 av=(AV*)SvRV(ST(2));
1881 opy=mymalloc( opyl*sizeof(int) );
1882 for(i=0;i<opyl;i++) {
1883 sv1=(*(av_fetch(av,i,0)));
1884 opy[i]=(int)SvIV(sv1);
1886 av=(AV*)SvRV(ST(3));
1887 parmlen=av_len(av)+1;
1888 parm=mymalloc( parmlen*sizeof(double) );
1889 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
1890 sv1=(*(av_fetch(av,i,0)));
1891 parm[i]=(double)SvNV(sv1);
1893 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
1897 ST(0) = sv_newmortal();
1898 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1899 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1902 i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
1921 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
1922 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
1923 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
1924 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1925 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
1927 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
1929 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
1930 av = (AV*)SvRV(ST(5));
1931 in_imgs_count = av_len(av)+1;
1932 for (i = 0; i < in_imgs_count; ++i) {
1933 sv1 = *av_fetch(av, i, 0);
1934 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1935 croak("Parameter 5 must contain only images");
1942 if (in_imgs_count > 0) {
1943 av = (AV*)SvRV(ST(5));
1944 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
1945 for (i = 0; i < in_imgs_count; ++i) {
1946 sv1 = *av_fetch(av,i,0);
1947 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1948 croak("Parameter 5 must contain only images");
1950 tmp = SvIV((SV*)SvRV(sv1));
1951 in_imgs[i] = (i_img*)tmp;
1955 /* no input images */
1958 /* default the output size from the first input if possible */
1960 width = SvIV(ST(0));
1961 else if (in_imgs_count)
1962 width = in_imgs[0]->xsize;
1964 croak("No output image width supplied");
1967 height = SvIV(ST(1));
1968 else if (in_imgs_count)
1969 height = in_imgs[0]->ysize;
1971 croak("No output image height supplied");
1973 ops = (struct rm_op *)SvPV(ST(2), ops_len);
1974 if (ops_len % sizeof(struct rm_op))
1975 croak("Imager: Parameter 3 must be a bitmap of regops\n");
1976 ops_count = ops_len / sizeof(struct rm_op);
1977 av = (AV*)SvRV(ST(3));
1978 n_regs_count = av_len(av)+1;
1979 n_regs = mymalloc(n_regs_count * sizeof(double));
1980 for (i = 0; i < n_regs_count; ++i) {
1981 sv1 = *av_fetch(av,i,0);
1983 n_regs[i] = SvNV(sv1);
1985 av = (AV*)SvRV(ST(4));
1986 c_regs_count = av_len(av)+1;
1987 c_regs = mymalloc(c_regs_count * sizeof(i_color));
1988 /* I don't bother initializing the colou?r registers */
1990 RETVAL=i_transform2(width, height, 3, ops, ops_count,
1991 n_regs, n_regs_count,
1992 c_regs, c_regs_count, in_imgs, in_imgs_count);
1997 ST(0) = sv_newmortal();
1998 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1999 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2003 i_contrast(im,intensity)
2012 i_noise(im,amount,type)
2018 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2028 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2047 i_postlevels(im,levels)
2057 i_watermark(im,wmark,tx,ty,pixdiff)
2059 Imager::ImgRaw wmark
2066 i_autolevels(im,lsat,usat,skew)
2073 i_radnoise(im,xo,yo,rscale,ascale)
2081 i_turbnoise(im, xo, yo, scale)
2104 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2105 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2106 croak("i_gradgen: Second argument must be an array ref");
2107 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2108 croak("i_gradgen: Third argument must be an array ref");
2109 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2110 croak("i_gradgen: Fourth argument must be an array ref");
2111 axx = (AV *)SvRV(ST(1));
2112 ayy = (AV *)SvRV(ST(2));
2113 ac = (AV *)SvRV(ST(3));
2114 dmeasure = (int)SvIV(ST(4));
2116 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2117 num = num <= av_len(ac) ? num : av_len(ac);
2119 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2120 xo = mymalloc( sizeof(int) * num );
2121 yo = mymalloc( sizeof(int) * num );
2122 ival = mymalloc( sizeof(i_color) * num );
2123 for(i = 0; i<num; i++) {
2124 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2125 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2126 sv = *av_fetch(ac, i, 0);
2127 if ( !sv_derived_from(sv, "Imager::Color") ) {
2128 free(axx); free(ayy); free(ac);
2129 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2131 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
2133 i_gradgen(im, num, xo, yo, ival, dmeasure);
2136 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2146 double ssample_param
2150 i_fountain_seg *segs;
2152 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2153 croak("i_fountain: argument 11 must be an array ref");
2155 asegs = (AV *)SvRV(ST(10));
2156 segs = load_fount_segs(asegs, &count);
2157 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
2158 ssample_param, count, segs);
2162 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2171 double ssample_param
2175 i_fountain_seg *segs;
2177 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2178 croak("i_fountain: argument 11 must be an array ref");
2180 asegs = (AV *)SvRV(ST(9));
2181 segs = load_fount_segs(asegs, &count);
2182 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2183 super_sample, ssample_param, count, segs);
2197 errors = i_errors();
2199 while (errors[i].msg) {
2201 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2202 if (!av_store(av, 0, sv)) {
2205 sv = newSViv(errors[i].code);
2206 if (!av_store(av, 1, sv)) {
2209 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2214 i_nearest_color(im, ...)
2229 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2230 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2231 croak("i_nearest_color: Second argument must be an array ref");
2232 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2233 croak("i_nearest_color: Third argument must be an array ref");
2234 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2235 croak("i_nearest_color: Fourth argument must be an array ref");
2236 axx = (AV *)SvRV(ST(1));
2237 ayy = (AV *)SvRV(ST(2));
2238 ac = (AV *)SvRV(ST(3));
2239 dmeasure = (int)SvIV(ST(4));
2241 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2242 num = num <= av_len(ac) ? num : av_len(ac);
2244 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2245 xo = mymalloc( sizeof(int) * num );
2246 yo = mymalloc( sizeof(int) * num );
2247 ival = mymalloc( sizeof(i_color) * num );
2248 for(i = 0; i<num; i++) {
2249 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2250 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2251 sv = *av_fetch(ac, i, 0);
2252 if ( !sv_derived_from(sv, "Imager::Color") ) {
2253 free(axx); free(ayy); free(ac);
2254 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2256 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
2258 i_nearest_color(im, num, xo, yo, ival, dmeasure);
2272 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
2273 hv=(HV*)SvRV(ST(0));
2274 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
2275 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
2276 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
2285 rc=DSO_open(filename,&evstr);
2289 PUSHs(sv_2mortal(newSViv((IV)rc)));
2290 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2293 PUSHs(sv_2mortal(newSViv((IV)rc)));
2299 DSO_close(dso_handle)
2303 DSO_funclist(dso_handle_v)
2307 DSO_handle *dso_handle;
2309 dso_handle=(DSO_handle*)dso_handle_v;
2311 while( dso_handle->function_list[i].name != NULL) {
2313 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
2315 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
2320 DSO_call(handle,func_index,hv)
2326 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2327 hv=(HV*)SvRV(ST(2));
2328 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2329 DSO_call( (DSO_handle *)handle,func_index,hv);
2333 # this is mostly for testing...
2335 i_get_pixel(im, x, y)
2342 color = (i_color *)mymalloc(sizeof(i_color));
2343 if (i_gpix(im, x, y, color) == 0) {
2344 ST(0) = sv_newmortal();
2345 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
2349 ST(0) = &PL_sv_undef;
2354 i_ppix(im, x, y, cl)
2361 i_img_pal_new(x, y, channels, maxpal)
2368 i_img_to_pal(src, quant)
2374 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2375 croak("i_img_to_pal: second argument must be a hash ref");
2376 hv = (HV *)SvRV(ST(1));
2377 memset(&quant, 0, sizeof(quant));
2378 quant.mc_size = 256;
2379 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
2380 handle_quant_opts(&quant, hv);
2381 RETVAL = i_img_to_pal(src, &quant);
2383 copy_colors_back(hv, &quant);
2385 myfree(quant.mc_colors);
2404 work = mymalloc((r-l) * sizeof(i_palidx));
2405 count = i_gpal(im, l, r, y, work);
2406 if (GIMME_V == G_ARRAY) {
2408 for (i = 0; i < count; ++i) {
2409 PUSHs(sv_2mortal(newSViv(work[i])));
2414 PUSHs(sv_2mortal(newSVpv(work, count * sizeof(i_palidx))));
2419 if (GIMME_V != G_ARRAY) {
2421 PUSHs(&PL_sv_undef);
2426 i_ppal(im, l, y, ...)
2435 work = mymalloc(sizeof(i_palidx) * (items-3));
2436 for (i=0; i < items-3; ++i) {
2437 work[i] = SvIV(ST(i+3));
2439 RETVAL = i_ppal(im, l, l+items-3, y, work);
2449 i_addcolors(im, ...)
2457 croak("i_addcolors: no colors to add");
2458 colors = mymalloc((items-1) * sizeof(i_color));
2459 for (i=0; i < items-1; ++i) {
2460 if (sv_isobject(ST(i+1))
2461 && sv_derived_from(ST(i+1), "Imager::Color")) {
2462 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
2463 colors[i] = *(i_color *)tmp;
2467 croak("i_plin: pixels must be Imager::Color objects");
2470 index = i_addcolors(im, colors, items-1);
2473 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2475 else if (index == -1) {
2476 ST(0) = &PL_sv_undef;
2479 ST(0) = sv_2mortal(newSViv(index));
2483 i_setcolors(im, index, ...)
2491 croak("i_setcolors: no colors to add");
2492 colors = mymalloc((items-2) * sizeof(i_color));
2493 for (i=0; i < items-2; ++i) {
2494 if (sv_isobject(ST(i+2))
2495 && sv_derived_from(ST(i+2), "Imager::Color")) {
2496 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
2497 colors[i] = *(i_color *)tmp;
2501 croak("i_setcolors: pixels must be Imager::Color objects");
2504 RETVAL = i_setcolors(im, index, colors, items-2);
2508 i_getcolors(im, index, ...)
2517 croak("i_getcolors: too many arguments");
2519 count = SvIV(ST(2));
2521 croak("i_getcolors: count must be positive");
2522 colors = mymalloc(sizeof(i_color) * count);
2523 if (i_getcolors(im, index, colors, count)) {
2524 for (i = 0; i < count; ++i) {
2526 SV *sv = sv_newmortal();
2527 pv = mymalloc(sizeof(i_color));
2529 sv_setref_pv(sv, "Imager::Color", (void *)pv);
2542 count = i_colorcount(im);
2544 ST(0) = sv_2mortal(newSViv(count));
2547 ST(0) = &PL_sv_undef;
2556 count = i_maxcolors(im);
2558 ST(0) = sv_2mortal(newSViv(count));
2561 ST(0) = &PL_sv_undef;
2565 i_findcolor(im, color)
2571 if (i_findcolor(im, color, &index)) {
2572 ST(0) = sv_2mortal(newSViv(index));
2575 ST(0) = &PL_sv_undef;
2591 i_gsamp(im, l, r, y, ...)
2603 croak("No channel numbers supplied to g_samp()");
2605 chan_count = items - 4;
2606 chans = mymalloc(sizeof(int) * chan_count);
2607 for (i = 0; i < chan_count; ++i)
2608 chans[i] = SvIV(ST(i+4));
2609 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
2610 count = i_gsamp(im, l, r, y, data, chans, chan_count);
2612 if (GIMME_V == G_ARRAY) {
2614 for (i = 0; i < count; ++i)
2615 PUSHs(sv_2mortal(newSViv(data[i])));
2619 PUSHs(sv_2mortal(newSVpv(data, count * sizeof(i_sample_t))));
2623 if (GIMME_V != G_ARRAY) {
2625 PUSHs(&PL_sv_undef);
2630 i_img_masked_new(targ, mask, x, y, w, h)
2640 if (!sv_isobject(ST(1))
2641 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
2642 croak("i_img_masked_new: parameter 2 must undef or an image");
2644 mask = (i_img *)SvIV((SV *)SvRV(ST(1)));
2648 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
2653 i_plin(im, l, y, ...)
2662 work = mymalloc(sizeof(i_color) * (items-3));
2663 for (i=0; i < items-3; ++i) {
2664 if (sv_isobject(ST(i+3))
2665 && sv_derived_from(ST(i+3), "Imager::Color")) {
2666 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2667 work[i] = *(i_color *)tmp;
2671 croak("i_plin: pixels must be Imager::Color objects");
2675 RETVAL = i_plin(im, l, l+items-3, y, work);
2685 i_ppixf(im, x, y, cl)
2689 Imager::Color::Float cl
2692 i_gsampf(im, l, r, y, ...)
2704 croak("No channel numbers supplied to g_sampf()");
2706 chan_count = items - 4;
2707 chans = mymalloc(sizeof(int) * chan_count);
2708 for (i = 0; i < chan_count; ++i)
2709 chans[i] = SvIV(ST(i+4));
2710 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
2711 count = i_gsampf(im, l, r, y, data, chans, chan_count);
2712 if (GIMME_V == G_ARRAY) {
2714 for (i = 0; i < count; ++i)
2715 PUSHs(sv_2mortal(newSVnv(data[i])));
2719 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
2723 if (GIMME_V != G_ARRAY) {
2725 PUSHs(&PL_sv_undef);
2730 i_plinf(im, l, y, ...)
2739 work = mymalloc(sizeof(i_fcolor) * (items-3));
2740 for (i=0; i < items-3; ++i) {
2741 if (sv_isobject(ST(i+3))
2742 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
2743 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2744 work[i] = *(i_fcolor *)tmp;
2748 croak("i_plin: pixels must be Imager::Color::Float objects");
2752 RETVAL = i_plinf(im, l, l+items-3, y, work);
2769 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
2770 if (i_gpixf(im, x, y, color) == 0) {
2771 ST(0) = sv_newmortal();
2772 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
2776 ST(0) = &PL_sv_undef;
2790 vals = mymalloc((r-l) * sizeof(i_color));
2791 count = i_glin(im, l, r, y, vals);
2793 for (i = 0; i < count; ++i) {
2795 i_color *col = mymalloc(sizeof(i_color));
2796 sv = sv_newmortal();
2797 sv_setref_pv(sv, "Imager::Color", (void *)col);
2804 i_glinf(im, l, r, y)
2814 vals = mymalloc((r-l) * sizeof(i_fcolor));
2815 count = i_glinf(im, l, r, y, vals);
2817 for (i = 0; i < count; ++i) {
2819 i_fcolor *col = mymalloc(sizeof(i_fcolor));
2821 sv = sv_newmortal();
2822 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
2829 i_img_16_new(x, y, ch)
2835 i_img_double_new(x, y, ch)
2841 i_tags_addn(im, name, code, idata)
2850 name = SvPV(ST(1), len);
2853 RETVAL = i_tags_addn(&im->tags, name, code, idata);
2858 i_tags_add(im, name, code, data, idata)
2868 name = SvPV(ST(1), len);
2872 data = SvPV(ST(3), len);
2877 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
2882 i_tags_find(im, name, start)
2889 if (i_tags_find(&im->tags, name, start, &entry)) {
2891 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2893 ST(0) = sv_2mortal(newSViv(entry));
2895 ST(0) = &PL_sv_undef;
2899 i_tags_findn(im, code, start)
2906 if (i_tags_findn(&im->tags, code, start, &entry)) {
2908 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2910 ST(0) = sv_2mortal(newSViv(entry));
2913 ST(0) = &PL_sv_undef;
2916 i_tags_delete(im, entry)
2920 RETVAL = i_tags_delete(&im->tags, entry);
2925 i_tags_delbyname(im, name)
2929 RETVAL = i_tags_delbyname(&im->tags, name);
2934 i_tags_delbycode(im, code)
2938 RETVAL = i_tags_delbycode(&im->tags, code);
2943 i_tags_get(im, index)
2947 if (index >= 0 && index < im->tags.count) {
2948 i_img_tag *entry = im->tags.tags + index;
2952 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
2955 PUSHs(sv_2mortal(newSViv(entry->code)));
2958 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
2961 PUSHs(sv_2mortal(newSViv(entry->idata)));
2969 RETVAL = im->tags.count;
2976 i_wf_bbox(face, size, text)
2983 if (i_wf_bbox(face, size, text, strlen(text), cords)) {
2985 PUSHs(sv_2mortal(newSViv(cords[0])));
2986 PUSHs(sv_2mortal(newSViv(cords[1])));
2987 PUSHs(sv_2mortal(newSViv(cords[2])));
2988 PUSHs(sv_2mortal(newSViv(cords[3])));
2989 PUSHs(sv_2mortal(newSViv(cords[4])));
2990 PUSHs(sv_2mortal(newSViv(cords[5])));
2994 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3005 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3011 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3022 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3032 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
3034 #define FT2_DESTROY(font) i_ft2_destroy(font)
3038 Imager::Font::FT2 font
3040 MODULE = Imager PACKAGE = Imager::Font::FreeType2
3043 i_ft2_new(name, index)
3048 i_ft2_setdpi(font, xdpi, ydpi)
3049 Imager::Font::FT2 font
3055 Imager::Font::FT2 font
3059 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
3061 PUSHs(sv_2mortal(newSViv(xdpi)));
3062 PUSHs(sv_2mortal(newSViv(ydpi)));
3066 i_ft2_sethinting(font, hinting)
3067 Imager::Font::FT2 font
3071 i_ft2_settransform(font, matrix)
3072 Imager::Font::FT2 font
3080 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3081 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
3082 av=(AV*)SvRV(ST(1));
3086 for (i = 0; i < len; ++i) {
3087 sv1=(*(av_fetch(av,i,0)));
3088 matrix[i] = SvNV(sv1);
3092 RETVAL = i_ft2_settransform(font, matrix);
3097 i_ft2_bbox(font, cheight, cwidth, text)
3098 Imager::Font::FT2 font
3106 if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox)) {
3108 for (i = 0; i < 6; ++i)
3109 PUSHs(sv_2mortal(newSViv(bbox[i])));
3113 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
3114 Imager::Font::FT2 font
3128 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
3131 for (i = 0; i < 8; ++i)
3132 PUSHs(sv_2mortal(newSViv(bbox[i])));
3136 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
3137 Imager::Font::FT2 font
3153 if (SvUTF8(ST(7))) {
3157 text = SvPV(ST(7), len);
3158 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
3159 len, align, aa, vlayout, utf8);
3164 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
3165 Imager::Font::FT2 font
3182 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
3183 strlen(text), align, aa, vlayout, 1);
3188 ft2_transform_box(font, x0, x1, x2, x3)
3189 Imager::Font::FT2 font
3197 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
3198 ft2_transform_box(font, box);
3200 PUSHs(sv_2mortal(newSViv(box[0])));
3201 PUSHs(sv_2mortal(newSViv(box[1])));
3202 PUSHs(sv_2mortal(newSViv(box[2])));
3203 PUSHs(sv_2mortal(newSViv(box[3])));
3207 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3211 Imager::FillHandle fill
3213 MODULE = Imager PACKAGE = Imager
3216 i_new_fill_solid(cl, combine)
3221 i_new_fill_solidf(cl, combine)
3222 Imager::Color::Float cl
3226 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3234 unsigned char *cust_hatch;
3238 cust_hatch = SvPV(ST(4), len);
3242 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3247 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3248 Imager::Color::Float fg
3249 Imager::Color::Float bg
3255 unsigned char *cust_hatch;
3259 cust_hatch = SvPV(ST(4), len);
3263 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3268 i_new_fill_image(src, matrix, xoff, yoff, combine)
3285 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3286 croak("i_new_fill_image: parameter must be an arrayref");
3287 av=(AV*)SvRV(ST(1));
3291 for (i = 0; i < len; ++i) {
3292 sv1=(*(av_fetch(av,i,0)));
3293 matrix[i] = SvNV(sv1);
3299 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);