7 image.c - implements most of the basic functions of Imager and much of the rest
13 c = i_color_new(red, green, blue, alpha);
21 image.c implements the basic functions to create and destroy image and
22 color objects for Imager.
24 =head1 FUNCTION REFERENCE
26 Some of these functions are internal.
37 #define minmax(a,b,i) ( ((a>=i)?a: ( (b<=i)?b:i )) )
39 /* Hack around an obscure linker bug on solaris - probably due to builtin gcc thingies */
40 static void fake(void) { ceil(1); }
42 static int i_ppix_d(i_img *im, int x, int y, i_color *val);
43 static int i_gpix_d(i_img *im, int x, int y, i_color *val);
44 static int i_glin_d(i_img *im, int l, int r, int y, i_color *vals);
45 static int i_plin_d(i_img *im, int l, int r, int y, i_color *vals);
46 static int i_ppixf_d(i_img *im, int x, int y, i_fcolor *val);
47 static int i_gpixf_d(i_img *im, int x, int y, i_fcolor *val);
48 static int i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
49 static int i_plinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
50 static int i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, const int *chans, int chan_count);
51 static int i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, const int *chans, int chan_count);
52 /*static int i_psamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count);
53 static int i_psampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count);*/
56 =item ICL_new_internal(r, g, b, a)
58 Return a new color object with values passed to it.
60 r - red component (range: 0 - 255)
61 g - green component (range: 0 - 255)
62 b - blue component (range: 0 - 255)
63 a - alpha component (range: 0 - 255)
69 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
72 mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
74 if ( (cl=mymalloc(sizeof(i_color))) == NULL) m_fatal(2,"malloc() error\n");
79 mm_log((1,"(%p) <- ICL_new_internal\n",cl));
85 =item ICL_set_internal(cl, r, g, b, a)
87 Overwrite a color with new values.
89 cl - pointer to color object
90 r - red component (range: 0 - 255)
91 g - green component (range: 0 - 255)
92 b - blue component (range: 0 - 255)
93 a - alpha component (range: 0 - 255)
99 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
100 mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
102 if ( (cl=mymalloc(sizeof(i_color))) == NULL)
103 m_fatal(2,"malloc() error\n");
108 mm_log((1,"(%p) <- ICL_set_internal\n",cl));
114 =item ICL_add(dst, src, ch)
116 Add src to dst inplace - dst is modified.
118 dst - pointer to destination color object
119 src - pointer to color object that is added
120 ch - number of channels
126 ICL_add(i_color *dst,i_color *src,int ch) {
129 tmp=dst->channel[i]+src->channel[i];
130 dst->channel[i]= tmp>255 ? 255:tmp;
137 Dump color information to log - strictly for debugging.
139 cl - pointer to color object
145 ICL_info(i_color *cl) {
146 mm_log((1,"i_color_info(cl* %p)\n",cl));
147 mm_log((1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
153 Destroy ancillary data for Color object.
155 cl - pointer to color object
161 ICL_DESTROY(i_color *cl) {
162 mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
167 =item i_fcolor_new(double r, double g, double b, double a)
171 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
174 mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
176 if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) m_fatal(2,"malloc() error\n");
181 mm_log((1,"(%p) <- i_fcolor_new\n",cl));
187 =item i_fcolor_destroy(i_fcolor *cl)
191 void i_fcolor_destroy(i_fcolor *cl) {
196 =item IIM_base_8bit_direct (static)
198 A static i_img object used to initialize direct 8-bit per sample images.
202 static i_img IIM_base_8bit_direct =
204 0, /* channels set */
205 0, 0, 0, /* xsize, ysize, bytes */
208 i_direct_type, /* type */
211 { 0, 0, NULL }, /* tags */
214 i_ppix_d, /* i_f_ppix */
215 i_ppixf_d, /* i_f_ppixf */
216 i_plin_d, /* i_f_plin */
217 i_plinf_d, /* i_f_plinf */
218 i_gpix_d, /* i_f_gpix */
219 i_gpixf_d, /* i_f_gpixf */
220 i_glin_d, /* i_f_glin */
221 i_glinf_d, /* i_f_glinf */
222 i_gsamp_d, /* i_f_gsamp */
223 i_gsampf_d, /* i_f_gsampf */
227 NULL, /* i_f_addcolors */
228 NULL, /* i_f_getcolors */
229 NULL, /* i_f_colorcount */
230 NULL, /* i_f_maxcolors */
231 NULL, /* i_f_findcolor */
232 NULL, /* i_f_setcolors */
234 NULL, /* i_f_destroy */
237 /*static void set_8bit_direct(i_img *im) {
238 im->i_f_ppix = i_ppix_d;
239 im->i_f_ppixf = i_ppixf_d;
240 im->i_f_plin = i_plin_d;
241 im->i_f_plinf = i_plinf_d;
242 im->i_f_gpix = i_gpix_d;
243 im->i_f_gpixf = i_gpixf_d;
244 im->i_f_glin = i_glin_d;
245 im->i_f_glinf = i_glinf_d;
248 im->i_f_addcolor = NULL;
249 im->i_f_getcolor = NULL;
250 im->i_f_colorcount = NULL;
251 im->i_f_findcolor = NULL;
255 =item IIM_new(x, y, ch)
257 Creates a new image object I<x> pixels wide, and I<y> pixels high with I<ch> channels.
264 IIM_new(int x,int y,int ch) {
266 mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
268 im=i_img_empty_ch(NULL,x,y,ch);
270 mm_log((1,"(%p) <- IIM_new\n",im));
276 IIM_DESTROY(i_img *im) {
277 mm_log((1,"IIM_DESTROY(im* %p)\n",im));
287 Create new image reference - notice that this isn't an object yet and
288 this should be fixed asap.
298 mm_log((1,"i_img_struct()\n"));
299 if ( (im=mymalloc(sizeof(i_img))) == NULL)
300 m_fatal(2,"malloc() error\n");
302 *im = IIM_base_8bit_direct;
310 mm_log((1,"(%p) <- i_img_struct\n",im));
315 =item i_img_empty(im, x, y)
317 Re-new image reference (assumes 3 channels)
320 x - xsize of destination image
321 y - ysize of destination image
323 **FIXME** what happens if a live image is passed in here?
325 Should this just call i_img_empty_ch()?
331 i_img_empty(i_img *im,int x,int y) {
332 mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
333 return i_img_empty_ch(im, x, y, 3);
337 =item i_img_empty_ch(im, x, y, ch)
339 Re-new image reference
342 x - xsize of destination image
343 y - ysize of destination image
344 ch - number of channels
350 i_img_empty_ch(i_img *im,int x,int y,int ch) {
351 mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
353 if (x < 1 || y < 1) {
354 i_push_error(0, "Image sizes must be positive");
357 if (ch < 1 || ch > MAXCHANNELS) {
358 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
363 if ( (im=mymalloc(sizeof(i_img))) == NULL)
364 m_fatal(2,"malloc() error\n");
366 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
367 i_tags_new(&im->tags);
371 im->ch_mask = MAXINT;
372 im->bytes=x*y*im->channels;
373 if ( (im->idata=mymalloc(im->bytes)) == NULL) m_fatal(2,"malloc() error\n");
374 memset(im->idata,0,(size_t)im->bytes);
378 mm_log((1,"(%p) <- i_img_empty_ch\n",im));
383 =item i_img_exorcise(im)
393 i_img_exorcise(i_img *im) {
394 mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
395 i_tags_destroy(&im->tags);
397 (im->i_f_destroy)(im);
398 if (im->idata != NULL) { myfree(im->idata); }
404 im->i_f_ppix=i_ppix_d;
405 im->i_f_gpix=i_gpix_d;
406 im->i_f_plin=i_plin_d;
407 im->i_f_glin=i_glin_d;
412 =item i_img_destroy(im)
414 Destroy image and free data via exorcise.
422 i_img_destroy(i_img *im) {
423 mm_log((1,"i_img_destroy(im %p)\n",im));
425 if (im) { myfree(im); }
429 =item i_img_info(im, info)
431 Return image information
434 info - pointer to array to return data
436 info is an array of 4 integers with the following values:
441 info[3] - channel mask
448 i_img_info(i_img *im,int *info) {
449 mm_log((1,"i_img_info(im 0x%x)\n",im));
451 mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
452 mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
455 info[2] = im->channels;
456 info[3] = im->ch_mask;
466 =item i_img_setmask(im, ch_mask)
468 Set the image channel mask for I<im> to I<ch_mask>.
473 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
477 =item i_img_getmask(im)
479 Get the image channel mask for I<im>.
484 i_img_getmask(i_img *im) { return im->ch_mask; }
487 =item i_img_getchannels(im)
489 Get the number of channels in I<im>.
494 i_img_getchannels(i_img *im) { return im->channels; }
499 =item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
501 (x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
502 (tx,ty) specifies the upper left corner for the target image.
503 pass NULL in trans for non transparent i_colors.
509 i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans) {
511 int x,y,t,ttx,tty,tt,ch;
513 mm_log((1,"i_copyto_trans(im* %p,src 0x%x, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d, trans* 0x%x)\n",
514 im, src, x1, y1, x2, y2, tx, ty, trans));
516 if (x2<x1) { t=x1; x1=x2; x2=t; }
517 if (y2<y1) { t=y1; y1=y2; y2=t; }
529 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
530 if (tt) i_ppix(im,ttx,tty,&pv);
531 } else i_ppix(im,ttx,tty,&pv);
539 =item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
541 Copies image data from the area (x1,y1)-[x2,y2] in the source image to
542 a rectangle the same size with it's top-left corner at (tx,ty) in the
545 If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
551 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
552 int x, y, t, ttx, tty;
554 if (x2<x1) { t=x1; x1=x2; x2=t; }
555 if (y2<y1) { t=y1; y1=y2; y2=t; }
557 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
558 im, src, x1, y1, x2, y2, tx, ty));
560 if (im->bits == i_8_bits) {
563 for(y=y1; y<y2; y++) {
565 for(x=x1; x<x2; x++) {
566 i_gpix(src, x, y, &pv);
567 i_ppix(im, ttx, tty, &pv);
576 for(y=y1; y<y2; y++) {
578 for(x=x1; x<x2; x++) {
579 i_gpixf(src, x, y, &pv);
580 i_ppixf(im, ttx, tty, &pv);
589 =item i_copy(im, src)
591 Copies the contents of the image I<src> over the image I<im>.
597 i_copy(i_img *im, i_img *src) {
600 mm_log((1,"i_copy(im* %p,src %p)\n", im, src));
604 if (src->type == i_direct_type) {
605 if (src->bits == i_8_bits) {
607 i_img_empty_ch(im, x1, y1, src->channels);
608 pv = mymalloc(sizeof(i_color) * x1);
610 for (y = 0; y < y1; ++y) {
611 i_glin(src, 0, x1, y, pv);
612 i_plin(im, 0, x1, y, pv);
618 if (src->bits == i_16_bits)
619 i_img_16_new_low(im, x1, y1, src->channels);
620 else if (src->bits == i_double_bits)
621 i_img_double_new_low(im, x1, y1, src->channels);
623 fprintf(stderr, "i_copy(): Unknown image bit size %d\n", src->bits);
624 return; /* I dunno */
627 pv = mymalloc(sizeof(i_fcolor) * x1);
628 for (y = 0; y < y1; ++y) {
629 i_glinf(src, 0, x1, y, pv);
630 i_plinf(im, 0, x1, y, pv);
642 i_img_pal_new_low(im, x1, y1, src->channels, i_maxcolors(src));
643 /* copy across the palette */
644 count = i_colorcount(src);
645 for (index = 0; index < count; ++index) {
646 i_getcolors(src, index, &temp, 1);
647 i_addcolors(im, &temp, 1);
650 vals = mymalloc(sizeof(i_palidx) * x1);
651 for (y = 0; y < y1; ++y) {
652 i_gpal(src, 0, x1, y, vals);
653 i_ppal(im, 0, x1, y, vals);
661 =item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
663 Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
664 overlays it at (I<tx>,I<ty>) on the image object.
666 The alpha channel of each pixel in I<src> is used to control how much
667 the existing colour in I<im> is replaced, if it is 255 then the colour
668 is completely replaced, if it is 0 then the original colour is left
675 i_rubthru(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny,
676 int src_maxx, int src_maxy) {
683 mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d, src_minx %d, "
684 "src_miny %d, src_maxx %d, src_maxy %d)\n",
685 im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy));
688 if (im->channels == 3 && src->channels == 4) {
690 chans[0] = 0; chans[1] = 1; chans[2] = 2;
693 else if (im->channels == 3 && src->channels == 2) {
695 chans[0] = chans[1] = chans[2] = 0;
698 else if (im->channels == 1 && src->channels == 2) {
704 i_push_error(0, "rubthru can only work where (dest, src) channels are (3,4), (3,2) or (1,2)");
709 /* if you change this code, please make sure the else branch is
710 changed in a similar fashion - TC */
712 i_color pv, orig, dest;
714 for(y = src_miny; y < src_maxy; y++) {
716 for(x = src_minx; x < src_maxx; x++) {
717 i_gpix(src, x, y, &pv);
718 i_gpix(im, ttx, tty, &orig);
719 alpha = pv.channel[alphachan];
720 for (ch = 0; ch < chancount; ++ch) {
721 dest.channel[ch] = (alpha * pv.channel[chans[ch]]
722 + (255 - alpha) * orig.channel[ch])/255;
724 i_ppix(im, ttx, tty, &dest);
732 i_fcolor pv, orig, dest;
735 for(y = src_miny; y < src_maxy; y++) {
737 for(x = src_minx; x < src_maxx; x++) {
738 i_gpixf(src, x, y, &pv);
739 i_gpixf(im, ttx, tty, &orig);
740 alpha = pv.channel[alphachan];
741 for (ch = 0; ch < chancount; ++ch) {
742 dest.channel[ch] = alpha * pv.channel[chans[ch]]
743 + (1 - alpha) * orig.channel[ch];
745 i_ppixf(im, ttx, tty, &dest);
757 =item i_flipxy(im, axis)
759 Flips the image inplace around the axis specified.
760 Returns 0 if parameters are invalid.
763 axis - 0 = x, 1 = y, 2 = both
769 i_flipxy(i_img *im, int direction) {
770 int x, x2, y, y2, xm, ym;
774 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
779 case XAXIS: /* Horizontal flip */
782 for(y=0; y<ym; y++) {
784 for(x=0; x<xm; x++) {
786 i_gpix(im, x, y, &val1);
787 i_gpix(im, x2, y, &val2);
788 i_ppix(im, x, y, &val2);
789 i_ppix(im, x2, y, &val1);
794 case YAXIS: /* Vertical flip */
798 for(y=0; y<ym; y++) {
799 for(x=0; x<xm; x++) {
801 i_gpix(im, x, y, &val1);
802 i_gpix(im, x, y2, &val2);
803 i_ppix(im, x, y, &val2);
804 i_ppix(im, x, y2, &val1);
809 case XYAXIS: /* Horizontal and Vertical flip */
813 for(y=0; y<ym; y++) {
815 for(x=0; x<xm; x++) {
817 i_gpix(im, x, y, &val1);
818 i_gpix(im, x2, y2, &val2);
819 i_ppix(im, x, y, &val2);
820 i_ppix(im, x2, y2, &val1);
822 i_gpix(im, x2, y, &val1);
823 i_gpix(im, x, y2, &val2);
824 i_ppix(im, x2, y, &val2);
825 i_ppix(im, x, y2, &val1);
830 if (xm*2 != xs) { /* odd number of column */
831 mm_log((1, "i_flipxy: odd number of columns\n"));
834 for(y=0; y<ym; y++) {
836 i_gpix(im, x, y, &val1);
837 i_gpix(im, x, y2, &val2);
838 i_ppix(im, x, y, &val2);
839 i_ppix(im, x, y2, &val1);
843 if (ym*2 != ys) { /* odd number of rows */
844 mm_log((1, "i_flipxy: odd number of rows\n"));
847 for(x=0; x<xm; x++) {
849 i_gpix(im, x, y, &val1);
850 i_gpix(im, x2, y, &val2);
851 i_ppix(im, x, y, &val2);
852 i_ppix(im, x2, y, &val1);
858 mm_log((1, "i_flipxy: direction is invalid\n" ));
876 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
877 else if (x == 0.0) return (1.0);
878 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
883 =item i_scaleaxis(im, value, axis)
885 Returns a new image object which is I<im> scaled by I<value> along
886 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
892 i_scaleaxis(i_img *im, float Value, int Axis) {
893 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
894 int LanczosWidthFactor;
895 float *l0, *l1, OldLocation;
898 float F, PictureValue[MAXCHANNELS];
900 i_color val,val1,val2;
903 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
907 hsize = (int)(0.5 + im->xsize * Value);
910 Value = 1.0 / im->xsize;
918 vsize = (int)(0.5 + im->ysize * Value);
922 Value = 1.0 / im->ysize;
929 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
931 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
932 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
933 lMax = LanczosWidthFactor << 1;
935 l0 = mymalloc(lMax * sizeof(float));
936 l1 = mymalloc(lMax * sizeof(float));
938 for (j=0; j<jEnd; j++) {
939 OldLocation = ((float) j) / Value;
940 T = (int) (OldLocation);
941 F = OldLocation - (float) T;
943 for (l = 0; l<lMax; l++) {
944 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
945 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
948 /* Make sure filter is normalized */
950 for(l=0; l<lMax; l++) {
954 t /= (float)LanczosWidthFactor;
956 for(l=0; l<lMax; l++) {
963 for (i=0; i<iEnd; i++) {
964 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
965 for (l=0; l<lMax; l++) {
968 mx = (mx < 0) ? 0 : mx;
969 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
971 i_gpix(im, Mx, i, &val1);
972 i_gpix(im, mx, i, &val2);
974 for (k=0; k<im->channels; k++) {
975 PictureValue[k] += l1[l] * val1.channel[k];
976 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
979 for(k=0;k<im->channels;k++) {
980 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
981 val.channel[k]=minmax(0,255,psave);
983 i_ppix(new_img, j, i, &val);
988 for (i=0; i<iEnd; i++) {
989 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
990 for (l=0; l < lMax; l++) {
993 mx = (mx < 0) ? 0 : mx;
994 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
996 i_gpix(im, i, Mx, &val1);
997 i_gpix(im, i, mx, &val2);
998 for (k=0; k<im->channels; k++) {
999 PictureValue[k] += l1[l] * val1.channel[k];
1000 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
1003 for (k=0; k<im->channels; k++) {
1004 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
1005 val.channel[k] = minmax(0, 255, psave);
1007 i_ppix(new_img, i, j, &val);
1015 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
1022 =item i_scale_nn(im, scx, scy)
1024 Scale by using nearest neighbor
1025 Both axes scaled at the same time since
1026 nothing is gained by doing it in two steps
1033 i_scale_nn(i_img *im, float scx, float scy) {
1035 int nxsize,nysize,nx,ny;
1039 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
1041 nxsize = (int) ((float) im->xsize * scx);
1044 scx = 1 / im->xsize;
1046 nysize = (int) ((float) im->ysize * scy);
1049 scy = 1 / im->ysize;
1052 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1054 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1055 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1056 i_ppix(new_img,nx,ny,&val);
1059 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1065 =item i_sametype(i_img *im, int xsize, int ysize)
1067 Returns an image of the same type (sample size, channels, paletted/direct).
1069 For paletted images the palette is copied from the source.
1074 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1075 if (src->type == i_direct_type) {
1076 if (src->bits == 8) {
1077 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1079 else if (src->bits == i_16_bits) {
1080 return i_img_16_new(xsize, ysize, src->channels);
1082 else if (src->bits == i_double_bits) {
1083 return i_img_double_new(xsize, ysize, src->channels);
1086 i_push_error(0, "Unknown image bits");
1094 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1095 for (i = 0; i < i_colorcount(src); ++i) {
1096 i_getcolors(src, i, &col, 1);
1097 i_addcolors(targ, &col, 1);
1105 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1107 Returns an image of the same type (sample size).
1109 For paletted images the equivalent direct type is returned.
1114 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1115 if (src->bits == 8) {
1116 return i_img_empty_ch(NULL, xsize, ysize, channels);
1118 else if (src->bits == i_16_bits) {
1119 return i_img_16_new(xsize, ysize, channels);
1121 else if (src->bits == i_double_bits) {
1122 return i_img_double_new(xsize, ysize, channels);
1125 i_push_error(0, "Unknown image bits");
1131 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1133 Spatially transforms I<im> returning a new image.
1135 opx for a length of opxl and opy for a length of opy are arrays of
1136 operators that modify the x and y positions to retreive the pixel data from.
1138 parm and parmlen define extra parameters that the operators may use.
1140 Note that this function is largely superseded by the more flexible
1141 L<transform.c/i_transform2>.
1143 Returns the new image.
1145 The operators for this function are defined in L<stackmach.c>.
1150 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1152 int nxsize,nysize,nx,ny;
1156 mm_log((1,"i_transform(im 0x%x, opx 0x%x, opxl %d, opy 0x%x, opyl %d, parm 0x%x, parmlen %d)\n",im,opx,opxl,opy,opyl,parm,parmlen));
1159 nysize = im->ysize ;
1161 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1162 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1163 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1164 /* parm[parmlen-2]=(double)nx;
1165 parm[parmlen-1]=(double)ny; */
1170 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1171 rx=i_op_run(opx,opxl,parm,parmlen);
1172 ry=i_op_run(opy,opyl,parm,parmlen);
1173 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1174 i_gpix(im,rx,ry,&val);
1175 i_ppix(new_img,nx,ny,&val);
1178 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1183 =item i_img_diff(im1, im2)
1185 Calculates the sum of the squares of the differences between
1186 correspoding channels in two images.
1188 If the images are not the same size then only the common area is
1189 compared, hence even if images are different sizes this function
1195 i_img_diff(i_img *im1,i_img *im2) {
1196 int x,y,ch,xb,yb,chb;
1200 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1202 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1203 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1204 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1206 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1209 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1210 i_gpix(im1,x,y,&val1);
1211 i_gpix(im2,x,y,&val2);
1213 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1215 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1219 /* just a tiny demo of haar wavelets */
1227 i_img *new_img,*new_img2;
1228 i_color val1,val2,dval1,dval2;
1236 /* horizontal pass */
1238 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1239 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1242 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1243 i_gpix(im,x*2,y,&val1);
1244 i_gpix(im,x*2+1,y,&val2);
1245 for(ch=0;ch<im->channels;ch++) {
1246 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1247 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1249 i_ppix(new_img,x,y,&dval1);
1250 i_ppix(new_img,x+fx,y,&dval2);
1253 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1254 i_gpix(new_img,x,y*2,&val1);
1255 i_gpix(new_img,x,y*2+1,&val2);
1256 for(ch=0;ch<im->channels;ch++) {
1257 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1258 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1260 i_ppix(new_img2,x,y,&dval1);
1261 i_ppix(new_img2,x,y+fy,&dval2);
1264 i_img_destroy(new_img);
1269 =item i_count_colors(im, maxc)
1271 returns number of colors or -1
1272 to indicate that it was more than max colors
1277 i_count_colors(i_img *im,int maxc) {
1284 mm_log((1,"i_count_colors(im 0x%08X,maxc %d)\n"));
1291 for(y=0;y<ysize;y++) for(x=0;x<xsize;x++) {
1292 i_gpix(im,x,y,&val);
1293 colorcnt+=octt_add(ct,val.rgb.r,val.rgb.g,val.rgb.b);
1294 if (colorcnt > maxc) { octt_delete(ct); return -1; }
1303 =head2 8-bit per sample image internal functions
1305 These are the functions installed in an 8-bit per sample image.
1309 =item i_ppix_d(im, x, y, col)
1313 This is the function kept in the i_f_ppix member of an i_img object.
1314 It does a normal store of a pixel into the image with range checking.
1316 Returns 0 if the pixel could be set, -1 otherwise.
1322 i_ppix_d(i_img *im, int x, int y, i_color *val) {
1325 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1326 for(ch=0;ch<im->channels;ch++)
1327 if (im->ch_mask&(1<<ch))
1328 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1331 return -1; /* error was clipped */
1335 =item i_gpix_d(im, x, y, &col)
1339 This is the function kept in the i_f_gpix member of an i_img object.
1340 It does normal retrieval of a pixel from the image with range checking.
1342 Returns 0 if the pixel could be set, -1 otherwise.
1348 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1350 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1351 for(ch=0;ch<im->channels;ch++)
1352 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1355 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1356 return -1; /* error was cliped */
1360 =item i_glin_d(im, l, r, y, vals)
1362 Reads a line of data from the image, storing the pixels at vals.
1364 The line runs from (l,y) inclusive to (r,y) non-inclusive
1366 vals should point at space for (r-l) pixels.
1368 l should never be less than zero (to avoid confusion about where to
1369 put the pixels in vals).
1371 Returns the number of pixels copied (eg. if r, l or y is out of range)
1377 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1379 unsigned char *data;
1380 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1383 data = im->idata + (l+y*im->xsize) * im->channels;
1385 for (i = 0; i < count; ++i) {
1386 for (ch = 0; ch < im->channels; ++ch)
1387 vals[i].channel[ch] = *data++;
1397 =item i_plin_d(im, l, r, y, vals)
1399 Writes a line of data into the image, using the pixels at vals.
1401 The line runs from (l,y) inclusive to (r,y) non-inclusive
1403 vals should point at (r-l) pixels.
1405 l should never be less than zero (to avoid confusion about where to
1406 get the pixels in vals).
1408 Returns the number of pixels copied (eg. if r, l or y is out of range)
1414 i_plin_d(i_img *im, int l, int r, int y, i_color *vals) {
1416 unsigned char *data;
1417 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1420 data = im->idata + (l+y*im->xsize) * im->channels;
1422 for (i = 0; i < count; ++i) {
1423 for (ch = 0; ch < im->channels; ++ch) {
1424 if (im->ch_mask & (1 << ch))
1425 *data = vals[i].channel[ch];
1437 =item i_ppixf_d(im, x, y, val)
1443 i_ppixf_d(i_img *im, int x, int y, i_fcolor *val) {
1446 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1447 for(ch=0;ch<im->channels;ch++)
1448 if (im->ch_mask&(1<<ch)) {
1449 im->idata[(x+y*im->xsize)*im->channels+ch] =
1450 SampleFTo8(val->channel[ch]);
1454 return -1; /* error was clipped */
1458 =item i_gpixf_d(im, x, y, val)
1464 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1466 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1467 for(ch=0;ch<im->channels;ch++) {
1469 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1473 return -1; /* error was cliped */
1477 =item i_glinf_d(im, l, r, y, vals)
1479 Reads a line of data from the image, storing the pixels at vals.
1481 The line runs from (l,y) inclusive to (r,y) non-inclusive
1483 vals should point at space for (r-l) pixels.
1485 l should never be less than zero (to avoid confusion about where to
1486 put the pixels in vals).
1488 Returns the number of pixels copied (eg. if r, l or y is out of range)
1494 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1496 unsigned char *data;
1497 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1500 data = im->idata + (l+y*im->xsize) * im->channels;
1502 for (i = 0; i < count; ++i) {
1503 for (ch = 0; ch < im->channels; ++ch)
1504 vals[i].channel[ch] = Sample8ToF(*data++);
1514 =item i_plinf_d(im, l, r, y, vals)
1516 Writes a line of data into the image, using the pixels at vals.
1518 The line runs from (l,y) inclusive to (r,y) non-inclusive
1520 vals should point at (r-l) pixels.
1522 l should never be less than zero (to avoid confusion about where to
1523 get the pixels in vals).
1525 Returns the number of pixels copied (eg. if r, l or y is out of range)
1531 i_plinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1533 unsigned char *data;
1534 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1537 data = im->idata + (l+y*im->xsize) * im->channels;
1539 for (i = 0; i < count; ++i) {
1540 for (ch = 0; ch < im->channels; ++ch) {
1541 if (im->ch_mask & (1 << ch))
1542 *data = SampleFTo8(vals[i].channel[ch]);
1554 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1556 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1557 for the channels specified by chans, an array of int with chan_count
1560 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1566 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1567 const int *chans, int chan_count) {
1568 int ch, count, i, w;
1569 unsigned char *data;
1571 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1574 data = im->idata + (l+y*im->xsize) * im->channels;
1579 /* make sure we have good channel numbers */
1580 for (ch = 0; ch < chan_count; ++ch) {
1581 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1582 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1586 for (i = 0; i < w; ++i) {
1587 for (ch = 0; ch < chan_count; ++ch) {
1588 *samps++ = data[chans[ch]];
1591 data += im->channels;
1595 for (i = 0; i < w; ++i) {
1596 for (ch = 0; ch < chan_count; ++ch) {
1597 *samps++ = data[ch];
1600 data += im->channels;
1612 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1614 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1615 for the channels specified by chan_mask, where bit 0 is the first
1618 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1624 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1625 const int *chans, int chan_count) {
1626 int ch, count, i, w;
1627 unsigned char *data;
1628 for (ch = 0; ch < chan_count; ++ch) {
1629 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1630 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1633 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1636 data = im->idata + (l+y*im->xsize) * im->channels;
1641 /* make sure we have good channel numbers */
1642 for (ch = 0; ch < chan_count; ++ch) {
1643 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1644 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1648 for (i = 0; i < w; ++i) {
1649 for (ch = 0; ch < chan_count; ++ch) {
1650 *samps++ = Sample8ToF(data[chans[ch]]);
1653 data += im->channels;
1657 for (i = 0; i < w; ++i) {
1658 for (ch = 0; ch < chan_count; ++ch) {
1659 *samps++ = Sample8ToF(data[ch]);
1662 data += im->channels;
1675 =head2 Image method wrappers
1677 These functions provide i_fsample_t functions in terms of their
1678 i_sample_t versions.
1682 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1687 int i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1691 for (ch = 0; ch < im->channels; ++ch)
1692 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1694 return i_ppix(im, x, y, &temp);
1698 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1702 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1706 if (i_gpix(im, x, y, &temp)) {
1707 for (ch = 0; ch < im->channels; ++ch)
1708 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1716 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1720 int i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1723 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1729 work = mymalloc(sizeof(i_color) * (r-l));
1730 for (i = 0; i < r-l; ++i) {
1731 for (ch = 0; ch < im->channels; ++ch)
1732 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1734 ret = i_plin(im, l, r, y, work);
1749 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1753 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1756 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1762 work = mymalloc(sizeof(i_color) * (r-l));
1763 ret = i_plin(im, l, r, y, work);
1764 for (i = 0; i < r-l; ++i) {
1765 for (ch = 0; ch < im->channels; ++ch)
1766 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1782 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1786 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1787 int const *chans, int chan_count) {
1790 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1796 work = mymalloc(sizeof(i_sample_t) * (r-l));
1797 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1798 for (i = 0; i < ret; ++i) {
1799 samp[i] = Sample8ToF(work[i]);
1817 =head2 Palette wrapper functions
1819 Used for virtual images, these forward palette calls to a wrapped image,
1820 assuming the wrapped image is the first pointer in the structure that
1821 im->ext_data points at.
1825 =item i_addcolors_forward(i_img *im, i_color *colors, int count)
1829 int i_addcolors_forward(i_img *im, i_color *colors, int count) {
1830 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1834 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1838 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1839 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1843 =item i_setcolors_forward(i_img *im, int i, i_color *color, int count)
1847 int i_setcolors_forward(i_img *im, int i, i_color *color, int count) {
1848 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1852 =item i_colorcount_forward(i_img *im)
1856 int i_colorcount_forward(i_img *im) {
1857 return i_colorcount(*(i_img **)im->ext_data);
1861 =item i_maxcolors_forward(i_img *im)
1865 int i_maxcolors_forward(i_img *im) {
1866 return i_maxcolors(*(i_img **)im->ext_data);
1870 =item i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry)
1874 int i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry) {
1875 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1881 =head2 Stream reading and writing wrapper functions
1885 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1887 Performs general read buffering for file readers that permit reading
1888 to be done through a callback.
1890 The final callback gets two parameters, a I<need> value, and a I<want>
1891 value, where I<need> is the amount of data that the file library needs
1892 to read, and I<want> is the amount of space available in the buffer
1893 maintained by these functions.
1895 This means if you need to read from a stream that you don't know the
1896 length of, you can return I<need> bytes, taking the performance hit of
1897 possibly expensive callbacks (eg. back to perl code), or if you are
1898 reading from a stream where it doesn't matter if some data is lost, or
1899 if the total length of the stream is known, you can return I<want>
1906 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1909 if (length < gci->length - gci->cpos) {
1911 memcpy(buf, gci->buffer+gci->cpos, length);
1912 gci->cpos += length;
1917 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1918 total += gci->length - gci->cpos;
1919 length -= gci->length - gci->cpos;
1920 buf += gci->length - gci->cpos;
1921 if (length < (int)sizeof(gci->buffer)) {
1925 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
1926 sizeof(gci->buffer))) > 0) {
1928 gci->length = did_read;
1930 copy_size = i_min(length, gci->length);
1931 memcpy(buf, gci->buffer, copy_size);
1932 gci->cpos += copy_size;
1935 length -= copy_size;
1939 /* just read the rest - too big for our buffer*/
1941 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
1951 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
1953 For use by callback file readers to initialize the reader buffer.
1955 Allocates, initializes and returns the reader buffer.
1957 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
1962 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
1963 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
1965 self->userdata = userdata;
1973 =item i_free_gen_read_data(i_gen_read_data *)
1979 void i_free_gen_read_data(i_gen_read_data *self) {
1984 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
1986 Performs write buffering for a callback based file writer.
1988 Failures are considered fatal, if a write fails then data will be
1995 i_gen_write_data *self,
1999 if (self->filledto && self->filledto+size > self->maxlength) {
2000 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2008 if (self->filledto+size <= self->maxlength) {
2010 memcpy(self->buffer+self->filledto, data, size);
2011 self->filledto += size;
2014 /* doesn't fit - hand it off */
2015 return self->cb(self->userdata, data, size);
2019 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2021 Allocates and initializes the data structure used by i_gen_writer.
2023 This should be released with L<image.c/i_free_gen_write_data>
2027 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2028 char *userdata, int max_length)
2030 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2032 self->userdata = userdata;
2033 self->maxlength = i_min(max_length, sizeof(self->buffer));
2034 if (self->maxlength < 0)
2035 self->maxlength = sizeof(self->buffer);
2042 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2044 Cleans up the write buffer.
2046 Will flush any left-over data if I<flush> is non-zero.
2048 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2050 Return zero only if flush is non-zero and info->cb() returns zero.
2056 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2058 int result = !flush ||
2059 info->filledto == 0 ||
2060 info->cb(info->userdata, info->buffer, info->filledto);
2069 =item i_test_format_probe(io_glue *data, int length)
2071 Check the beginning of the supplied file for a 'magic number'
2078 i_test_format_probe(io_glue *data, int length) {
2084 {"\xFF\xD8", "jpeg"},
2090 {"\x89PNG\x0d\x0a\x1a\x0a", "png"},
2103 io_glue_commit_types(data);
2104 rc = data->readcb(data, head, 18);
2105 if (rc == -1) return NULL;
2106 data->seekcb(data, -rc, SEEK_CUR);
2108 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2110 ssize_t len = strlen(formats[i].magic);
2111 if (rc<len) continue;
2112 c = !strncmp(formats[i].magic, head, len);
2114 match = formats[i].name;
2120 if (match && !strcmp(match, "jpeg")) {
2121 unsigned int x0, x1;
2122 rc = data->readcb(data, head, 18);
2123 if (rc == -1) return NULL;
2124 x0 = (unsigned char)head[0];
2125 x1 = (unsigned char)head[1];
2126 data->seekcb(data, -rc, SEEK_CUR);
2127 printf("Jpeg reread: %x %x\n", x0, x1);
2133 tga_header_verify(head)) return "tga";
2145 Arnar M. Hrafnkelsson <addi@umich.edu>
2147 Tony Cook <tony@develop-help.com>