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 Set the image channel mask for I<im> to I<ch_mask>.
489 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
493 =item i_img_getmask(im)
495 Get the image channel mask for I<im>.
500 i_img_getmask(i_img *im) { return im->ch_mask; }
503 =item i_img_getchannels(im)
505 Get the number of channels in I<im>.
510 i_img_getchannels(i_img *im) { return im->channels; }
515 =item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
519 (x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
520 (tx,ty) specifies the upper left corner for the target image.
521 pass NULL in trans for non transparent i_colors.
527 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) {
529 int x,y,t,ttx,tty,tt,ch;
531 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",
532 im, src, x1, y1, x2, y2, tx, ty, trans));
534 if (x2<x1) { t=x1; x1=x2; x2=t; }
535 if (y2<y1) { t=y1; y1=y2; y2=t; }
547 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
548 if (tt) i_ppix(im,ttx,tty,&pv);
549 } else i_ppix(im,ttx,tty,&pv);
557 =item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
561 Copies image data from the area (x1,y1)-[x2,y2] in the source image to
562 a rectangle the same size with it's top-left corner at (tx,ty) in the
565 If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
571 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
572 int x, y, t, ttx, tty;
574 if (x2<x1) { t=x1; x1=x2; x2=t; }
575 if (y2<y1) { t=y1; y1=y2; y2=t; }
577 /* adjust everything equally */
587 if (x1 >= src->xsize || y1 >= src->ysize)
588 return; /* nothing to do */
593 if (x1 == x2 || y1 == y2)
594 return; /* nothing to do */
596 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
597 im, src, x1, y1, x2, y2, tx, ty));
599 if (im->bits == i_8_bits) {
600 i_color *row = mymalloc(sizeof(i_color) * (x2-x1));
602 for(y=y1; y<y2; y++) {
604 i_glin(src, x1, x2, y, row);
605 i_plin(im, tx, tx+x2-x1, tty, row);
613 for(y=y1; y<y2; y++) {
615 for(x=x1; x<x2; x++) {
616 i_gpixf(src, x, y, &pv);
617 i_ppixf(im, ttx, tty, &pv);
630 Creates a new image that is a copy of src.
632 Tags are not copied, only the image data.
642 i_img *im = i_sametype(src, src->xsize, src->ysize);
644 mm_log((1,"i_copy(src %p)\n", src));
651 if (src->type == i_direct_type) {
652 if (src->bits == i_8_bits) {
654 pv = mymalloc(sizeof(i_color) * x1);
656 for (y = 0; y < y1; ++y) {
657 i_glin(src, 0, x1, y, pv);
658 i_plin(im, 0, x1, y, pv);
665 pv = mymalloc(sizeof(i_fcolor) * x1);
666 for (y = 0; y < y1; ++y) {
667 i_glinf(src, 0, x1, y, pv);
668 i_plinf(im, 0, x1, y, pv);
680 i_img_pal_new_low(im, x1, y1, src->channels, i_maxcolors(src));
681 /* copy across the palette */
682 count = i_colorcount(src);
683 for (index = 0; index < count; ++index) {
684 i_getcolors(src, index, &temp, 1);
685 i_addcolors(im, &temp, 1);
688 vals = mymalloc(sizeof(i_palidx) * x1);
689 for (y = 0; y < y1; ++y) {
690 i_gpal(src, 0, x1, y, vals);
691 i_ppal(im, 0, x1, y, vals);
701 =item i_flipxy(im, axis)
703 Flips the image inplace around the axis specified.
704 Returns 0 if parameters are invalid.
707 axis - 0 = x, 1 = y, 2 = both
713 i_flipxy(i_img *im, int direction) {
714 int x, x2, y, y2, xm, ym;
718 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
723 case XAXIS: /* Horizontal flip */
726 for(y=0; y<ym; y++) {
728 for(x=0; x<xm; x++) {
730 i_gpix(im, x, y, &val1);
731 i_gpix(im, x2, y, &val2);
732 i_ppix(im, x, y, &val2);
733 i_ppix(im, x2, y, &val1);
738 case YAXIS: /* Vertical flip */
742 for(y=0; y<ym; y++) {
743 for(x=0; x<xm; x++) {
745 i_gpix(im, x, y, &val1);
746 i_gpix(im, x, y2, &val2);
747 i_ppix(im, x, y, &val2);
748 i_ppix(im, x, y2, &val1);
753 case XYAXIS: /* Horizontal and Vertical flip */
757 for(y=0; y<ym; y++) {
759 for(x=0; x<xm; x++) {
761 i_gpix(im, x, y, &val1);
762 i_gpix(im, x2, y2, &val2);
763 i_ppix(im, x, y, &val2);
764 i_ppix(im, x2, y2, &val1);
766 i_gpix(im, x2, y, &val1);
767 i_gpix(im, x, y2, &val2);
768 i_ppix(im, x2, y, &val2);
769 i_ppix(im, x, y2, &val1);
774 if (xm*2 != xs) { /* odd number of column */
775 mm_log((1, "i_flipxy: odd number of columns\n"));
778 for(y=0; y<ym; y++) {
780 i_gpix(im, x, y, &val1);
781 i_gpix(im, x, y2, &val2);
782 i_ppix(im, x, y, &val2);
783 i_ppix(im, x, y2, &val1);
787 if (ym*2 != ys) { /* odd number of rows */
788 mm_log((1, "i_flipxy: odd number of rows\n"));
791 for(x=0; x<xm; x++) {
793 i_gpix(im, x, y, &val1);
794 i_gpix(im, x2, y, &val2);
795 i_ppix(im, x, y, &val2);
796 i_ppix(im, x2, y, &val1);
802 mm_log((1, "i_flipxy: direction is invalid\n" ));
820 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
821 else if (x == 0.0) return (1.0);
822 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
827 =item i_scaleaxis(im, value, axis)
829 Returns a new image object which is I<im> scaled by I<value> along
830 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
836 i_scaleaxis(i_img *im, float Value, int Axis) {
837 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
838 int LanczosWidthFactor;
839 float *l0, *l1, OldLocation;
842 float F, PictureValue[MAXCHANNELS];
844 i_color val,val1,val2;
847 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
851 hsize = (int)(0.5 + im->xsize * Value);
854 Value = 1.0 / im->xsize;
862 vsize = (int)(0.5 + im->ysize * Value);
866 Value = 1.0 / im->ysize;
873 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
875 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
876 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
877 lMax = LanczosWidthFactor << 1;
879 l0 = mymalloc(lMax * sizeof(float));
880 l1 = mymalloc(lMax * sizeof(float));
882 for (j=0; j<jEnd; j++) {
883 OldLocation = ((float) j) / Value;
884 T = (int) (OldLocation);
885 F = OldLocation - (float) T;
887 for (l = 0; l<lMax; l++) {
888 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
889 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
892 /* Make sure filter is normalized */
894 for(l=0; l<lMax; l++) {
898 t /= (float)LanczosWidthFactor;
900 for(l=0; l<lMax; l++) {
907 for (i=0; i<iEnd; i++) {
908 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
909 for (l=0; l<lMax; l++) {
912 mx = (mx < 0) ? 0 : mx;
913 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
915 i_gpix(im, Mx, i, &val1);
916 i_gpix(im, mx, i, &val2);
918 for (k=0; k<im->channels; k++) {
919 PictureValue[k] += l1[l] * val1.channel[k];
920 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
923 for(k=0;k<im->channels;k++) {
924 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
925 val.channel[k]=minmax(0,255,psave);
927 i_ppix(new_img, j, i, &val);
932 for (i=0; i<iEnd; i++) {
933 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
934 for (l=0; l < lMax; l++) {
937 mx = (mx < 0) ? 0 : mx;
938 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
940 i_gpix(im, i, Mx, &val1);
941 i_gpix(im, i, mx, &val2);
942 for (k=0; k<im->channels; k++) {
943 PictureValue[k] += l1[l] * val1.channel[k];
944 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
947 for (k=0; k<im->channels; k++) {
948 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
949 val.channel[k] = minmax(0, 255, psave);
951 i_ppix(new_img, i, j, &val);
959 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
966 =item i_scale_nn(im, scx, scy)
968 Scale by using nearest neighbor
969 Both axes scaled at the same time since
970 nothing is gained by doing it in two steps
977 i_scale_nn(i_img *im, float scx, float scy) {
979 int nxsize,nysize,nx,ny;
983 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
985 nxsize = (int) ((float) im->xsize * scx);
990 nysize = (int) ((float) im->ysize * scy);
996 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
998 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
999 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1000 i_ppix(new_img,nx,ny,&val);
1003 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1009 =item i_sametype(i_img *im, int xsize, int ysize)
1011 =category Image creation
1013 Returns an image of the same type (sample size, channels, paletted/direct).
1015 For paletted images the palette is copied from the source.
1020 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1021 if (src->type == i_direct_type) {
1022 if (src->bits == 8) {
1023 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1025 else if (src->bits == i_16_bits) {
1026 return i_img_16_new(xsize, ysize, src->channels);
1028 else if (src->bits == i_double_bits) {
1029 return i_img_double_new(xsize, ysize, src->channels);
1032 i_push_error(0, "Unknown image bits");
1040 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1041 for (i = 0; i < i_colorcount(src); ++i) {
1042 i_getcolors(src, i, &col, 1);
1043 i_addcolors(targ, &col, 1);
1051 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1053 =category Image creation
1055 Returns an image of the same type (sample size).
1057 For paletted images the equivalent direct type is returned.
1062 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1063 if (src->bits == 8) {
1064 return i_img_empty_ch(NULL, xsize, ysize, channels);
1066 else if (src->bits == i_16_bits) {
1067 return i_img_16_new(xsize, ysize, channels);
1069 else if (src->bits == i_double_bits) {
1070 return i_img_double_new(xsize, ysize, channels);
1073 i_push_error(0, "Unknown image bits");
1079 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1081 Spatially transforms I<im> returning a new image.
1083 opx for a length of opxl and opy for a length of opy are arrays of
1084 operators that modify the x and y positions to retreive the pixel data from.
1086 parm and parmlen define extra parameters that the operators may use.
1088 Note that this function is largely superseded by the more flexible
1089 L<transform.c/i_transform2>.
1091 Returns the new image.
1093 The operators for this function are defined in L<stackmach.c>.
1098 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1100 int nxsize,nysize,nx,ny;
1104 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));
1107 nysize = im->ysize ;
1109 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1110 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1111 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1112 /* parm[parmlen-2]=(double)nx;
1113 parm[parmlen-1]=(double)ny; */
1118 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1119 rx=i_op_run(opx,opxl,parm,parmlen);
1120 ry=i_op_run(opy,opyl,parm,parmlen);
1121 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1122 i_gpix(im,rx,ry,&val);
1123 i_ppix(new_img,nx,ny,&val);
1126 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1131 =item i_img_diff(im1, im2)
1133 Calculates the sum of the squares of the differences between
1134 correspoding channels in two images.
1136 If the images are not the same size then only the common area is
1137 compared, hence even if images are different sizes this function
1143 i_img_diff(i_img *im1,i_img *im2) {
1144 int x,y,ch,xb,yb,chb;
1148 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1150 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1151 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1152 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1154 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1157 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1158 i_gpix(im1,x,y,&val1);
1159 i_gpix(im2,x,y,&val2);
1161 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1163 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1167 /* just a tiny demo of haar wavelets */
1175 i_img *new_img,*new_img2;
1176 i_color val1,val2,dval1,dval2;
1184 /* horizontal pass */
1186 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1187 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1190 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1191 i_gpix(im,x*2,y,&val1);
1192 i_gpix(im,x*2+1,y,&val2);
1193 for(ch=0;ch<im->channels;ch++) {
1194 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1195 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1197 i_ppix(new_img,x,y,&dval1);
1198 i_ppix(new_img,x+fx,y,&dval2);
1201 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1202 i_gpix(new_img,x,y*2,&val1);
1203 i_gpix(new_img,x,y*2+1,&val2);
1204 for(ch=0;ch<im->channels;ch++) {
1205 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1206 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1208 i_ppix(new_img2,x,y,&dval1);
1209 i_ppix(new_img2,x,y+fy,&dval2);
1212 i_img_destroy(new_img);
1217 =item i_count_colors(im, maxc)
1219 returns number of colors or -1
1220 to indicate that it was more than max colors
1225 i_count_colors(i_img *im,int maxc) {
1232 mm_log((1,"i_count_colors(im 0x%08X,maxc %d)\n"));
1239 for(y=0;y<ysize;y++) for(x=0;x<xsize;x++) {
1240 i_gpix(im,x,y,&val);
1241 colorcnt+=octt_add(ct,val.rgb.r,val.rgb.g,val.rgb.b);
1242 if (colorcnt > maxc) { octt_delete(ct); return -1; }
1251 =head2 8-bit per sample image internal functions
1253 These are the functions installed in an 8-bit per sample image.
1257 =item i_ppix_d(im, x, y, col)
1261 This is the function kept in the i_f_ppix member of an i_img object.
1262 It does a normal store of a pixel into the image with range checking.
1264 Returns 0 if the pixel could be set, -1 otherwise.
1270 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1273 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1274 for(ch=0;ch<im->channels;ch++)
1275 if (im->ch_mask&(1<<ch))
1276 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1279 return -1; /* error was clipped */
1283 =item i_gpix_d(im, x, y, &col)
1287 This is the function kept in the i_f_gpix member of an i_img object.
1288 It does normal retrieval of a pixel from the image with range checking.
1290 Returns 0 if the pixel could be set, -1 otherwise.
1296 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1298 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1299 for(ch=0;ch<im->channels;ch++)
1300 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1303 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1304 return -1; /* error was cliped */
1308 =item i_glin_d(im, l, r, y, vals)
1310 Reads a line of data from the image, storing the pixels at vals.
1312 The line runs from (l,y) inclusive to (r,y) non-inclusive
1314 vals should point at space for (r-l) pixels.
1316 l should never be less than zero (to avoid confusion about where to
1317 put the pixels in vals).
1319 Returns the number of pixels copied (eg. if r, l or y is out of range)
1325 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1327 unsigned char *data;
1328 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1331 data = im->idata + (l+y*im->xsize) * im->channels;
1333 for (i = 0; i < count; ++i) {
1334 for (ch = 0; ch < im->channels; ++ch)
1335 vals[i].channel[ch] = *data++;
1345 =item i_plin_d(im, l, r, y, vals)
1347 Writes a line of data into the image, using the pixels at vals.
1349 The line runs from (l,y) inclusive to (r,y) non-inclusive
1351 vals should point at (r-l) pixels.
1353 l should never be less than zero (to avoid confusion about where to
1354 get the pixels in vals).
1356 Returns the number of pixels copied (eg. if r, l or y is out of range)
1362 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1364 unsigned char *data;
1365 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1368 data = im->idata + (l+y*im->xsize) * im->channels;
1370 for (i = 0; i < count; ++i) {
1371 for (ch = 0; ch < im->channels; ++ch) {
1372 if (im->ch_mask & (1 << ch))
1373 *data = vals[i].channel[ch];
1385 =item i_ppixf_d(im, x, y, val)
1391 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1394 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1395 for(ch=0;ch<im->channels;ch++)
1396 if (im->ch_mask&(1<<ch)) {
1397 im->idata[(x+y*im->xsize)*im->channels+ch] =
1398 SampleFTo8(val->channel[ch]);
1402 return -1; /* error was clipped */
1406 =item i_gpixf_d(im, x, y, val)
1412 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1414 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1415 for(ch=0;ch<im->channels;ch++) {
1417 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1421 return -1; /* error was cliped */
1425 =item i_glinf_d(im, l, r, y, vals)
1427 Reads a line of data from the image, storing the pixels at vals.
1429 The line runs from (l,y) inclusive to (r,y) non-inclusive
1431 vals should point at space for (r-l) pixels.
1433 l should never be less than zero (to avoid confusion about where to
1434 put the pixels in vals).
1436 Returns the number of pixels copied (eg. if r, l or y is out of range)
1442 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1444 unsigned char *data;
1445 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1448 data = im->idata + (l+y*im->xsize) * im->channels;
1450 for (i = 0; i < count; ++i) {
1451 for (ch = 0; ch < im->channels; ++ch)
1452 vals[i].channel[ch] = Sample8ToF(*data++);
1462 =item i_plinf_d(im, l, r, y, vals)
1464 Writes a line of data into the image, using the pixels at vals.
1466 The line runs from (l,y) inclusive to (r,y) non-inclusive
1468 vals should point at (r-l) pixels.
1470 l should never be less than zero (to avoid confusion about where to
1471 get the pixels in vals).
1473 Returns the number of pixels copied (eg. if r, l or y is out of range)
1479 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1481 unsigned char *data;
1482 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1485 data = im->idata + (l+y*im->xsize) * im->channels;
1487 for (i = 0; i < count; ++i) {
1488 for (ch = 0; ch < im->channels; ++ch) {
1489 if (im->ch_mask & (1 << ch))
1490 *data = SampleFTo8(vals[i].channel[ch]);
1502 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1504 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1505 for the channels specified by chans, an array of int with chan_count
1508 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1514 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1515 const int *chans, int chan_count) {
1516 int ch, count, i, w;
1517 unsigned char *data;
1519 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1522 data = im->idata + (l+y*im->xsize) * im->channels;
1527 /* make sure we have good channel numbers */
1528 for (ch = 0; ch < chan_count; ++ch) {
1529 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1530 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1534 for (i = 0; i < w; ++i) {
1535 for (ch = 0; ch < chan_count; ++ch) {
1536 *samps++ = data[chans[ch]];
1539 data += im->channels;
1543 for (i = 0; i < w; ++i) {
1544 for (ch = 0; ch < chan_count; ++ch) {
1545 *samps++ = data[ch];
1548 data += im->channels;
1560 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1562 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1563 for the channels specified by chan_mask, where bit 0 is the first
1566 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1572 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1573 const int *chans, int chan_count) {
1574 int ch, count, i, w;
1575 unsigned char *data;
1576 for (ch = 0; ch < chan_count; ++ch) {
1577 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1578 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1581 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1584 data = im->idata + (l+y*im->xsize) * im->channels;
1589 /* make sure we have good channel numbers */
1590 for (ch = 0; ch < chan_count; ++ch) {
1591 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1592 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1596 for (i = 0; i < w; ++i) {
1597 for (ch = 0; ch < chan_count; ++ch) {
1598 *samps++ = Sample8ToF(data[chans[ch]]);
1601 data += im->channels;
1605 for (i = 0; i < w; ++i) {
1606 for (ch = 0; ch < chan_count; ++ch) {
1607 *samps++ = Sample8ToF(data[ch]);
1610 data += im->channels;
1623 =head2 Image method wrappers
1625 These functions provide i_fsample_t functions in terms of their
1626 i_sample_t versions.
1630 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1635 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1639 for (ch = 0; ch < im->channels; ++ch)
1640 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1642 return i_ppix(im, x, y, &temp);
1646 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1650 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1654 if (i_gpix(im, x, y, &temp)) {
1655 for (ch = 0; ch < im->channels; ++ch)
1656 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1664 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1668 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1671 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1677 work = mymalloc(sizeof(i_color) * (r-l));
1678 for (i = 0; i < r-l; ++i) {
1679 for (ch = 0; ch < im->channels; ++ch)
1680 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1682 ret = i_plin(im, l, r, y, work);
1697 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1701 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1704 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1710 work = mymalloc(sizeof(i_color) * (r-l));
1711 ret = i_plin(im, l, r, y, work);
1712 for (i = 0; i < r-l; ++i) {
1713 for (ch = 0; ch < im->channels; ++ch)
1714 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1730 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1734 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1735 int const *chans, int chan_count) {
1738 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1744 work = mymalloc(sizeof(i_sample_t) * (r-l));
1745 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1746 for (i = 0; i < ret; ++i) {
1747 samp[i] = Sample8ToF(work[i]);
1765 =head2 Palette wrapper functions
1767 Used for virtual images, these forward palette calls to a wrapped image,
1768 assuming the wrapped image is the first pointer in the structure that
1769 im->ext_data points at.
1773 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1777 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1778 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1782 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1786 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1787 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1791 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1795 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1796 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1800 =item i_colorcount_forward(i_img *im)
1804 int i_colorcount_forward(i_img *im) {
1805 return i_colorcount(*(i_img **)im->ext_data);
1809 =item i_maxcolors_forward(i_img *im)
1813 int i_maxcolors_forward(i_img *im) {
1814 return i_maxcolors(*(i_img **)im->ext_data);
1818 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1822 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1823 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1829 =head2 Stream reading and writing wrapper functions
1833 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1835 Performs general read buffering for file readers that permit reading
1836 to be done through a callback.
1838 The final callback gets two parameters, a I<need> value, and a I<want>
1839 value, where I<need> is the amount of data that the file library needs
1840 to read, and I<want> is the amount of space available in the buffer
1841 maintained by these functions.
1843 This means if you need to read from a stream that you don't know the
1844 length of, you can return I<need> bytes, taking the performance hit of
1845 possibly expensive callbacks (eg. back to perl code), or if you are
1846 reading from a stream where it doesn't matter if some data is lost, or
1847 if the total length of the stream is known, you can return I<want>
1854 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1857 if (length < gci->length - gci->cpos) {
1859 memcpy(buf, gci->buffer+gci->cpos, length);
1860 gci->cpos += length;
1865 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1866 total += gci->length - gci->cpos;
1867 length -= gci->length - gci->cpos;
1868 buf += gci->length - gci->cpos;
1869 if (length < (int)sizeof(gci->buffer)) {
1873 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
1874 sizeof(gci->buffer))) > 0) {
1876 gci->length = did_read;
1878 copy_size = i_min(length, gci->length);
1879 memcpy(buf, gci->buffer, copy_size);
1880 gci->cpos += copy_size;
1883 length -= copy_size;
1887 /* just read the rest - too big for our buffer*/
1889 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
1899 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
1901 For use by callback file readers to initialize the reader buffer.
1903 Allocates, initializes and returns the reader buffer.
1905 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
1910 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
1911 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
1913 self->userdata = userdata;
1921 =item i_free_gen_read_data(i_gen_read_data *)
1927 void i_free_gen_read_data(i_gen_read_data *self) {
1932 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
1934 Performs write buffering for a callback based file writer.
1936 Failures are considered fatal, if a write fails then data will be
1943 i_gen_write_data *self,
1947 if (self->filledto && self->filledto+size > self->maxlength) {
1948 if (self->cb(self->userdata, self->buffer, self->filledto)) {
1956 if (self->filledto+size <= self->maxlength) {
1958 memcpy(self->buffer+self->filledto, data, size);
1959 self->filledto += size;
1962 /* doesn't fit - hand it off */
1963 return self->cb(self->userdata, data, size);
1967 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
1969 Allocates and initializes the data structure used by i_gen_writer.
1971 This should be released with L<image.c/i_free_gen_write_data>
1975 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
1976 char *userdata, int max_length)
1978 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
1980 self->userdata = userdata;
1981 self->maxlength = i_min(max_length, sizeof(self->buffer));
1982 if (self->maxlength < 0)
1983 self->maxlength = sizeof(self->buffer);
1990 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
1992 Cleans up the write buffer.
1994 Will flush any left-over data if I<flush> is non-zero.
1996 Returns non-zero if flush is zero or if info->cb() returns non-zero.
1998 Return zero only if flush is non-zero and info->cb() returns zero.
2004 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2006 int result = !flush ||
2007 info->filledto == 0 ||
2008 info->cb(info->userdata, info->buffer, info->filledto);
2014 struct magic_entry {
2015 unsigned char *magic;
2018 unsigned char *mask;
2022 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2023 if (length < magic->magic_size)
2027 unsigned char *bufp = buffer,
2028 *maskp = magic->mask,
2029 *magicp = magic->magic;
2031 for (i = 0; i < magic->magic_size; ++i) {
2032 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2035 if ((*bufp++ & mask) != (*magicp++ & mask))
2042 return !memcmp(magic->magic, buffer, magic->magic_size);
2047 =item i_test_format_probe(io_glue *data, int length)
2049 Check the beginning of the supplied file for a 'magic number'
2054 #define FORMAT_ENTRY(magic, type) \
2055 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2056 #define FORMAT_ENTRY2(magic, type, mask) \
2057 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2060 i_test_format_probe(io_glue *data, int length) {
2061 static const struct magic_entry formats[] = {
2062 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2063 FORMAT_ENTRY("GIF87a", "gif"),
2064 FORMAT_ENTRY("GIF89a", "gif"),
2065 FORMAT_ENTRY("MM\0*", "tiff"),
2066 FORMAT_ENTRY("II*\0", "tiff"),
2067 FORMAT_ENTRY("BM", "bmp"),
2068 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2069 FORMAT_ENTRY("P1", "pnm"),
2070 FORMAT_ENTRY("P2", "pnm"),
2071 FORMAT_ENTRY("P3", "pnm"),
2072 FORMAT_ENTRY("P4", "pnm"),
2073 FORMAT_ENTRY("P5", "pnm"),
2074 FORMAT_ENTRY("P6", "pnm"),
2075 FORMAT_ENTRY("/* XPM", "xpm"),
2076 FORMAT_ENTRY("\x8aMNG", "mng"),
2077 FORMAT_ENTRY("\x8aJNG", "jng"),
2078 /* SGI RGB - with various possible parameters to avoid false positives
2080 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2082 FORMAT_ENTRY("\x01\xDA\x00\x01", "rgb"),
2083 FORMAT_ENTRY("\x01\xDA\x00\x02", "rgb"),
2084 FORMAT_ENTRY("\x01\xDA\x01\x01", "rgb"),
2085 FORMAT_ENTRY("\x01\xDA\x01\x02", "rgb"),
2087 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
2089 /* different versions of PCX format
2090 http://www.fileformat.info/format/pcx/
2092 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2093 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2094 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2095 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2096 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2098 /* FITS - http://fits.gsfc.nasa.gov/ */
2099 FORMAT_ENTRY("SIMPLE =", "fits"),
2101 /* PSD - Photoshop */
2102 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2104 /* EPS - Encapsulated Postscript */
2105 /* only reading 18 chars, so we don't include the F in EPSF */
2106 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2109 FORMAT_ENTRY("\x52\xCC", "utah"),
2111 /* GZIP compressed, only matching deflate for now */
2112 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2114 /* bzip2 compressed */
2115 FORMAT_ENTRY("BZh", "bzip2"),
2117 static const struct magic_entry more_formats[] = {
2118 /* these were originally both listed as ico, but cur files can
2119 include hotspot information */
2120 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2121 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2122 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
2123 "xwd", " xxxx"), /* X Windows Dump */
2127 unsigned char head[18];
2130 io_glue_commit_types(data);
2131 rc = data->readcb(data, head, 18);
2132 if (rc == -1) return NULL;
2133 data->seekcb(data, -rc, SEEK_CUR);
2135 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2136 struct magic_entry const *entry = formats + i;
2138 if (test_magic(head, rc, entry))
2143 tga_header_verify(head))
2146 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
2147 struct magic_entry const *entry = more_formats + i;
2149 if (test_magic(head, rc, entry))
2157 =item i_img_is_monochrome(img, &zero_is_white)
2159 Tests an image to check it meets our monochrome tests.
2161 The idea is that a file writer can use this to test where it should
2162 write the image in whatever bi-level format it uses, eg. pbm for pnm.
2164 For performance of encoders we require monochrome images:
2174 have a palette of two colors, containing only (0,0,0) and
2175 (255,255,255) in either order.
2179 zero_is_white is set to non-zero iff the first palette entry is white.
2185 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2186 if (im->type == i_palette_type
2187 && i_colorcount(im) == 2) {
2189 i_getcolors(im, 0, colors, 2);
2190 if (im->channels == 3) {
2191 if (colors[0].rgb.r == 255 &&
2192 colors[0].rgb.g == 255 &&
2193 colors[0].rgb.b == 255 &&
2194 colors[1].rgb.r == 0 &&
2195 colors[1].rgb.g == 0 &&
2196 colors[1].rgb.b == 0) {
2200 else if (colors[0].rgb.r == 0 &&
2201 colors[0].rgb.g == 0 &&
2202 colors[0].rgb.b == 0 &&
2203 colors[1].rgb.r == 255 &&
2204 colors[1].rgb.g == 255 &&
2205 colors[1].rgb.b == 255) {
2210 else if (im->channels == 1) {
2211 if (colors[0].channel[0] == 255 &&
2212 colors[1].channel[1] == 0) {
2216 else if (colors[0].channel[0] == 0 &&
2217 colors[0].channel[0] == 255) {
2233 Arnar M. Hrafnkelsson <addi@umich.edu>
2235 Tony Cook <tony@develop-help.com>