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, const 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, const i_color *vals);
46 static int i_ppixf_d(i_img *im, int x, int y, const 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, const 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) i_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 i_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 const *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) i_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 =item i_img_8_new(x, y, ch)
259 =category Image creation
261 Creates a new image object I<x> pixels wide, and I<y> pixels high with
269 IIM_new(int x,int y,int ch) {
271 mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
273 im=i_img_empty_ch(NULL,x,y,ch);
275 mm_log((1,"(%p) <- IIM_new\n",im));
281 IIM_DESTROY(i_img *im) {
282 mm_log((1,"IIM_DESTROY(im* %p)\n",im));
290 Create new image reference - notice that this isn't an object yet and
291 this should be fixed asap.
301 mm_log((1,"i_img_struct()\n"));
302 if ( (im=mymalloc(sizeof(i_img))) == NULL)
303 i_fatal(2,"malloc() error\n");
305 *im = IIM_base_8bit_direct;
313 mm_log((1,"(%p) <- i_img_struct\n",im));
318 =item i_img_empty(im, x, y)
320 Re-new image reference (assumes 3 channels)
323 x - xsize of destination image
324 y - ysize of destination image
326 **FIXME** what happens if a live image is passed in here?
328 Should this just call i_img_empty_ch()?
334 i_img_empty(i_img *im,int x,int y) {
335 mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
336 return i_img_empty_ch(im, x, y, 3);
340 =item i_img_empty_ch(im, x, y, ch)
342 Re-new image reference
345 x - xsize of destination image
346 y - ysize of destination image
347 ch - number of channels
353 i_img_empty_ch(i_img *im,int x,int y,int ch) {
356 mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
358 if (x < 1 || y < 1) {
359 i_push_error(0, "Image sizes must be positive");
362 if (ch < 1 || ch > MAXCHANNELS) {
363 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
366 /* check this multiplication doesn't overflow */
368 if (bytes / y / ch != x) {
369 i_push_errorf(0, "integer overflow calculating image allocation");
374 if ( (im=mymalloc(sizeof(i_img))) == NULL)
375 i_fatal(2,"malloc() error\n");
377 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
378 i_tags_new(&im->tags);
382 im->ch_mask = MAXINT;
384 if ( (im->idata=mymalloc(im->bytes)) == NULL)
385 i_fatal(2,"malloc() error\n");
386 memset(im->idata,0,(size_t)im->bytes);
390 mm_log((1,"(%p) <- i_img_empty_ch\n",im));
395 =item i_img_exorcise(im)
405 i_img_exorcise(i_img *im) {
406 mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
407 i_tags_destroy(&im->tags);
409 (im->i_f_destroy)(im);
410 if (im->idata != NULL) { myfree(im->idata); }
416 im->i_f_ppix=i_ppix_d;
417 im->i_f_gpix=i_gpix_d;
418 im->i_f_plin=i_plin_d;
419 im->i_f_glin=i_glin_d;
424 =item i_img_destroy(im)
428 Destroy image and free data via exorcise.
436 i_img_destroy(i_img *im) {
437 mm_log((1,"i_img_destroy(im %p)\n",im));
439 if (im) { myfree(im); }
443 =item i_img_info(im, info)
447 Return image information
450 info - pointer to array to return data
452 info is an array of 4 integers with the following values:
457 info[3] - channel mask
464 i_img_info(i_img *im,int *info) {
465 mm_log((1,"i_img_info(im 0x%x)\n",im));
467 mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
468 mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
471 info[2] = im->channels;
472 info[3] = im->ch_mask;
482 =item i_img_setmask(im, ch_mask)
484 =synopsis // only channel 0 writeable
485 =synopsis i_img_setmask(img, 0x01);
487 Set the image channel mask for I<im> to I<ch_mask>.
492 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
496 =item i_img_getmask(im)
498 =synopsis mask = i_img_getmask(img);
500 Get the image channel mask for I<im>.
505 i_img_getmask(i_img *im) { return im->ch_mask; }
508 =item i_img_getchannels(im)
510 =synopsis channels = i_img_getchannels(img);
512 Get the number of channels in I<im>.
517 i_img_getchannels(i_img *im) { return im->channels; }
520 =item i_img_get_width(im)
522 =synopsis width = i_img_get_width(im);
524 Returns the width in pixels of the image.
529 i_img_get_width(i_img *im) {
534 =item i_img_get_height(im)
536 =synopsis height = i_img_get_height(im);
538 Returns the height in pixels of the image.
543 i_img_get_height(i_img *im) {
548 =item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
552 (x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
553 (tx,ty) specifies the upper left corner for the target image.
554 pass NULL in trans for non transparent i_colors.
560 i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,const i_color *trans) {
562 int x,y,t,ttx,tty,tt,ch;
564 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",
565 im, src, x1, y1, x2, y2, tx, ty, trans));
567 if (x2<x1) { t=x1; x1=x2; x2=t; }
568 if (y2<y1) { t=y1; y1=y2; y2=t; }
580 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
581 if (tt) i_ppix(im,ttx,tty,&pv);
582 } else i_ppix(im,ttx,tty,&pv);
590 =item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
594 Copies image data from the area (x1,y1)-[x2,y2] in the source image to
595 a rectangle the same size with it's top-left corner at (tx,ty) in the
598 If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
604 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
605 int x, y, t, ttx, tty;
607 if (x2<x1) { t=x1; x1=x2; x2=t; }
608 if (y2<y1) { t=y1; y1=y2; y2=t; }
610 /* adjust everything equally */
620 if (x1 >= src->xsize || y1 >= src->ysize)
621 return; /* nothing to do */
626 if (x1 == x2 || y1 == y2)
627 return; /* nothing to do */
629 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
630 im, src, x1, y1, x2, y2, tx, ty));
632 if (im->bits == i_8_bits) {
633 i_color *row = mymalloc(sizeof(i_color) * (x2-x1));
635 for(y=y1; y<y2; y++) {
637 i_glin(src, x1, x2, y, row);
638 i_plin(im, tx, tx+x2-x1, tty, row);
646 for(y=y1; y<y2; y++) {
648 for(x=x1; x<x2; x++) {
649 i_gpixf(src, x, y, &pv);
650 i_ppixf(im, ttx, tty, &pv);
663 Creates a new image that is a copy of src.
665 Tags are not copied, only the image data.
675 i_img *im = i_sametype(src, src->xsize, src->ysize);
677 mm_log((1,"i_copy(src %p)\n", src));
684 if (src->type == i_direct_type) {
685 if (src->bits == i_8_bits) {
687 pv = mymalloc(sizeof(i_color) * x1);
689 for (y = 0; y < y1; ++y) {
690 i_glin(src, 0, x1, y, pv);
691 i_plin(im, 0, x1, y, pv);
698 pv = mymalloc(sizeof(i_fcolor) * x1);
699 for (y = 0; y < y1; ++y) {
700 i_glinf(src, 0, x1, y, pv);
701 i_plinf(im, 0, x1, y, pv);
713 i_img_pal_new_low(im, x1, y1, src->channels, i_maxcolors(src));
714 /* copy across the palette */
715 count = i_colorcount(src);
716 for (index = 0; index < count; ++index) {
717 i_getcolors(src, index, &temp, 1);
718 i_addcolors(im, &temp, 1);
721 vals = mymalloc(sizeof(i_palidx) * x1);
722 for (y = 0; y < y1; ++y) {
723 i_gpal(src, 0, x1, y, vals);
724 i_ppal(im, 0, x1, y, vals);
734 =item i_flipxy(im, axis)
736 Flips the image inplace around the axis specified.
737 Returns 0 if parameters are invalid.
740 axis - 0 = x, 1 = y, 2 = both
746 i_flipxy(i_img *im, int direction) {
747 int x, x2, y, y2, xm, ym;
751 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
756 case XAXIS: /* Horizontal flip */
759 for(y=0; y<ym; y++) {
761 for(x=0; x<xm; x++) {
763 i_gpix(im, x, y, &val1);
764 i_gpix(im, x2, y, &val2);
765 i_ppix(im, x, y, &val2);
766 i_ppix(im, x2, y, &val1);
771 case YAXIS: /* Vertical flip */
775 for(y=0; y<ym; y++) {
776 for(x=0; x<xm; x++) {
778 i_gpix(im, x, y, &val1);
779 i_gpix(im, x, y2, &val2);
780 i_ppix(im, x, y, &val2);
781 i_ppix(im, x, y2, &val1);
786 case XYAXIS: /* Horizontal and Vertical flip */
790 for(y=0; y<ym; y++) {
792 for(x=0; x<xm; x++) {
794 i_gpix(im, x, y, &val1);
795 i_gpix(im, x2, y2, &val2);
796 i_ppix(im, x, y, &val2);
797 i_ppix(im, x2, y2, &val1);
799 i_gpix(im, x2, y, &val1);
800 i_gpix(im, x, y2, &val2);
801 i_ppix(im, x2, y, &val2);
802 i_ppix(im, x, y2, &val1);
807 if (xm*2 != xs) { /* odd number of column */
808 mm_log((1, "i_flipxy: odd number of columns\n"));
811 for(y=0; y<ym; y++) {
813 i_gpix(im, x, y, &val1);
814 i_gpix(im, x, y2, &val2);
815 i_ppix(im, x, y, &val2);
816 i_ppix(im, x, y2, &val1);
820 if (ym*2 != ys) { /* odd number of rows */
821 mm_log((1, "i_flipxy: odd number of rows\n"));
824 for(x=0; x<xm; x++) {
826 i_gpix(im, x, y, &val1);
827 i_gpix(im, x2, y, &val2);
828 i_ppix(im, x, y, &val2);
829 i_ppix(im, x2, y, &val1);
835 mm_log((1, "i_flipxy: direction is invalid\n" ));
853 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
854 else if (x == 0.0) return (1.0);
855 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
860 =item i_scaleaxis(im, value, axis)
862 Returns a new image object which is I<im> scaled by I<value> along
863 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
869 i_scaleaxis(i_img *im, float Value, int Axis) {
870 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
871 int LanczosWidthFactor;
872 float *l0, *l1, OldLocation;
875 float F, PictureValue[MAXCHANNELS];
877 i_color val,val1,val2;
880 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
884 hsize = (int)(0.5 + im->xsize * Value);
887 Value = 1.0 / im->xsize;
895 vsize = (int)(0.5 + im->ysize * Value);
899 Value = 1.0 / im->ysize;
906 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
908 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
909 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
910 lMax = LanczosWidthFactor << 1;
912 l0 = mymalloc(lMax * sizeof(float));
913 l1 = mymalloc(lMax * sizeof(float));
915 for (j=0; j<jEnd; j++) {
916 OldLocation = ((float) j) / Value;
917 T = (int) (OldLocation);
918 F = OldLocation - (float) T;
920 for (l = 0; l<lMax; l++) {
921 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
922 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
925 /* Make sure filter is normalized */
927 for(l=0; l<lMax; l++) {
931 t /= (float)LanczosWidthFactor;
933 for(l=0; l<lMax; l++) {
940 for (i=0; i<iEnd; i++) {
941 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
942 for (l=0; l<lMax; l++) {
945 mx = (mx < 0) ? 0 : mx;
946 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
948 i_gpix(im, Mx, i, &val1);
949 i_gpix(im, mx, i, &val2);
951 for (k=0; k<im->channels; k++) {
952 PictureValue[k] += l1[l] * val1.channel[k];
953 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
956 for(k=0;k<im->channels;k++) {
957 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
958 val.channel[k]=minmax(0,255,psave);
960 i_ppix(new_img, j, i, &val);
965 for (i=0; i<iEnd; i++) {
966 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
967 for (l=0; l < lMax; l++) {
970 mx = (mx < 0) ? 0 : mx;
971 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
973 i_gpix(im, i, Mx, &val1);
974 i_gpix(im, i, mx, &val2);
975 for (k=0; k<im->channels; k++) {
976 PictureValue[k] += l1[l] * val1.channel[k];
977 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
980 for (k=0; k<im->channels; k++) {
981 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
982 val.channel[k] = minmax(0, 255, psave);
984 i_ppix(new_img, i, j, &val);
992 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
999 =item i_scale_nn(im, scx, scy)
1001 Scale by using nearest neighbor
1002 Both axes scaled at the same time since
1003 nothing is gained by doing it in two steps
1010 i_scale_nn(i_img *im, float scx, float scy) {
1012 int nxsize,nysize,nx,ny;
1016 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
1018 nxsize = (int) ((float) im->xsize * scx);
1021 scx = 1 / im->xsize;
1023 nysize = (int) ((float) im->ysize * scy);
1026 scy = 1 / im->ysize;
1029 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1031 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1032 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1033 i_ppix(new_img,nx,ny,&val);
1036 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1042 =item i_sametype(i_img *im, int xsize, int ysize)
1044 =category Image creation
1046 Returns an image of the same type (sample size, channels, paletted/direct).
1048 For paletted images the palette is copied from the source.
1053 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1054 if (src->type == i_direct_type) {
1055 if (src->bits == 8) {
1056 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1058 else if (src->bits == i_16_bits) {
1059 return i_img_16_new(xsize, ysize, src->channels);
1061 else if (src->bits == i_double_bits) {
1062 return i_img_double_new(xsize, ysize, src->channels);
1065 i_push_error(0, "Unknown image bits");
1073 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1074 for (i = 0; i < i_colorcount(src); ++i) {
1075 i_getcolors(src, i, &col, 1);
1076 i_addcolors(targ, &col, 1);
1084 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1086 =category Image creation
1088 Returns an image of the same type (sample size).
1090 For paletted images the equivalent direct type is returned.
1095 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1096 if (src->bits == 8) {
1097 return i_img_empty_ch(NULL, xsize, ysize, channels);
1099 else if (src->bits == i_16_bits) {
1100 return i_img_16_new(xsize, ysize, channels);
1102 else if (src->bits == i_double_bits) {
1103 return i_img_double_new(xsize, ysize, channels);
1106 i_push_error(0, "Unknown image bits");
1112 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1114 Spatially transforms I<im> returning a new image.
1116 opx for a length of opxl and opy for a length of opy are arrays of
1117 operators that modify the x and y positions to retreive the pixel data from.
1119 parm and parmlen define extra parameters that the operators may use.
1121 Note that this function is largely superseded by the more flexible
1122 L<transform.c/i_transform2>.
1124 Returns the new image.
1126 The operators for this function are defined in L<stackmach.c>.
1131 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1133 int nxsize,nysize,nx,ny;
1137 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));
1140 nysize = im->ysize ;
1142 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1143 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1144 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1145 /* parm[parmlen-2]=(double)nx;
1146 parm[parmlen-1]=(double)ny; */
1151 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1152 rx=i_op_run(opx,opxl,parm,parmlen);
1153 ry=i_op_run(opy,opyl,parm,parmlen);
1154 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1155 i_gpix(im,rx,ry,&val);
1156 i_ppix(new_img,nx,ny,&val);
1159 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1164 =item i_img_diff(im1, im2)
1166 Calculates the sum of the squares of the differences between
1167 correspoding channels in two images.
1169 If the images are not the same size then only the common area is
1170 compared, hence even if images are different sizes this function
1176 i_img_diff(i_img *im1,i_img *im2) {
1177 int x,y,ch,xb,yb,chb;
1181 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1183 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1184 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1185 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1187 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1190 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1191 i_gpix(im1,x,y,&val1);
1192 i_gpix(im2,x,y,&val2);
1194 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1196 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1200 /* just a tiny demo of haar wavelets */
1208 i_img *new_img,*new_img2;
1209 i_color val1,val2,dval1,dval2;
1217 /* horizontal pass */
1219 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1220 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1223 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1224 i_gpix(im,x*2,y,&val1);
1225 i_gpix(im,x*2+1,y,&val2);
1226 for(ch=0;ch<im->channels;ch++) {
1227 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1228 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1230 i_ppix(new_img,x,y,&dval1);
1231 i_ppix(new_img,x+fx,y,&dval2);
1234 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1235 i_gpix(new_img,x,y*2,&val1);
1236 i_gpix(new_img,x,y*2+1,&val2);
1237 for(ch=0;ch<im->channels;ch++) {
1238 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1239 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1241 i_ppix(new_img2,x,y,&dval1);
1242 i_ppix(new_img2,x,y+fy,&dval2);
1245 i_img_destroy(new_img);
1250 =item i_count_colors(im, maxc)
1252 returns number of colors or -1
1253 to indicate that it was more than max colors
1257 /* This function has been changed and is now faster. It's using
1258 * i_gsamp instead of i_gpix */
1260 i_count_colors(i_img *im,int maxc) {
1267 int xsize = im->xsize;
1268 int ysize = im->ysize;
1269 int samp_cnt = 3 * xsize;
1271 if (im->channels >= 3) {
1275 channels[0] = channels[1] = channels[2] = 0;
1276 samp_chans = channels;
1281 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1284 for(y = 0; y < ysize; ) {
1285 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1286 for(x = 0; x < samp_cnt; ) {
1287 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1289 if (colorcnt > maxc) {
1300 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1301 * (adapted from the Numerical Recipes)
1303 /* Needed by get_anonymous_color_histo */
1305 hpsort(unsigned int n, unsigned *ra) {
1330 if (j < ir && ra[j] < ra[j+1]) j++;
1342 /* This function constructs an ordered list which represents how much the
1343 * different colors are used. So for instance (100, 100, 500) means that one
1344 * color is used for 500 pixels, another for 100 pixels and another for 100
1345 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1346 * the maxc ;-) and you might want to change the name... */
1347 /* Uses octt_histo */
1349 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1353 unsigned int *col_usage_it;
1358 int xsize = im->xsize;
1359 int ysize = im->ysize;
1360 int samp_cnt = 3 * xsize;
1363 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1365 if (im->channels >= 3) {
1369 channels[0] = channels[1] = channels[2] = 0;
1370 samp_chans = channels;
1374 for(y = 0; y < ysize; ) {
1375 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1376 for(x = 0; x < samp_cnt; ) {
1377 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1379 if (colorcnt > maxc) {
1386 /* Now that we know the number of colours... */
1387 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1388 octt_histo(ct, &col_usage_it);
1389 hpsort(colorcnt, *col_usage);
1397 =head2 8-bit per sample image internal functions
1399 These are the functions installed in an 8-bit per sample image.
1403 =item i_ppix_d(im, x, y, col)
1407 This is the function kept in the i_f_ppix member of an i_img object.
1408 It does a normal store of a pixel into the image with range checking.
1410 Returns 0 if the pixel could be set, -1 otherwise.
1416 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1419 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1420 for(ch=0;ch<im->channels;ch++)
1421 if (im->ch_mask&(1<<ch))
1422 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1425 return -1; /* error was clipped */
1429 =item i_gpix_d(im, x, y, &col)
1433 This is the function kept in the i_f_gpix member of an i_img object.
1434 It does normal retrieval of a pixel from the image with range checking.
1436 Returns 0 if the pixel could be set, -1 otherwise.
1442 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1444 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1445 for(ch=0;ch<im->channels;ch++)
1446 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1449 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1450 return -1; /* error was cliped */
1454 =item i_glin_d(im, l, r, y, vals)
1456 Reads a line of data from the image, storing the pixels at vals.
1458 The line runs from (l,y) inclusive to (r,y) non-inclusive
1460 vals should point at space for (r-l) pixels.
1462 l should never be less than zero (to avoid confusion about where to
1463 put the pixels in vals).
1465 Returns the number of pixels copied (eg. if r, l or y is out of range)
1471 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1473 unsigned char *data;
1474 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1477 data = im->idata + (l+y*im->xsize) * im->channels;
1479 for (i = 0; i < count; ++i) {
1480 for (ch = 0; ch < im->channels; ++ch)
1481 vals[i].channel[ch] = *data++;
1491 =item i_plin_d(im, l, r, y, vals)
1493 Writes a line of data into the image, using the pixels at vals.
1495 The line runs from (l,y) inclusive to (r,y) non-inclusive
1497 vals should point at (r-l) pixels.
1499 l should never be less than zero (to avoid confusion about where to
1500 get the pixels in vals).
1502 Returns the number of pixels copied (eg. if r, l or y is out of range)
1508 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1510 unsigned char *data;
1511 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1514 data = im->idata + (l+y*im->xsize) * im->channels;
1516 for (i = 0; i < count; ++i) {
1517 for (ch = 0; ch < im->channels; ++ch) {
1518 if (im->ch_mask & (1 << ch))
1519 *data = vals[i].channel[ch];
1531 =item i_ppixf_d(im, x, y, val)
1537 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1540 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1541 for(ch=0;ch<im->channels;ch++)
1542 if (im->ch_mask&(1<<ch)) {
1543 im->idata[(x+y*im->xsize)*im->channels+ch] =
1544 SampleFTo8(val->channel[ch]);
1548 return -1; /* error was clipped */
1552 =item i_gpixf_d(im, x, y, val)
1558 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1560 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1561 for(ch=0;ch<im->channels;ch++) {
1563 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1567 return -1; /* error was cliped */
1571 =item i_glinf_d(im, l, r, y, vals)
1573 Reads a line of data from the image, storing the pixels at vals.
1575 The line runs from (l,y) inclusive to (r,y) non-inclusive
1577 vals should point at space for (r-l) pixels.
1579 l should never be less than zero (to avoid confusion about where to
1580 put the pixels in vals).
1582 Returns the number of pixels copied (eg. if r, l or y is out of range)
1588 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1590 unsigned char *data;
1591 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1594 data = im->idata + (l+y*im->xsize) * im->channels;
1596 for (i = 0; i < count; ++i) {
1597 for (ch = 0; ch < im->channels; ++ch)
1598 vals[i].channel[ch] = Sample8ToF(*data++);
1608 =item i_plinf_d(im, l, r, y, vals)
1610 Writes a line of data into the image, using the pixels at vals.
1612 The line runs from (l,y) inclusive to (r,y) non-inclusive
1614 vals should point at (r-l) pixels.
1616 l should never be less than zero (to avoid confusion about where to
1617 get the pixels in vals).
1619 Returns the number of pixels copied (eg. if r, l or y is out of range)
1625 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1627 unsigned char *data;
1628 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1631 data = im->idata + (l+y*im->xsize) * im->channels;
1633 for (i = 0; i < count; ++i) {
1634 for (ch = 0; ch < im->channels; ++ch) {
1635 if (im->ch_mask & (1 << ch))
1636 *data = SampleFTo8(vals[i].channel[ch]);
1648 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1650 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1651 for the channels specified by chans, an array of int with chan_count
1654 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1660 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1661 const int *chans, int chan_count) {
1662 int ch, count, i, w;
1663 unsigned char *data;
1665 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1668 data = im->idata + (l+y*im->xsize) * im->channels;
1673 /* make sure we have good channel numbers */
1674 for (ch = 0; ch < chan_count; ++ch) {
1675 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1676 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1680 for (i = 0; i < w; ++i) {
1681 for (ch = 0; ch < chan_count; ++ch) {
1682 *samps++ = data[chans[ch]];
1685 data += im->channels;
1689 for (i = 0; i < w; ++i) {
1690 for (ch = 0; ch < chan_count; ++ch) {
1691 *samps++ = data[ch];
1694 data += im->channels;
1706 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1708 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1709 for the channels specified by chan_mask, where bit 0 is the first
1712 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1718 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1719 const int *chans, int chan_count) {
1720 int ch, count, i, w;
1721 unsigned char *data;
1722 for (ch = 0; ch < chan_count; ++ch) {
1723 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1724 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1727 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1730 data = im->idata + (l+y*im->xsize) * im->channels;
1735 /* make sure we have good channel numbers */
1736 for (ch = 0; ch < chan_count; ++ch) {
1737 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1738 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1742 for (i = 0; i < w; ++i) {
1743 for (ch = 0; ch < chan_count; ++ch) {
1744 *samps++ = Sample8ToF(data[chans[ch]]);
1747 data += im->channels;
1751 for (i = 0; i < w; ++i) {
1752 for (ch = 0; ch < chan_count; ++ch) {
1753 *samps++ = Sample8ToF(data[ch]);
1756 data += im->channels;
1769 =head2 Image method wrappers
1771 These functions provide i_fsample_t functions in terms of their
1772 i_sample_t versions.
1776 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1781 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1785 for (ch = 0; ch < im->channels; ++ch)
1786 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1788 return i_ppix(im, x, y, &temp);
1792 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1796 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1800 if (i_gpix(im, x, y, &temp)) {
1801 for (ch = 0; ch < im->channels; ++ch)
1802 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1810 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1814 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1817 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1823 work = mymalloc(sizeof(i_color) * (r-l));
1824 for (i = 0; i < r-l; ++i) {
1825 for (ch = 0; ch < im->channels; ++ch)
1826 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1828 ret = i_plin(im, l, r, y, work);
1843 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1847 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1850 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1856 work = mymalloc(sizeof(i_color) * (r-l));
1857 ret = i_plin(im, l, r, y, work);
1858 for (i = 0; i < r-l; ++i) {
1859 for (ch = 0; ch < im->channels; ++ch)
1860 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1876 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1880 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1881 int const *chans, int chan_count) {
1884 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1890 work = mymalloc(sizeof(i_sample_t) * (r-l));
1891 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1892 for (i = 0; i < ret; ++i) {
1893 samp[i] = Sample8ToF(work[i]);
1911 =head2 Palette wrapper functions
1913 Used for virtual images, these forward palette calls to a wrapped image,
1914 assuming the wrapped image is the first pointer in the structure that
1915 im->ext_data points at.
1919 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1923 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1924 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1928 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1932 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1933 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1937 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1941 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1942 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1946 =item i_colorcount_forward(i_img *im)
1950 int i_colorcount_forward(i_img *im) {
1951 return i_colorcount(*(i_img **)im->ext_data);
1955 =item i_maxcolors_forward(i_img *im)
1959 int i_maxcolors_forward(i_img *im) {
1960 return i_maxcolors(*(i_img **)im->ext_data);
1964 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1968 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1969 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1975 =head2 Stream reading and writing wrapper functions
1979 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1981 Performs general read buffering for file readers that permit reading
1982 to be done through a callback.
1984 The final callback gets two parameters, a I<need> value, and a I<want>
1985 value, where I<need> is the amount of data that the file library needs
1986 to read, and I<want> is the amount of space available in the buffer
1987 maintained by these functions.
1989 This means if you need to read from a stream that you don't know the
1990 length of, you can return I<need> bytes, taking the performance hit of
1991 possibly expensive callbacks (eg. back to perl code), or if you are
1992 reading from a stream where it doesn't matter if some data is lost, or
1993 if the total length of the stream is known, you can return I<want>
2000 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2003 if (length < gci->length - gci->cpos) {
2005 memcpy(buf, gci->buffer+gci->cpos, length);
2006 gci->cpos += length;
2011 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2012 total += gci->length - gci->cpos;
2013 length -= gci->length - gci->cpos;
2014 buf += gci->length - gci->cpos;
2015 if (length < (int)sizeof(gci->buffer)) {
2019 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
2020 sizeof(gci->buffer))) > 0) {
2022 gci->length = did_read;
2024 copy_size = i_min(length, gci->length);
2025 memcpy(buf, gci->buffer, copy_size);
2026 gci->cpos += copy_size;
2029 length -= copy_size;
2033 /* just read the rest - too big for our buffer*/
2035 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2045 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2047 For use by callback file readers to initialize the reader buffer.
2049 Allocates, initializes and returns the reader buffer.
2051 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2056 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2057 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2059 self->userdata = userdata;
2067 =item i_free_gen_read_data(i_gen_read_data *)
2073 void i_free_gen_read_data(i_gen_read_data *self) {
2078 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2080 Performs write buffering for a callback based file writer.
2082 Failures are considered fatal, if a write fails then data will be
2089 i_gen_write_data *self,
2093 if (self->filledto && self->filledto+size > self->maxlength) {
2094 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2102 if (self->filledto+size <= self->maxlength) {
2104 memcpy(self->buffer+self->filledto, data, size);
2105 self->filledto += size;
2108 /* doesn't fit - hand it off */
2109 return self->cb(self->userdata, data, size);
2113 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2115 Allocates and initializes the data structure used by i_gen_writer.
2117 This should be released with L<image.c/i_free_gen_write_data>
2121 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2122 char *userdata, int max_length)
2124 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2126 self->userdata = userdata;
2127 self->maxlength = i_min(max_length, sizeof(self->buffer));
2128 if (self->maxlength < 0)
2129 self->maxlength = sizeof(self->buffer);
2136 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2138 Cleans up the write buffer.
2140 Will flush any left-over data if I<flush> is non-zero.
2142 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2144 Return zero only if flush is non-zero and info->cb() returns zero.
2150 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2152 int result = !flush ||
2153 info->filledto == 0 ||
2154 info->cb(info->userdata, info->buffer, info->filledto);
2160 struct magic_entry {
2161 unsigned char *magic;
2164 unsigned char *mask;
2168 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2169 if (length < magic->magic_size)
2173 unsigned char *bufp = buffer,
2174 *maskp = magic->mask,
2175 *magicp = magic->magic;
2177 for (i = 0; i < magic->magic_size; ++i) {
2178 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2181 if ((*bufp++ & mask) != (*magicp++ & mask))
2188 return !memcmp(magic->magic, buffer, magic->magic_size);
2193 =item i_test_format_probe(io_glue *data, int length)
2195 Check the beginning of the supplied file for a 'magic number'
2200 #define FORMAT_ENTRY(magic, type) \
2201 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2202 #define FORMAT_ENTRY2(magic, type, mask) \
2203 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2206 i_test_format_probe(io_glue *data, int length) {
2207 static const struct magic_entry formats[] = {
2208 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2209 FORMAT_ENTRY("GIF87a", "gif"),
2210 FORMAT_ENTRY("GIF89a", "gif"),
2211 FORMAT_ENTRY("MM\0*", "tiff"),
2212 FORMAT_ENTRY("II*\0", "tiff"),
2213 FORMAT_ENTRY("BM", "bmp"),
2214 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2215 FORMAT_ENTRY("P1", "pnm"),
2216 FORMAT_ENTRY("P2", "pnm"),
2217 FORMAT_ENTRY("P3", "pnm"),
2218 FORMAT_ENTRY("P4", "pnm"),
2219 FORMAT_ENTRY("P5", "pnm"),
2220 FORMAT_ENTRY("P6", "pnm"),
2221 FORMAT_ENTRY("/* XPM", "xpm"),
2222 FORMAT_ENTRY("\x8aMNG", "mng"),
2223 FORMAT_ENTRY("\x8aJNG", "jng"),
2224 /* SGI RGB - with various possible parameters to avoid false positives
2226 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2228 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2229 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2230 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2231 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2233 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
2235 /* different versions of PCX format
2236 http://www.fileformat.info/format/pcx/
2238 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2239 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2240 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2241 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2242 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2244 /* FITS - http://fits.gsfc.nasa.gov/ */
2245 FORMAT_ENTRY("SIMPLE =", "fits"),
2247 /* PSD - Photoshop */
2248 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2250 /* EPS - Encapsulated Postscript */
2251 /* only reading 18 chars, so we don't include the F in EPSF */
2252 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2255 FORMAT_ENTRY("\x52\xCC", "utah"),
2257 /* GZIP compressed, only matching deflate for now */
2258 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2260 /* bzip2 compressed */
2261 FORMAT_ENTRY("BZh", "bzip2"),
2263 static const struct magic_entry more_formats[] = {
2264 /* these were originally both listed as ico, but cur files can
2265 include hotspot information */
2266 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2267 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2268 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
2269 "xwd", " xxxx"), /* X Windows Dump */
2273 unsigned char head[18];
2276 io_glue_commit_types(data);
2277 rc = data->readcb(data, head, 18);
2278 if (rc == -1) return NULL;
2279 data->seekcb(data, -rc, SEEK_CUR);
2281 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2282 struct magic_entry const *entry = formats + i;
2284 if (test_magic(head, rc, entry))
2289 tga_header_verify(head))
2292 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
2293 struct magic_entry const *entry = more_formats + i;
2295 if (test_magic(head, rc, entry))
2303 =item i_img_is_monochrome(img, &zero_is_white)
2305 Tests an image to check it meets our monochrome tests.
2307 The idea is that a file writer can use this to test where it should
2308 write the image in whatever bi-level format it uses, eg. pbm for pnm.
2310 For performance of encoders we require monochrome images:
2320 have a palette of two colors, containing only (0,0,0) and
2321 (255,255,255) in either order.
2325 zero_is_white is set to non-zero iff the first palette entry is white.
2331 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2332 if (im->type == i_palette_type
2333 && i_colorcount(im) == 2) {
2335 i_getcolors(im, 0, colors, 2);
2336 if (im->channels == 3) {
2337 if (colors[0].rgb.r == 255 &&
2338 colors[0].rgb.g == 255 &&
2339 colors[0].rgb.b == 255 &&
2340 colors[1].rgb.r == 0 &&
2341 colors[1].rgb.g == 0 &&
2342 colors[1].rgb.b == 0) {
2346 else if (colors[0].rgb.r == 0 &&
2347 colors[0].rgb.g == 0 &&
2348 colors[0].rgb.b == 0 &&
2349 colors[1].rgb.r == 255 &&
2350 colors[1].rgb.g == 255 &&
2351 colors[1].rgb.b == 255) {
2356 else if (im->channels == 1) {
2357 if (colors[0].channel[0] == 255 &&
2358 colors[1].channel[1] == 0) {
2362 else if (colors[0].channel[0] == 0 &&
2363 colors[0].channel[0] == 255) {
2379 Arnar M. Hrafnkelsson <addi@umich.edu>
2381 Tony Cook <tony@develop-help.com>