8 image.c - implements most of the basic functions of Imager and much of the rest
14 c = i_color_new(red, green, blue, alpha);
22 image.c implements the basic functions to create and destroy image and
23 color objects for Imager.
25 =head1 FUNCTION REFERENCE
27 Some of these functions are internal.
38 #define minmax(a,b,i) ( ((a>=i)?a: ( (b<=i)?b:i )) )
40 /* Hack around an obscure linker bug on solaris - probably due to builtin gcc thingies */
41 static void fake(void) { ceil(1); }
43 static int i_ppix_d(i_img *im, int x, int y, i_color *val);
44 static int i_gpix_d(i_img *im, int x, int y, i_color *val);
45 static int i_glin_d(i_img *im, int l, int r, int y, i_color *vals);
46 static int i_plin_d(i_img *im, int l, int r, int y, i_color *vals);
47 static int i_ppixf_d(i_img *im, int x, int y, i_fcolor *val);
48 static int i_gpixf_d(i_img *im, int x, int y, i_fcolor *val);
49 static int i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
50 static int i_plinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
51 static int i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, const int *chans, int chan_count);
52 static int i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, const int *chans, int chan_count);
53 /*static int i_psamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count);
54 static int i_psampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count);*/
57 =item ICL_new_internal(r, g, b, a)
59 Return a new color object with values passed to it.
61 r - red component (range: 0 - 255)
62 g - green component (range: 0 - 255)
63 b - blue component (range: 0 - 255)
64 a - alpha component (range: 0 - 255)
70 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
73 mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
75 if ( (cl=mymalloc(sizeof(i_color))) == NULL) m_fatal(2,"malloc() error\n");
80 mm_log((1,"(%p) <- ICL_new_internal\n",cl));
86 =item ICL_set_internal(cl, r, g, b, a)
88 Overwrite a color with new values.
90 cl - pointer to color object
91 r - red component (range: 0 - 255)
92 g - green component (range: 0 - 255)
93 b - blue component (range: 0 - 255)
94 a - alpha component (range: 0 - 255)
100 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
101 mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
103 if ( (cl=mymalloc(sizeof(i_color))) == NULL)
104 m_fatal(2,"malloc() error\n");
109 mm_log((1,"(%p) <- ICL_set_internal\n",cl));
115 =item ICL_add(dst, src, ch)
117 Add src to dst inplace - dst is modified.
119 dst - pointer to destination color object
120 src - pointer to color object that is added
121 ch - number of channels
127 ICL_add(i_color *dst,i_color *src,int ch) {
130 tmp=dst->channel[i]+src->channel[i];
131 dst->channel[i]= tmp>255 ? 255:tmp;
138 Dump color information to log - strictly for debugging.
140 cl - pointer to color object
146 ICL_info(i_color *cl) {
147 mm_log((1,"i_color_info(cl* %p)\n",cl));
148 mm_log((1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
154 Destroy ancillary data for Color object.
156 cl - pointer to color object
162 ICL_DESTROY(i_color *cl) {
163 mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
168 =item i_fcolor_new(double r, double g, double b, double a)
172 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
175 mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
177 if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) m_fatal(2,"malloc() error\n");
182 mm_log((1,"(%p) <- i_fcolor_new\n",cl));
188 =item i_fcolor_destroy(i_fcolor *cl)
192 void i_fcolor_destroy(i_fcolor *cl) {
197 =item IIM_base_8bit_direct (static)
199 A static i_img object used to initialize direct 8-bit per sample images.
203 static i_img IIM_base_8bit_direct =
205 0, /* channels set */
206 0, 0, 0, /* xsize, ysize, bytes */
209 i_direct_type, /* type */
212 { 0, 0, NULL }, /* tags */
215 i_ppix_d, /* i_f_ppix */
216 i_ppixf_d, /* i_f_ppixf */
217 i_plin_d, /* i_f_plin */
218 i_plinf_d, /* i_f_plinf */
219 i_gpix_d, /* i_f_gpix */
220 i_gpixf_d, /* i_f_gpixf */
221 i_glin_d, /* i_f_glin */
222 i_glinf_d, /* i_f_glinf */
223 i_gsamp_d, /* i_f_gsamp */
224 i_gsampf_d, /* i_f_gsampf */
228 NULL, /* i_f_addcolors */
229 NULL, /* i_f_getcolors */
230 NULL, /* i_f_colorcount */
231 NULL, /* i_f_maxcolors */
232 NULL, /* i_f_findcolor */
233 NULL, /* i_f_setcolors */
235 NULL, /* i_f_destroy */
238 /*static void set_8bit_direct(i_img *im) {
239 im->i_f_ppix = i_ppix_d;
240 im->i_f_ppixf = i_ppixf_d;
241 im->i_f_plin = i_plin_d;
242 im->i_f_plinf = i_plinf_d;
243 im->i_f_gpix = i_gpix_d;
244 im->i_f_gpixf = i_gpixf_d;
245 im->i_f_glin = i_glin_d;
246 im->i_f_glinf = i_glinf_d;
249 im->i_f_addcolor = NULL;
250 im->i_f_getcolor = NULL;
251 im->i_f_colorcount = NULL;
252 im->i_f_findcolor = NULL;
256 =item IIM_new(x, y, ch)
258 Creates a new image object I<x> pixels wide, and I<y> pixels high with I<ch> channels.
265 IIM_new(int x,int y,int ch) {
267 mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
269 im=i_img_empty_ch(NULL,x,y,ch);
271 mm_log((1,"(%p) <- IIM_new\n",im));
277 IIM_DESTROY(i_img *im) {
278 mm_log((1,"IIM_DESTROY(im* %p)\n",im));
288 Create new image reference - notice that this isn't an object yet and
289 this should be fixed asap.
299 mm_log((1,"i_img_struct()\n"));
300 if ( (im=mymalloc(sizeof(i_img))) == NULL)
301 m_fatal(2,"malloc() error\n");
303 *im = IIM_base_8bit_direct;
311 mm_log((1,"(%p) <- i_img_struct\n",im));
316 =item i_img_empty(im, x, y)
318 Re-new image reference (assumes 3 channels)
321 x - xsize of destination image
322 y - ysize of destination image
324 **FIXME** what happens if a live image is passed in here?
326 Should this just call i_img_empty_ch()?
332 i_img_empty(i_img *im,int x,int y) {
333 mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
334 return i_img_empty_ch(im, x, y, 3);
338 =item i_img_empty_ch(im, x, y, ch)
340 Re-new image reference
343 x - xsize of destination image
344 y - ysize of destination image
345 ch - number of channels
351 i_img_empty_ch(i_img *im,int x,int y,int ch) {
352 mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
354 if ( (im=mymalloc(sizeof(i_img))) == NULL)
355 m_fatal(2,"malloc() error\n");
357 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
358 i_tags_new(&im->tags);
362 im->ch_mask = MAXINT;
363 im->bytes=x*y*im->channels;
364 if ( (im->idata=mymalloc(im->bytes)) == NULL) m_fatal(2,"malloc() error\n");
365 memset(im->idata,0,(size_t)im->bytes);
369 mm_log((1,"(%p) <- i_img_empty_ch\n",im));
374 =item i_img_exorcise(im)
384 i_img_exorcise(i_img *im) {
385 mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
386 i_tags_destroy(&im->tags);
388 (im->i_f_destroy)(im);
389 if (im->idata != NULL) { myfree(im->idata); }
395 im->i_f_ppix=i_ppix_d;
396 im->i_f_gpix=i_gpix_d;
397 im->i_f_plin=i_plin_d;
398 im->i_f_glin=i_glin_d;
403 =item i_img_destroy(im)
405 Destroy image and free data via exorcise.
413 i_img_destroy(i_img *im) {
414 mm_log((1,"i_img_destroy(im %p)\n",im));
416 if (im) { myfree(im); }
420 =item i_img_info(im, info)
422 Return image information
425 info - pointer to array to return data
427 info is an array of 4 integers with the following values:
432 info[3] - channel mask
439 i_img_info(i_img *im,int *info) {
440 mm_log((1,"i_img_info(im 0x%x)\n",im));
442 mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
443 mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
446 info[2] = im->channels;
447 info[3] = im->ch_mask;
457 =item i_img_setmask(im, ch_mask)
459 Set the image channel mask for I<im> to I<ch_mask>.
464 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
468 =item i_img_getmask(im)
470 Get the image channel mask for I<im>.
475 i_img_getmask(i_img *im) { return im->ch_mask; }
478 =item i_img_getchannels(im)
480 Get the number of channels in I<im>.
485 i_img_getchannels(i_img *im) { return im->channels; }
490 =item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
492 (x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
493 (tx,ty) specifies the upper left corner for the target image.
494 pass NULL in trans for non transparent i_colors.
500 i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans) {
502 int x,y,t,ttx,tty,tt,ch;
504 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",
505 im, src, x1, y1, x2, y2, tx, ty, trans));
507 if (x2<x1) { t=x1; x1=x2; x2=t; }
508 if (y2<y1) { t=y1; y1=y2; y2=t; }
520 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
521 if (tt) i_ppix(im,ttx,tty,&pv);
522 } else i_ppix(im,ttx,tty,&pv);
530 =item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
532 Copies image data from the area (x1,y1)-[x2,y2] in the source image to
533 a rectangle the same size with it's top-left corner at (tx,ty) in the
536 If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
542 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
543 int x, y, t, ttx, tty;
545 if (x2<x1) { t=x1; x1=x2; x2=t; }
546 if (y2<y1) { t=y1; y1=y2; y2=t; }
548 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
549 im, src, x1, y1, x2, y2, tx, ty));
551 if (im->bits == i_8_bits) {
554 for(y=y1; y<y2; y++) {
556 for(x=x1; x<x2; x++) {
557 i_gpix(src, x, y, &pv);
558 i_ppix(im, ttx, tty, &pv);
567 for(y=y1; y<y2; y++) {
569 for(x=x1; x<x2; x++) {
570 i_gpixf(src, x, y, &pv);
571 i_ppixf(im, ttx, tty, &pv);
580 =item i_copy(im, src)
582 Copies the contents of the image I<src> over the image I<im>.
588 i_copy(i_img *im, i_img *src) {
591 mm_log((1,"i_copy(im* %p,src %p)\n", im, src));
595 if (src->type == i_direct_type) {
596 if (src->bits == i_8_bits) {
598 i_img_empty_ch(im, x1, y1, src->channels);
599 pv = mymalloc(sizeof(i_color) * x1);
601 for (y = 0; y < y1; ++y) {
602 i_glin(src, 0, x1, y, pv);
603 i_plin(im, 0, x1, y, pv);
609 if (src->bits == i_16_bits)
610 i_img_16_new_low(im, x1, y1, src->channels);
611 else if (src->bits == i_double_bits)
612 i_img_double_new_low(im, x1, y1, src->channels);
614 fprintf(stderr, "i_copy(): Unknown image bit size %d\n", src->bits);
615 return; /* I dunno */
618 pv = mymalloc(sizeof(i_fcolor) * x1);
619 for (y = 0; y < y1; ++y) {
620 i_glinf(src, 0, x1, y, pv);
621 i_plinf(im, 0, x1, y, pv);
633 i_img_pal_new_low(im, x1, y1, src->channels, i_maxcolors(src));
634 /* copy across the palette */
635 count = i_colorcount(src);
636 for (index = 0; index < count; ++index) {
637 i_getcolors(src, index, &temp, 1);
638 i_addcolors(im, &temp, 1);
641 vals = mymalloc(sizeof(i_palidx) * x1);
642 for (y = 0; y < y1; ++y) {
643 i_gpal(src, 0, x1, y, vals);
644 i_ppal(im, 0, x1, y, vals);
652 =item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
654 Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
655 overlays it at (I<tx>,I<ty>) on the image object.
657 The alpha channel of each pixel in I<src> is used to control how much
658 the existing colour in I<im> is replaced, if it is 255 then the colour
659 is completely replaced, if it is 0 then the original colour is left
666 i_rubthru(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny,
667 int src_maxx, int src_maxy) {
674 mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d, src_minx %d, "
675 "src_miny %d, src_maxx %d, src_maxy %d)\n",
676 im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy));
679 if (im->channels == 3 && src->channels == 4) {
681 chans[0] = 0; chans[1] = 1; chans[2] = 2;
684 else if (im->channels == 3 && src->channels == 2) {
686 chans[0] = chans[1] = chans[2] = 0;
689 else if (im->channels == 1 && src->channels == 2) {
695 i_push_error(0, "rubthru can only work where (dest, src) channels are (3,4), (3,2) or (1,2)");
700 /* if you change this code, please make sure the else branch is
701 changed in a similar fashion - TC */
703 i_color pv, orig, dest;
705 for(y = src_miny; y < src_maxy; y++) {
707 for(x = src_minx; x < src_maxx; x++) {
708 i_gpix(src, x, y, &pv);
709 i_gpix(im, ttx, tty, &orig);
710 alpha = pv.channel[alphachan];
711 for (ch = 0; ch < chancount; ++ch) {
712 dest.channel[ch] = (alpha * pv.channel[chans[ch]]
713 + (255 - alpha) * orig.channel[ch])/255;
715 i_ppix(im, ttx, tty, &dest);
723 i_fcolor pv, orig, dest;
726 for(y = src_miny; y < src_maxy; y++) {
728 for(x = src_minx; x < src_maxx; x++) {
729 i_gpixf(src, x, y, &pv);
730 i_gpixf(im, ttx, tty, &orig);
731 alpha = pv.channel[alphachan];
732 for (ch = 0; ch < chancount; ++ch) {
733 dest.channel[ch] = alpha * pv.channel[chans[ch]]
734 + (1 - alpha) * orig.channel[ch];
736 i_ppixf(im, ttx, tty, &dest);
748 =item i_flipxy(im, axis)
750 Flips the image inplace around the axis specified.
751 Returns 0 if parameters are invalid.
754 axis - 0 = x, 1 = y, 2 = both
760 i_flipxy(i_img *im, int direction) {
761 int x, x2, y, y2, xm, ym;
765 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
770 case XAXIS: /* Horizontal flip */
773 for(y=0; y<ym; y++) {
775 for(x=0; x<xm; x++) {
777 i_gpix(im, x, y, &val1);
778 i_gpix(im, x2, y, &val2);
779 i_ppix(im, x, y, &val2);
780 i_ppix(im, x2, y, &val1);
785 case YAXIS: /* Vertical flip */
789 for(y=0; y<ym; y++) {
790 for(x=0; x<xm; x++) {
792 i_gpix(im, x, y, &val1);
793 i_gpix(im, x, y2, &val2);
794 i_ppix(im, x, y, &val2);
795 i_ppix(im, x, y2, &val1);
800 case XYAXIS: /* Horizontal and Vertical flip */
804 for(y=0; y<ym; y++) {
806 for(x=0; x<xm; x++) {
808 i_gpix(im, x, y, &val1);
809 i_gpix(im, x2, y2, &val2);
810 i_ppix(im, x, y, &val2);
811 i_ppix(im, x2, y2, &val1);
813 i_gpix(im, x2, y, &val1);
814 i_gpix(im, x, y2, &val2);
815 i_ppix(im, x2, y, &val2);
816 i_ppix(im, x, y2, &val1);
821 if (xm*2 != xs) { /* odd number of column */
822 mm_log((1, "i_flipxy: odd number of columns\n"));
825 for(y=0; y<ym; y++) {
827 i_gpix(im, x, y, &val1);
828 i_gpix(im, x, y2, &val2);
829 i_ppix(im, x, y, &val2);
830 i_ppix(im, x, y2, &val1);
834 if (ym*2 != ys) { /* odd number of rows */
835 mm_log((1, "i_flipxy: odd number of rows\n"));
838 for(x=0; x<xm; x++) {
840 i_gpix(im, x, y, &val1);
841 i_gpix(im, x2, y, &val2);
842 i_ppix(im, x, y, &val2);
843 i_ppix(im, x2, y, &val1);
849 mm_log((1, "i_flipxy: direction is invalid\n" ));
867 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
868 else if (x == 0.0) return (1.0);
869 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
874 =item i_scaleaxis(im, value, axis)
876 Returns a new image object which is I<im> scaled by I<value> along
877 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
883 i_scaleaxis(i_img *im, float Value, int Axis) {
884 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
885 int LanczosWidthFactor;
886 float *l0, *l1, OldLocation;
889 float F, PictureValue[MAXCHANNELS];
891 i_color val,val1,val2;
894 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
898 hsize = (int)(0.5 + im->xsize * Value);
905 vsize = (int)(0.5 + im->ysize * Value);
911 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
913 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
914 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
915 lMax = LanczosWidthFactor << 1;
917 l0 = mymalloc(lMax * sizeof(float));
918 l1 = mymalloc(lMax * sizeof(float));
920 for (j=0; j<jEnd; j++) {
921 OldLocation = ((float) j) / Value;
922 T = (int) (OldLocation);
923 F = OldLocation - (float) T;
925 for (l = 0; l<lMax; l++) {
926 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
927 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
930 /* Make sure filter is normalized */
932 for(l=0; l<lMax; l++) {
936 t /= (float)LanczosWidthFactor;
938 for(l=0; l<lMax; l++) {
945 for (i=0; i<iEnd; i++) {
946 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
947 for (l=0; l<lMax; l++) {
950 mx = (mx < 0) ? 0 : mx;
951 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
953 i_gpix(im, Mx, i, &val1);
954 i_gpix(im, mx, i, &val2);
956 for (k=0; k<im->channels; k++) {
957 PictureValue[k] += l1[l] * val1.channel[k];
958 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
961 for(k=0;k<im->channels;k++) {
962 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
963 val.channel[k]=minmax(0,255,psave);
965 i_ppix(new_img, j, i, &val);
970 for (i=0; i<iEnd; i++) {
971 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
972 for (l=0; l < lMax; l++) {
975 mx = (mx < 0) ? 0 : mx;
976 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
978 i_gpix(im, i, Mx, &val1);
979 i_gpix(im, i, mx, &val2);
980 for (k=0; k<im->channels; k++) {
981 PictureValue[k] += l1[l] * val1.channel[k];
982 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
985 for (k=0; k<im->channels; k++) {
986 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
987 val.channel[k] = minmax(0, 255, psave);
989 i_ppix(new_img, i, j, &val);
997 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
1004 =item i_scale_nn(im, scx, scy)
1006 Scale by using nearest neighbor
1007 Both axes scaled at the same time since
1008 nothing is gained by doing it in two steps
1015 i_scale_nn(i_img *im, float scx, float scy) {
1017 int nxsize,nysize,nx,ny;
1021 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
1023 nxsize = (int) ((float) im->xsize * scx);
1024 nysize = (int) ((float) im->ysize * scy);
1026 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1028 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1029 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1030 i_ppix(new_img,nx,ny,&val);
1033 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1039 =item i_sametype(i_img *im, int xsize, int ysize)
1041 Returns an image of the same type (sample size, channels, paletted/direct).
1043 For paletted images the palette is copied from the source.
1048 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1049 if (src->type == i_direct_type) {
1050 if (src->bits == 8) {
1051 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1053 else if (src->bits == i_16_bits) {
1054 return i_img_16_new(xsize, ysize, src->channels);
1056 else if (src->bits == i_double_bits) {
1057 return i_img_double_new(xsize, ysize, src->channels);
1060 i_push_error(0, "Unknown image bits");
1068 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1069 for (i = 0; i < i_colorcount(src); ++i) {
1070 i_getcolors(src, i, &col, 1);
1071 i_addcolors(targ, &col, 1);
1079 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1081 Returns an image of the same type (sample size).
1083 For paletted images the equivalent direct type is returned.
1088 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1089 if (src->bits == 8) {
1090 return i_img_empty_ch(NULL, xsize, ysize, channels);
1092 else if (src->bits == i_16_bits) {
1093 return i_img_16_new(xsize, ysize, channels);
1095 else if (src->bits == i_double_bits) {
1096 return i_img_double_new(xsize, ysize, channels);
1099 i_push_error(0, "Unknown image bits");
1105 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1107 Spatially transforms I<im> returning a new image.
1109 opx for a length of opxl and opy for a length of opy are arrays of
1110 operators that modify the x and y positions to retreive the pixel data from.
1112 parm and parmlen define extra parameters that the operators may use.
1114 Note that this function is largely superseded by the more flexible
1115 L<transform.c/i_transform2>.
1117 Returns the new image.
1119 The operators for this function are defined in L<stackmach.c>.
1124 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1126 int nxsize,nysize,nx,ny;
1130 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));
1133 nysize = im->ysize ;
1135 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1136 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1137 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1138 /* parm[parmlen-2]=(double)nx;
1139 parm[parmlen-1]=(double)ny; */
1144 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1145 rx=i_op_run(opx,opxl,parm,parmlen);
1146 ry=i_op_run(opy,opyl,parm,parmlen);
1147 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1148 i_gpix(im,rx,ry,&val);
1149 i_ppix(new_img,nx,ny,&val);
1152 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1157 =item i_img_diff(im1, im2)
1159 Calculates the sum of the squares of the differences between
1160 correspoding channels in two images.
1162 If the images are not the same size then only the common area is
1163 compared, hence even if images are different sizes this function
1169 i_img_diff(i_img *im1,i_img *im2) {
1170 int x,y,ch,xb,yb,chb;
1174 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1176 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1177 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1178 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1180 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1183 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1184 i_gpix(im1,x,y,&val1);
1185 i_gpix(im2,x,y,&val2);
1187 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1189 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1193 /* just a tiny demo of haar wavelets */
1201 i_img *new_img,*new_img2;
1202 i_color val1,val2,dval1,dval2;
1210 /* horizontal pass */
1212 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1213 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1216 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1217 i_gpix(im,x*2,y,&val1);
1218 i_gpix(im,x*2+1,y,&val2);
1219 for(ch=0;ch<im->channels;ch++) {
1220 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1221 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1223 i_ppix(new_img,x,y,&dval1);
1224 i_ppix(new_img,x+fx,y,&dval2);
1227 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1228 i_gpix(new_img,x,y*2,&val1);
1229 i_gpix(new_img,x,y*2+1,&val2);
1230 for(ch=0;ch<im->channels;ch++) {
1231 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1232 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1234 i_ppix(new_img2,x,y,&dval1);
1235 i_ppix(new_img2,x,y+fy,&dval2);
1238 i_img_destroy(new_img);
1243 =item i_count_colors(im, maxc)
1245 returns number of colors or -1
1246 to indicate that it was more than max colors
1251 i_count_colors(i_img *im,int maxc) {
1258 mm_log((1,"i_count_colors(im 0x%08X,maxc %d)\n"));
1265 for(y=0;y<ysize;y++) for(x=0;x<xsize;x++) {
1266 i_gpix(im,x,y,&val);
1267 colorcnt+=octt_add(ct,val.rgb.r,val.rgb.g,val.rgb.b);
1268 if (colorcnt > maxc) { octt_delete(ct); return -1; }
1277 =head2 8-bit per sample image internal functions
1279 These are the functions installed in an 8-bit per sample image.
1283 =item i_ppix_d(im, x, y, col)
1287 This is the function kept in the i_f_ppix member of an i_img object.
1288 It does a normal store of a pixel into the image with range checking.
1290 Returns 0 if the pixel could be set, -1 otherwise.
1296 i_ppix_d(i_img *im, int x, int y, i_color *val) {
1299 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1300 for(ch=0;ch<im->channels;ch++)
1301 if (im->ch_mask&(1<<ch))
1302 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1305 return -1; /* error was clipped */
1309 =item i_gpix_d(im, x, y, &col)
1313 This is the function kept in the i_f_gpix member of an i_img object.
1314 It does normal retrieval of a pixel from the image with range checking.
1316 Returns 0 if the pixel could be set, -1 otherwise.
1322 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1324 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1325 for(ch=0;ch<im->channels;ch++)
1326 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1329 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1330 return -1; /* error was cliped */
1334 =item i_glin_d(im, l, r, y, vals)
1336 Reads a line of data from the image, storing the pixels at vals.
1338 The line runs from (l,y) inclusive to (r,y) non-inclusive
1340 vals should point at space for (r-l) pixels.
1342 l should never be less than zero (to avoid confusion about where to
1343 put the pixels in vals).
1345 Returns the number of pixels copied (eg. if r, l or y is out of range)
1351 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1353 unsigned char *data;
1354 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1357 data = im->idata + (l+y*im->xsize) * im->channels;
1359 for (i = 0; i < count; ++i) {
1360 for (ch = 0; ch < im->channels; ++ch)
1361 vals[i].channel[ch] = *data++;
1371 =item i_plin_d(im, l, r, y, vals)
1373 Writes a line of data into the image, using the pixels at vals.
1375 The line runs from (l,y) inclusive to (r,y) non-inclusive
1377 vals should point at (r-l) pixels.
1379 l should never be less than zero (to avoid confusion about where to
1380 get the pixels in vals).
1382 Returns the number of pixels copied (eg. if r, l or y is out of range)
1388 i_plin_d(i_img *im, int l, int r, int y, i_color *vals) {
1390 unsigned char *data;
1391 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1394 data = im->idata + (l+y*im->xsize) * im->channels;
1396 for (i = 0; i < count; ++i) {
1397 for (ch = 0; ch < im->channels; ++ch) {
1398 if (im->ch_mask & (1 << ch))
1399 *data = vals[i].channel[ch];
1411 =item i_ppixf_d(im, x, y, val)
1417 i_ppixf_d(i_img *im, int x, int y, i_fcolor *val) {
1420 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1421 for(ch=0;ch<im->channels;ch++)
1422 if (im->ch_mask&(1<<ch)) {
1423 im->idata[(x+y*im->xsize)*im->channels+ch] =
1424 SampleFTo8(val->channel[ch]);
1428 return -1; /* error was clipped */
1432 =item i_gpixf_d(im, x, y, val)
1438 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1440 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1441 for(ch=0;ch<im->channels;ch++) {
1443 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1447 return -1; /* error was cliped */
1451 =item i_glinf_d(im, l, r, y, vals)
1453 Reads a line of data from the image, storing the pixels at vals.
1455 The line runs from (l,y) inclusive to (r,y) non-inclusive
1457 vals should point at space for (r-l) pixels.
1459 l should never be less than zero (to avoid confusion about where to
1460 put the pixels in vals).
1462 Returns the number of pixels copied (eg. if r, l or y is out of range)
1468 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1470 unsigned char *data;
1471 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1474 data = im->idata + (l+y*im->xsize) * im->channels;
1476 for (i = 0; i < count; ++i) {
1477 for (ch = 0; ch < im->channels; ++ch)
1478 vals[i].channel[ch] = Sample8ToF(*data++);
1488 =item i_plinf_d(im, l, r, y, vals)
1490 Writes a line of data into the image, using the pixels at vals.
1492 The line runs from (l,y) inclusive to (r,y) non-inclusive
1494 vals should point at (r-l) pixels.
1496 l should never be less than zero (to avoid confusion about where to
1497 get the pixels in vals).
1499 Returns the number of pixels copied (eg. if r, l or y is out of range)
1505 i_plinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1507 unsigned char *data;
1508 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1511 data = im->idata + (l+y*im->xsize) * im->channels;
1513 for (i = 0; i < count; ++i) {
1514 for (ch = 0; ch < im->channels; ++ch) {
1515 if (im->ch_mask & (1 << ch))
1516 *data = SampleFTo8(vals[i].channel[ch]);
1528 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1530 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1531 for the channels specified by chans, an array of int with chan_count
1534 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1540 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1541 const int *chans, int chan_count) {
1542 int ch, count, i, w;
1543 unsigned char *data;
1545 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1548 data = im->idata + (l+y*im->xsize) * im->channels;
1553 /* make sure we have good channel numbers */
1554 for (ch = 0; ch < chan_count; ++ch) {
1555 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1556 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1560 for (i = 0; i < w; ++i) {
1561 for (ch = 0; ch < chan_count; ++ch) {
1562 *samps++ = data[chans[ch]];
1565 data += im->channels;
1569 for (i = 0; i < w; ++i) {
1570 for (ch = 0; ch < chan_count; ++ch) {
1571 *samps++ = data[ch];
1574 data += im->channels;
1586 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1588 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1589 for the channels specified by chan_mask, where bit 0 is the first
1592 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1598 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1599 const int *chans, int chan_count) {
1600 int ch, count, i, w;
1601 unsigned char *data;
1602 for (ch = 0; ch < chan_count; ++ch) {
1603 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1604 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1607 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1610 data = im->idata + (l+y*im->xsize) * im->channels;
1615 /* make sure we have good channel numbers */
1616 for (ch = 0; ch < chan_count; ++ch) {
1617 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1618 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1622 for (i = 0; i < w; ++i) {
1623 for (ch = 0; ch < chan_count; ++ch) {
1624 *samps++ = Sample8ToF(data[chans[ch]]);
1627 data += im->channels;
1631 for (i = 0; i < w; ++i) {
1632 for (ch = 0; ch < chan_count; ++ch) {
1633 *samps++ = Sample8ToF(data[ch]);
1636 data += im->channels;
1649 =head2 Image method wrappers
1651 These functions provide i_fsample_t functions in terms of their
1652 i_sample_t versions.
1656 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1661 int i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1665 for (ch = 0; ch < im->channels; ++ch)
1666 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1668 return i_ppix(im, x, y, &temp);
1672 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1676 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1680 if (i_gpix(im, x, y, &temp)) {
1681 for (ch = 0; ch < im->channels; ++ch)
1682 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1690 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1694 int i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1697 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1703 work = mymalloc(sizeof(i_color) * (r-l));
1704 for (i = 0; i < r-l; ++i) {
1705 for (ch = 0; ch < im->channels; ++ch)
1706 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1708 ret = i_plin(im, l, r, y, work);
1723 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1727 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1730 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1736 work = mymalloc(sizeof(i_color) * (r-l));
1737 ret = i_plin(im, l, r, y, work);
1738 for (i = 0; i < r-l; ++i) {
1739 for (ch = 0; ch < im->channels; ++ch)
1740 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1756 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1760 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1761 int const *chans, int chan_count) {
1764 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1770 work = mymalloc(sizeof(i_sample_t) * (r-l));
1771 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1772 for (i = 0; i < ret; ++i) {
1773 samp[i] = Sample8ToF(work[i]);
1791 =head2 Palette wrapper functions
1793 Used for virtual images, these forward palette calls to a wrapped image,
1794 assuming the wrapped image is the first pointer in the structure that
1795 im->ext_data points at.
1799 =item i_addcolors_forward(i_img *im, i_color *colors, int count)
1803 int i_addcolors_forward(i_img *im, i_color *colors, int count) {
1804 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1808 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1812 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1813 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1817 =item i_setcolors_forward(i_img *im, int i, i_color *color, int count)
1821 int i_setcolors_forward(i_img *im, int i, i_color *color, int count) {
1822 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1826 =item i_colorcount_forward(i_img *im)
1830 int i_colorcount_forward(i_img *im) {
1831 return i_colorcount(*(i_img **)im->ext_data);
1835 =item i_maxcolors_forward(i_img *im)
1839 int i_maxcolors_forward(i_img *im) {
1840 return i_maxcolors(*(i_img **)im->ext_data);
1844 =item i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry)
1848 int i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry) {
1849 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1855 =head2 Stream reading and writing wrapper functions
1859 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1861 Performs general read buffering for file readers that permit reading
1862 to be done through a callback.
1864 The final callback gets two parameters, a I<need> value, and a I<want>
1865 value, where I<need> is the amount of data that the file library needs
1866 to read, and I<want> is the amount of space available in the buffer
1867 maintained by these functions.
1869 This means if you need to read from a stream that you don't know the
1870 length of, you can return I<need> bytes, taking the performance hit of
1871 possibly expensive callbacks (eg. back to perl code), or if you are
1872 reading from a stream where it doesn't matter if some data is lost, or
1873 if the total length of the stream is known, you can return I<want>
1880 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1883 if (length < gci->length - gci->cpos) {
1885 memcpy(buf, gci->buffer+gci->cpos, length);
1886 gci->cpos += length;
1891 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1892 total += gci->length - gci->cpos;
1893 length -= gci->length - gci->cpos;
1894 buf += gci->length - gci->cpos;
1895 if (length < (int)sizeof(gci->buffer)) {
1899 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
1900 sizeof(gci->buffer))) > 0) {
1902 gci->length = did_read;
1904 copy_size = i_min(length, gci->length);
1905 memcpy(buf, gci->buffer, copy_size);
1906 gci->cpos += copy_size;
1909 length -= copy_size;
1913 /* just read the rest - too big for our buffer*/
1915 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
1925 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
1927 For use by callback file readers to initialize the reader buffer.
1929 Allocates, initializes and returns the reader buffer.
1931 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
1936 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
1937 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
1939 self->userdata = userdata;
1947 =item i_free_gen_read_data(i_gen_read_data *)
1953 void i_free_gen_read_data(i_gen_read_data *self) {
1958 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
1960 Performs write buffering for a callback based file writer.
1962 Failures are considered fatal, if a write fails then data will be
1969 i_gen_write_data *self,
1973 if (self->filledto && self->filledto+size > self->maxlength) {
1974 if (self->cb(self->userdata, self->buffer, self->filledto)) {
1982 if (self->filledto+size <= self->maxlength) {
1984 memcpy(self->buffer+self->filledto, data, size);
1985 self->filledto += size;
1988 /* doesn't fit - hand it off */
1989 return self->cb(self->userdata, data, size);
1993 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
1995 Allocates and initializes the data structure used by i_gen_writer.
1997 This should be released with L<image.c/i_free_gen_write_data>
2001 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2002 char *userdata, int max_length)
2004 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2006 self->userdata = userdata;
2007 self->maxlength = i_min(max_length, sizeof(self->buffer));
2008 if (self->maxlength < 0)
2009 self->maxlength = sizeof(self->buffer);
2016 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2018 Cleans up the write buffer.
2020 Will flush any left-over data if I<flush> is non-zero.
2022 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2024 Return zero only if flush is non-zero and info->cb() returns zero.
2030 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2032 int result = !flush ||
2033 info->filledto == 0 ||
2034 info->cb(info->userdata, info->buffer, info->filledto);
2043 =item i_test_format_probe(io_glue *data, int length)
2045 Cleans up the write buffer.
2047 Will flush any left-over data if I<flush> is non-zero.
2049 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2051 Return zero only if flush is non-zero and info->cb() returns zero.
2059 i_test_format_probe(io_glue *data, int length) {
2065 {"\xFF\xD8", "jpeg"},
2071 {"\x89PNG\x0d\x0a\x1a\x0a", "png"},
2084 io_glue_commit_types(data);
2085 rc = data->readcb(data, head, 18);
2086 if (rc == -1) return NULL;
2087 data->seekcb(data, -rc, SEEK_CUR);
2089 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2091 ssize_t len = strlen(formats[i].magic);
2092 if (rc<len) continue;
2093 c = !strncmp(formats[i].magic, head, len);
2095 match = formats[i].name;
2101 if (match && !strcmp(match, "jpeg")) {
2102 unsigned int x0, x1;
2103 rc = data->readcb(data, head, 18);
2104 if (rc == -1) return NULL;
2105 x0 = (unsigned char)head[0];
2106 x1 = (unsigned char)head[1];
2107 data->seekcb(data, -rc, SEEK_CUR);
2108 printf("Jpeg reread: %x %x\n", x0, x1);
2114 tga_header_verify(head)) return "tga";
2126 Arnar M. Hrafnkelsson <addi@umich.edu>
2128 Tony Cook <tony@develop-help.com>