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);
55 =category Image Implementation
57 Allocates a new i_img structure.
59 When implementing a new image type perform the following steps in your
60 image object creation function:
66 allocate the image with i_img_alloc().
70 initialize any function pointers or other data as needed, you can
71 overwrite the whole block if you need to.
75 initialize Imager's internal data by calling i_img_init() on the image
85 return mymalloc(sizeof(i_img));
90 =category Image Implementation
92 Imager interal initialization of images.
94 Currently this does very little, in the future it may be used to
95 support threads, or color profiles.
101 i_img_init(i_img *img) {
106 =item ICL_new_internal(r, g, b, a)
108 Return a new color object with values passed to it.
110 r - red component (range: 0 - 255)
111 g - green component (range: 0 - 255)
112 b - blue component (range: 0 - 255)
113 a - alpha component (range: 0 - 255)
119 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
122 mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
124 if ( (cl=mymalloc(sizeof(i_color))) == NULL) i_fatal(2,"malloc() error\n");
129 mm_log((1,"(%p) <- ICL_new_internal\n",cl));
135 =item ICL_set_internal(cl, r, g, b, a)
137 Overwrite a color with new values.
139 cl - pointer to color object
140 r - red component (range: 0 - 255)
141 g - green component (range: 0 - 255)
142 b - blue component (range: 0 - 255)
143 a - alpha component (range: 0 - 255)
149 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
150 mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
152 if ( (cl=mymalloc(sizeof(i_color))) == NULL)
153 i_fatal(2,"malloc() error\n");
158 mm_log((1,"(%p) <- ICL_set_internal\n",cl));
164 =item ICL_add(dst, src, ch)
166 Add src to dst inplace - dst is modified.
168 dst - pointer to destination color object
169 src - pointer to color object that is added
170 ch - number of channels
176 ICL_add(i_color *dst,i_color *src,int ch) {
179 tmp=dst->channel[i]+src->channel[i];
180 dst->channel[i]= tmp>255 ? 255:tmp;
187 Dump color information to log - strictly for debugging.
189 cl - pointer to color object
195 ICL_info(i_color const *cl) {
196 mm_log((1,"i_color_info(cl* %p)\n",cl));
197 mm_log((1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
203 Destroy ancillary data for Color object.
205 cl - pointer to color object
211 ICL_DESTROY(i_color *cl) {
212 mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
217 =item i_fcolor_new(double r, double g, double b, double a)
221 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
224 mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
226 if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) i_fatal(2,"malloc() error\n");
231 mm_log((1,"(%p) <- i_fcolor_new\n",cl));
237 =item i_fcolor_destroy(i_fcolor *cl)
241 void i_fcolor_destroy(i_fcolor *cl) {
246 =item IIM_base_8bit_direct (static)
248 A static i_img object used to initialize direct 8-bit per sample images.
252 static i_img IIM_base_8bit_direct =
254 0, /* channels set */
255 0, 0, 0, /* xsize, ysize, bytes */
258 i_direct_type, /* type */
261 { 0, 0, NULL }, /* tags */
264 i_ppix_d, /* i_f_ppix */
265 i_ppixf_d, /* i_f_ppixf */
266 i_plin_d, /* i_f_plin */
267 i_plinf_d, /* i_f_plinf */
268 i_gpix_d, /* i_f_gpix */
269 i_gpixf_d, /* i_f_gpixf */
270 i_glin_d, /* i_f_glin */
271 i_glinf_d, /* i_f_glinf */
272 i_gsamp_d, /* i_f_gsamp */
273 i_gsampf_d, /* i_f_gsampf */
277 NULL, /* i_f_addcolors */
278 NULL, /* i_f_getcolors */
279 NULL, /* i_f_colorcount */
280 NULL, /* i_f_maxcolors */
281 NULL, /* i_f_findcolor */
282 NULL, /* i_f_setcolors */
284 NULL, /* i_f_destroy */
287 NULL, /* i_f_psamp_bits */
290 /*static void set_8bit_direct(i_img *im) {
291 im->i_f_ppix = i_ppix_d;
292 im->i_f_ppixf = i_ppixf_d;
293 im->i_f_plin = i_plin_d;
294 im->i_f_plinf = i_plinf_d;
295 im->i_f_gpix = i_gpix_d;
296 im->i_f_gpixf = i_gpixf_d;
297 im->i_f_glin = i_glin_d;
298 im->i_f_glinf = i_glinf_d;
301 im->i_f_addcolor = NULL;
302 im->i_f_getcolor = NULL;
303 im->i_f_colorcount = NULL;
304 im->i_f_findcolor = NULL;
308 =item IIM_new(x, y, ch)
310 =item i_img_8_new(x, y, ch)
312 =category Image creation/destruction
314 =synopsis i_img *img = i_img_8_new(width, height, channels);
316 Creates a new image object I<x> pixels wide, and I<y> pixels high with
324 IIM_new(int x,int y,int ch) {
326 mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
328 im=i_img_empty_ch(NULL,x,y,ch);
330 mm_log((1,"(%p) <- IIM_new\n",im));
336 IIM_DESTROY(i_img *im) {
337 mm_log((1,"IIM_DESTROY(im* %p)\n",im));
345 Create new image reference - notice that this isn't an object yet and
346 this should be fixed asap.
356 mm_log((1,"i_img_struct()\n"));
360 *im = IIM_base_8bit_direct;
370 mm_log((1,"(%p) <- i_img_struct\n",im));
375 =item i_img_empty(im, x, y)
377 Re-new image reference (assumes 3 channels)
380 x - xsize of destination image
381 y - ysize of destination image
383 **FIXME** what happens if a live image is passed in here?
385 Should this just call i_img_empty_ch()?
391 i_img_empty(i_img *im,int x,int y) {
392 mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
393 return i_img_empty_ch(im, x, y, 3);
397 =item i_img_empty_ch(im, x, y, ch)
399 Re-new image reference
402 x - xsize of destination image
403 y - ysize of destination image
404 ch - number of channels
410 i_img_empty_ch(i_img *im,int x,int y,int ch) {
413 mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
415 if (x < 1 || y < 1) {
416 i_push_error(0, "Image sizes must be positive");
419 if (ch < 1 || ch > MAXCHANNELS) {
420 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
423 /* check this multiplication doesn't overflow */
425 if (bytes / y / ch != x) {
426 i_push_errorf(0, "integer overflow calculating image allocation");
433 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
434 i_tags_new(&im->tags);
438 im->ch_mask = MAXINT;
440 if ( (im->idata=mymalloc(im->bytes)) == NULL)
441 i_fatal(2,"malloc() error\n");
442 memset(im->idata,0,(size_t)im->bytes);
448 mm_log((1,"(%p) <- i_img_empty_ch\n",im));
453 =item i_img_exorcise(im)
463 i_img_exorcise(i_img *im) {
464 mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
465 i_tags_destroy(&im->tags);
467 (im->i_f_destroy)(im);
468 if (im->idata != NULL) { myfree(im->idata); }
474 im->i_f_ppix=i_ppix_d;
475 im->i_f_gpix=i_gpix_d;
476 im->i_f_plin=i_plin_d;
477 im->i_f_glin=i_glin_d;
482 =item i_img_destroy(img)
484 =category Image creation/destruction
485 =synopsis i_img_destroy(img)
487 Destroy an image object
493 i_img_destroy(i_img *im) {
494 mm_log((1,"i_img_destroy(im %p)\n",im));
496 if (im) { myfree(im); }
500 =item i_img_info(im, info)
504 Return image information
507 info - pointer to array to return data
509 info is an array of 4 integers with the following values:
514 info[3] - channel mask
521 i_img_info(i_img *im,int *info) {
522 mm_log((1,"i_img_info(im 0x%x)\n",im));
524 mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
525 mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
528 info[2] = im->channels;
529 info[3] = im->ch_mask;
539 =item i_img_setmask(im, ch_mask)
541 =synopsis // only channel 0 writeable
542 =synopsis i_img_setmask(img, 0x01);
544 Set the image channel mask for I<im> to I<ch_mask>.
549 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
553 =item i_img_getmask(im)
555 =synopsis mask = i_img_getmask(img);
557 Get the image channel mask for I<im>.
562 i_img_getmask(i_img *im) { return im->ch_mask; }
565 =item i_img_getchannels(im)
567 =synopsis channels = i_img_getchannels(img);
569 Get the number of channels in I<im>.
574 i_img_getchannels(i_img *im) { return im->channels; }
577 =item i_img_get_width(im)
579 =synopsis width = i_img_get_width(im);
581 Returns the width in pixels of the image.
586 i_img_get_width(i_img *im) {
591 =item i_img_get_height(im)
593 =synopsis height = i_img_get_height(im);
595 Returns the height in pixels of the image.
600 i_img_get_height(i_img *im) {
605 =item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
609 (x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
610 (tx,ty) specifies the upper left corner for the target image.
611 pass NULL in trans for non transparent i_colors.
617 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) {
619 int x,y,t,ttx,tty,tt,ch;
621 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",
622 im, src, x1, y1, x2, y2, tx, ty, trans));
624 if (x2<x1) { t=x1; x1=x2; x2=t; }
625 if (y2<y1) { t=y1; y1=y2; y2=t; }
637 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
638 if (tt) i_ppix(im,ttx,tty,&pv);
639 } else i_ppix(im,ttx,tty,&pv);
651 Creates a new image that is a copy of src.
653 Tags are not copied, only the image data.
663 i_img *im = i_sametype(src, src->xsize, src->ysize);
665 mm_log((1,"i_copy(src %p)\n", src));
672 if (src->type == i_direct_type) {
673 if (src->bits == i_8_bits) {
675 pv = mymalloc(sizeof(i_color) * x1);
677 for (y = 0; y < y1; ++y) {
678 i_glin(src, 0, x1, y, pv);
679 i_plin(im, 0, x1, y, pv);
686 pv = mymalloc(sizeof(i_fcolor) * x1);
687 for (y = 0; y < y1; ++y) {
688 i_glinf(src, 0, x1, y, pv);
689 i_plinf(im, 0, x1, y, pv);
697 vals = mymalloc(sizeof(i_palidx) * x1);
698 for (y = 0; y < y1; ++y) {
699 i_gpal(src, 0, x1, y, vals);
700 i_ppal(im, 0, x1, y, vals);
710 =item i_flipxy(im, axis)
712 Flips the image inplace around the axis specified.
713 Returns 0 if parameters are invalid.
716 axis - 0 = x, 1 = y, 2 = both
722 i_flipxy(i_img *im, int direction) {
723 int x, x2, y, y2, xm, ym;
727 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
732 case XAXIS: /* Horizontal flip */
735 for(y=0; y<ym; y++) {
737 for(x=0; x<xm; x++) {
739 i_gpix(im, x, y, &val1);
740 i_gpix(im, x2, y, &val2);
741 i_ppix(im, x, y, &val2);
742 i_ppix(im, x2, y, &val1);
747 case YAXIS: /* Vertical flip */
751 for(y=0; y<ym; y++) {
752 for(x=0; x<xm; x++) {
754 i_gpix(im, x, y, &val1);
755 i_gpix(im, x, y2, &val2);
756 i_ppix(im, x, y, &val2);
757 i_ppix(im, x, y2, &val1);
762 case XYAXIS: /* Horizontal and Vertical flip */
766 for(y=0; y<ym; y++) {
768 for(x=0; x<xm; x++) {
770 i_gpix(im, x, y, &val1);
771 i_gpix(im, x2, y2, &val2);
772 i_ppix(im, x, y, &val2);
773 i_ppix(im, x2, y2, &val1);
775 i_gpix(im, x2, y, &val1);
776 i_gpix(im, x, y2, &val2);
777 i_ppix(im, x2, y, &val2);
778 i_ppix(im, x, y2, &val1);
783 if (xm*2 != xs) { /* odd number of column */
784 mm_log((1, "i_flipxy: odd number of columns\n"));
787 for(y=0; y<ym; y++) {
789 i_gpix(im, x, y, &val1);
790 i_gpix(im, x, y2, &val2);
791 i_ppix(im, x, y, &val2);
792 i_ppix(im, x, y2, &val1);
796 if (ym*2 != ys) { /* odd number of rows */
797 mm_log((1, "i_flipxy: odd number of rows\n"));
800 for(x=0; x<xm; x++) {
802 i_gpix(im, x, y, &val1);
803 i_gpix(im, x2, y, &val2);
804 i_ppix(im, x, y, &val2);
805 i_ppix(im, x2, y, &val1);
811 mm_log((1, "i_flipxy: direction is invalid\n" ));
829 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
830 else if (x == 0.0) return (1.0);
831 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
836 =item i_scaleaxis(im, value, axis)
838 Returns a new image object which is I<im> scaled by I<value> along
839 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
845 i_scaleaxis(i_img *im, float Value, int Axis) {
846 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
847 int LanczosWidthFactor;
848 float *l0, *l1, OldLocation;
851 float F, PictureValue[MAXCHANNELS];
853 i_color val,val1,val2;
856 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
860 hsize = (int)(0.5 + im->xsize * Value);
863 Value = 1.0 / im->xsize;
871 vsize = (int)(0.5 + im->ysize * Value);
875 Value = 1.0 / im->ysize;
882 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
884 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
885 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
886 lMax = LanczosWidthFactor << 1;
888 l0 = mymalloc(lMax * sizeof(float));
889 l1 = mymalloc(lMax * sizeof(float));
891 for (j=0; j<jEnd; j++) {
892 OldLocation = ((float) j) / Value;
893 T = (int) (OldLocation);
894 F = OldLocation - (float) T;
896 for (l = 0; l<lMax; l++) {
897 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
898 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
901 /* Make sure filter is normalized */
903 for(l=0; l<lMax; l++) {
907 t /= (float)LanczosWidthFactor;
909 for(l=0; l<lMax; l++) {
916 for (i=0; i<iEnd; i++) {
917 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
918 for (l=0; l<lMax; l++) {
921 mx = (mx < 0) ? 0 : mx;
922 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
924 i_gpix(im, Mx, i, &val1);
925 i_gpix(im, mx, i, &val2);
927 for (k=0; k<im->channels; k++) {
928 PictureValue[k] += l1[l] * val1.channel[k];
929 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
932 for(k=0;k<im->channels;k++) {
933 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
934 val.channel[k]=minmax(0,255,psave);
936 i_ppix(new_img, j, i, &val);
941 for (i=0; i<iEnd; i++) {
942 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
943 for (l=0; l < lMax; l++) {
946 mx = (mx < 0) ? 0 : mx;
947 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
949 i_gpix(im, i, Mx, &val1);
950 i_gpix(im, i, mx, &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, i, j, &val);
968 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
975 =item i_scale_nn(im, scx, scy)
977 Scale by using nearest neighbor
978 Both axes scaled at the same time since
979 nothing is gained by doing it in two steps
986 i_scale_nn(i_img *im, float scx, float scy) {
988 int nxsize,nysize,nx,ny;
992 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
994 nxsize = (int) ((float) im->xsize * scx);
999 nysize = (int) ((float) im->ysize * scy);
1002 scy = 1 / im->ysize;
1005 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1007 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1008 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1009 i_ppix(new_img,nx,ny,&val);
1012 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1018 =item i_sametype(i_img *im, int xsize, int ysize)
1020 =category Image creation/destruction
1021 =synopsis i_img *img = i_sametype(src, width, height);
1023 Returns an image of the same type (sample size, channels, paletted/direct).
1025 For paletted images the palette is copied from the source.
1030 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1031 if (src->type == i_direct_type) {
1032 if (src->bits == 8) {
1033 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1035 else if (src->bits == i_16_bits) {
1036 return i_img_16_new(xsize, ysize, src->channels);
1038 else if (src->bits == i_double_bits) {
1039 return i_img_double_new(xsize, ysize, src->channels);
1042 i_push_error(0, "Unknown image bits");
1050 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1051 for (i = 0; i < i_colorcount(src); ++i) {
1052 i_getcolors(src, i, &col, 1);
1053 i_addcolors(targ, &col, 1);
1061 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1063 =category Image creation/destruction
1064 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
1066 Returns an image of the same type (sample size).
1068 For paletted images the equivalent direct type is returned.
1073 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1074 if (src->bits == 8) {
1075 return i_img_empty_ch(NULL, xsize, ysize, channels);
1077 else if (src->bits == i_16_bits) {
1078 return i_img_16_new(xsize, ysize, channels);
1080 else if (src->bits == i_double_bits) {
1081 return i_img_double_new(xsize, ysize, channels);
1084 i_push_error(0, "Unknown image bits");
1090 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1092 Spatially transforms I<im> returning a new image.
1094 opx for a length of opxl and opy for a length of opy are arrays of
1095 operators that modify the x and y positions to retreive the pixel data from.
1097 parm and parmlen define extra parameters that the operators may use.
1099 Note that this function is largely superseded by the more flexible
1100 L<transform.c/i_transform2>.
1102 Returns the new image.
1104 The operators for this function are defined in L<stackmach.c>.
1109 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1111 int nxsize,nysize,nx,ny;
1115 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));
1118 nysize = im->ysize ;
1120 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1121 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1122 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1123 /* parm[parmlen-2]=(double)nx;
1124 parm[parmlen-1]=(double)ny; */
1129 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1130 rx=i_op_run(opx,opxl,parm,parmlen);
1131 ry=i_op_run(opy,opyl,parm,parmlen);
1132 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1133 i_gpix(im,rx,ry,&val);
1134 i_ppix(new_img,nx,ny,&val);
1137 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1142 =item i_img_diff(im1, im2)
1144 Calculates the sum of the squares of the differences between
1145 correspoding channels in two images.
1147 If the images are not the same size then only the common area is
1148 compared, hence even if images are different sizes this function
1154 i_img_diff(i_img *im1,i_img *im2) {
1155 int x,y,ch,xb,yb,chb;
1159 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1161 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1162 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1163 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1165 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1168 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1169 i_gpix(im1,x,y,&val1);
1170 i_gpix(im2,x,y,&val2);
1172 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1174 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1178 /* just a tiny demo of haar wavelets */
1186 i_img *new_img,*new_img2;
1187 i_color val1,val2,dval1,dval2;
1195 /* horizontal pass */
1197 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1198 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1201 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1202 i_gpix(im,x*2,y,&val1);
1203 i_gpix(im,x*2+1,y,&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_img,x,y,&dval1);
1209 i_ppix(new_img,x+fx,y,&dval2);
1212 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1213 i_gpix(new_img,x,y*2,&val1);
1214 i_gpix(new_img,x,y*2+1,&val2);
1215 for(ch=0;ch<im->channels;ch++) {
1216 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1217 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1219 i_ppix(new_img2,x,y,&dval1);
1220 i_ppix(new_img2,x,y+fy,&dval2);
1223 i_img_destroy(new_img);
1228 =item i_count_colors(im, maxc)
1230 returns number of colors or -1
1231 to indicate that it was more than max colors
1235 /* This function has been changed and is now faster. It's using
1236 * i_gsamp instead of i_gpix */
1238 i_count_colors(i_img *im,int maxc) {
1245 int xsize = im->xsize;
1246 int ysize = im->ysize;
1247 int samp_cnt = 3 * xsize;
1249 if (im->channels >= 3) {
1253 channels[0] = channels[1] = channels[2] = 0;
1254 samp_chans = channels;
1259 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1262 for(y = 0; y < ysize; ) {
1263 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1264 for(x = 0; x < samp_cnt; ) {
1265 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1267 if (colorcnt > maxc) {
1278 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1279 * (adapted from the Numerical Recipes)
1281 /* Needed by get_anonymous_color_histo */
1283 hpsort(unsigned int n, unsigned *ra) {
1308 if (j < ir && ra[j] < ra[j+1]) j++;
1320 /* This function constructs an ordered list which represents how much the
1321 * different colors are used. So for instance (100, 100, 500) means that one
1322 * color is used for 500 pixels, another for 100 pixels and another for 100
1323 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1324 * the maxc ;-) and you might want to change the name... */
1325 /* Uses octt_histo */
1327 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1331 unsigned int *col_usage_it;
1336 int xsize = im->xsize;
1337 int ysize = im->ysize;
1338 int samp_cnt = 3 * xsize;
1341 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1343 if (im->channels >= 3) {
1347 channels[0] = channels[1] = channels[2] = 0;
1348 samp_chans = channels;
1352 for(y = 0; y < ysize; ) {
1353 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1354 for(x = 0; x < samp_cnt; ) {
1355 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1357 if (colorcnt > maxc) {
1364 /* Now that we know the number of colours... */
1365 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1366 octt_histo(ct, &col_usage_it);
1367 hpsort(colorcnt, *col_usage);
1375 =head2 8-bit per sample image internal functions
1377 These are the functions installed in an 8-bit per sample image.
1381 =item i_ppix_d(im, x, y, col)
1385 This is the function kept in the i_f_ppix member of an i_img object.
1386 It does a normal store of a pixel into the image with range checking.
1388 Returns 0 if the pixel could be set, -1 otherwise.
1394 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1397 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1398 for(ch=0;ch<im->channels;ch++)
1399 if (im->ch_mask&(1<<ch))
1400 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1403 return -1; /* error was clipped */
1407 =item i_gpix_d(im, x, y, &col)
1411 This is the function kept in the i_f_gpix member of an i_img object.
1412 It does normal retrieval of a pixel from the image with range checking.
1414 Returns 0 if the pixel could be set, -1 otherwise.
1420 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1422 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1423 for(ch=0;ch<im->channels;ch++)
1424 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1427 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1428 return -1; /* error was cliped */
1432 =item i_glin_d(im, l, r, y, vals)
1434 Reads a line of data from the image, storing the pixels at vals.
1436 The line runs from (l,y) inclusive to (r,y) non-inclusive
1438 vals should point at space for (r-l) pixels.
1440 l should never be less than zero (to avoid confusion about where to
1441 put the pixels in vals).
1443 Returns the number of pixels copied (eg. if r, l or y is out of range)
1449 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1451 unsigned char *data;
1452 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1455 data = im->idata + (l+y*im->xsize) * im->channels;
1457 for (i = 0; i < count; ++i) {
1458 for (ch = 0; ch < im->channels; ++ch)
1459 vals[i].channel[ch] = *data++;
1469 =item i_plin_d(im, l, r, y, vals)
1471 Writes a line of data into the image, using the pixels at vals.
1473 The line runs from (l,y) inclusive to (r,y) non-inclusive
1475 vals should point at (r-l) pixels.
1477 l should never be less than zero (to avoid confusion about where to
1478 get the pixels in vals).
1480 Returns the number of pixels copied (eg. if r, l or y is out of range)
1486 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1488 unsigned char *data;
1489 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1492 data = im->idata + (l+y*im->xsize) * im->channels;
1494 for (i = 0; i < count; ++i) {
1495 for (ch = 0; ch < im->channels; ++ch) {
1496 if (im->ch_mask & (1 << ch))
1497 *data = vals[i].channel[ch];
1509 =item i_ppixf_d(im, x, y, val)
1515 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1518 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1519 for(ch=0;ch<im->channels;ch++)
1520 if (im->ch_mask&(1<<ch)) {
1521 im->idata[(x+y*im->xsize)*im->channels+ch] =
1522 SampleFTo8(val->channel[ch]);
1526 return -1; /* error was clipped */
1530 =item i_gpixf_d(im, x, y, val)
1536 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1538 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1539 for(ch=0;ch<im->channels;ch++) {
1541 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1545 return -1; /* error was cliped */
1549 =item i_glinf_d(im, l, r, y, vals)
1551 Reads a line of data from the image, storing the pixels at vals.
1553 The line runs from (l,y) inclusive to (r,y) non-inclusive
1555 vals should point at space for (r-l) pixels.
1557 l should never be less than zero (to avoid confusion about where to
1558 put the pixels in vals).
1560 Returns the number of pixels copied (eg. if r, l or y is out of range)
1566 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1568 unsigned char *data;
1569 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1572 data = im->idata + (l+y*im->xsize) * im->channels;
1574 for (i = 0; i < count; ++i) {
1575 for (ch = 0; ch < im->channels; ++ch)
1576 vals[i].channel[ch] = Sample8ToF(*data++);
1586 =item i_plinf_d(im, l, r, y, vals)
1588 Writes a line of data into the image, using the pixels at vals.
1590 The line runs from (l,y) inclusive to (r,y) non-inclusive
1592 vals should point at (r-l) pixels.
1594 l should never be less than zero (to avoid confusion about where to
1595 get the pixels in vals).
1597 Returns the number of pixels copied (eg. if r, l or y is out of range)
1603 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1605 unsigned char *data;
1606 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1609 data = im->idata + (l+y*im->xsize) * im->channels;
1611 for (i = 0; i < count; ++i) {
1612 for (ch = 0; ch < im->channels; ++ch) {
1613 if (im->ch_mask & (1 << ch))
1614 *data = SampleFTo8(vals[i].channel[ch]);
1626 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1628 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1629 for the channels specified by chans, an array of int with chan_count
1632 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1638 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1639 const int *chans, int chan_count) {
1640 int ch, count, i, w;
1641 unsigned char *data;
1643 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1646 data = im->idata + (l+y*im->xsize) * im->channels;
1651 /* make sure we have good channel numbers */
1652 for (ch = 0; ch < chan_count; ++ch) {
1653 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1654 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1658 for (i = 0; i < w; ++i) {
1659 for (ch = 0; ch < chan_count; ++ch) {
1660 *samps++ = data[chans[ch]];
1663 data += im->channels;
1667 if (chan_count <= 0 || chan_count > im->channels) {
1668 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1672 for (i = 0; i < w; ++i) {
1673 for (ch = 0; ch < chan_count; ++ch) {
1674 *samps++ = data[ch];
1677 data += im->channels;
1689 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1691 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1692 for the channels specified by chan_mask, where bit 0 is the first
1695 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1701 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1702 const int *chans, int chan_count) {
1703 int ch, count, i, w;
1704 unsigned char *data;
1705 for (ch = 0; ch < chan_count; ++ch) {
1706 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1707 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1710 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1713 data = im->idata + (l+y*im->xsize) * im->channels;
1718 /* make sure we have good channel numbers */
1719 for (ch = 0; ch < chan_count; ++ch) {
1720 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1721 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1725 for (i = 0; i < w; ++i) {
1726 for (ch = 0; ch < chan_count; ++ch) {
1727 *samps++ = Sample8ToF(data[chans[ch]]);
1730 data += im->channels;
1734 if (chan_count <= 0 || chan_count > im->channels) {
1735 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1739 for (i = 0; i < w; ++i) {
1740 for (ch = 0; ch < chan_count; ++ch) {
1741 *samps++ = Sample8ToF(data[ch]);
1744 data += im->channels;
1757 =head2 Image method wrappers
1759 These functions provide i_fsample_t functions in terms of their
1760 i_sample_t versions.
1764 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1769 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1773 for (ch = 0; ch < im->channels; ++ch)
1774 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1776 return i_ppix(im, x, y, &temp);
1780 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1784 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1788 if (i_gpix(im, x, y, &temp)) {
1789 for (ch = 0; ch < im->channels; ++ch)
1790 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1798 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1802 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1805 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1811 work = mymalloc(sizeof(i_color) * (r-l));
1812 for (i = 0; i < r-l; ++i) {
1813 for (ch = 0; ch < im->channels; ++ch)
1814 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1816 ret = i_plin(im, l, r, y, work);
1831 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1835 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1838 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1844 work = mymalloc(sizeof(i_color) * (r-l));
1845 ret = i_plin(im, l, r, y, work);
1846 for (i = 0; i < r-l; ++i) {
1847 for (ch = 0; ch < im->channels; ++ch)
1848 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1864 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1868 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1869 int const *chans, int chan_count) {
1872 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1878 work = mymalloc(sizeof(i_sample_t) * (r-l));
1879 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1880 for (i = 0; i < ret; ++i) {
1881 samp[i] = Sample8ToF(work[i]);
1899 =head2 Palette wrapper functions
1901 Used for virtual images, these forward palette calls to a wrapped image,
1902 assuming the wrapped image is the first pointer in the structure that
1903 im->ext_data points at.
1907 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1911 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1912 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1916 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1920 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1921 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1925 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1929 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1930 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1934 =item i_colorcount_forward(i_img *im)
1938 int i_colorcount_forward(i_img *im) {
1939 return i_colorcount(*(i_img **)im->ext_data);
1943 =item i_maxcolors_forward(i_img *im)
1947 int i_maxcolors_forward(i_img *im) {
1948 return i_maxcolors(*(i_img **)im->ext_data);
1952 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1956 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1957 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1963 =head2 Fallback handler
1967 =item i_gsamp_bits_fb
1973 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps,
1974 const int *chans, int chan_count, int bits) {
1975 if (bits < 1 || bits > 32) {
1976 i_push_error(0, "Invalid bits, must be 1..32");
1980 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1982 int ch, count, i, w;
1985 scale = 4294967295.0;
1987 scale = (double)(1 << bits) - 1;
1995 /* make sure we have good channel numbers */
1996 for (ch = 0; ch < chan_count; ++ch) {
1997 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1998 i_push_errorf(0, "No channel %d in this image", chans[ch]);
2002 for (i = 0; i < w; ++i) {
2004 i_gpixf(im, l+i, y, &c);
2005 for (ch = 0; ch < chan_count; ++ch) {
2006 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2012 if (chan_count <= 0 || chan_count > im->channels) {
2013 i_push_error(0, "Invalid channel count");
2016 for (i = 0; i < w; ++i) {
2018 i_gpixf(im, l+i, y, &c);
2019 for (ch = 0; ch < chan_count; ++ch) {
2020 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2029 i_push_error(0, "Image position outside of image");
2037 =head2 Stream reading and writing wrapper functions
2041 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
2043 Performs general read buffering for file readers that permit reading
2044 to be done through a callback.
2046 The final callback gets two parameters, a I<need> value, and a I<want>
2047 value, where I<need> is the amount of data that the file library needs
2048 to read, and I<want> is the amount of space available in the buffer
2049 maintained by these functions.
2051 This means if you need to read from a stream that you don't know the
2052 length of, you can return I<need> bytes, taking the performance hit of
2053 possibly expensive callbacks (eg. back to perl code), or if you are
2054 reading from a stream where it doesn't matter if some data is lost, or
2055 if the total length of the stream is known, you can return I<want>
2062 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2065 if (length < gci->length - gci->cpos) {
2067 memcpy(buf, gci->buffer+gci->cpos, length);
2068 gci->cpos += length;
2073 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2074 total += gci->length - gci->cpos;
2075 length -= gci->length - gci->cpos;
2076 buf += gci->length - gci->cpos;
2077 if (length < (int)sizeof(gci->buffer)) {
2081 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
2082 sizeof(gci->buffer))) > 0) {
2084 gci->length = did_read;
2086 copy_size = i_min(length, gci->length);
2087 memcpy(buf, gci->buffer, copy_size);
2088 gci->cpos += copy_size;
2091 length -= copy_size;
2095 /* just read the rest - too big for our buffer*/
2097 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2107 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2109 For use by callback file readers to initialize the reader buffer.
2111 Allocates, initializes and returns the reader buffer.
2113 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2118 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2119 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2121 self->userdata = userdata;
2129 =item i_free_gen_read_data(i_gen_read_data *)
2135 void i_free_gen_read_data(i_gen_read_data *self) {
2140 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2142 Performs write buffering for a callback based file writer.
2144 Failures are considered fatal, if a write fails then data will be
2151 i_gen_write_data *self,
2155 if (self->filledto && self->filledto+size > self->maxlength) {
2156 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2164 if (self->filledto+size <= self->maxlength) {
2166 memcpy(self->buffer+self->filledto, data, size);
2167 self->filledto += size;
2170 /* doesn't fit - hand it off */
2171 return self->cb(self->userdata, data, size);
2175 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2177 Allocates and initializes the data structure used by i_gen_writer.
2179 This should be released with L<image.c/i_free_gen_write_data>
2183 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2184 char *userdata, int max_length)
2186 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2188 self->userdata = userdata;
2189 self->maxlength = i_min(max_length, sizeof(self->buffer));
2190 if (self->maxlength < 0)
2191 self->maxlength = sizeof(self->buffer);
2198 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2200 Cleans up the write buffer.
2202 Will flush any left-over data if I<flush> is non-zero.
2204 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2206 Return zero only if flush is non-zero and info->cb() returns zero.
2212 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2214 int result = !flush ||
2215 info->filledto == 0 ||
2216 info->cb(info->userdata, info->buffer, info->filledto);
2222 struct magic_entry {
2223 unsigned char *magic;
2226 unsigned char *mask;
2230 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2231 if (length < magic->magic_size)
2235 unsigned char *bufp = buffer,
2236 *maskp = magic->mask,
2237 *magicp = magic->magic;
2239 for (i = 0; i < magic->magic_size; ++i) {
2240 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2243 if ((*bufp++ & mask) != (*magicp++ & mask))
2250 return !memcmp(magic->magic, buffer, magic->magic_size);
2255 =item i_test_format_probe(io_glue *data, int length)
2257 Check the beginning of the supplied file for a 'magic number'
2262 #define FORMAT_ENTRY(magic, type) \
2263 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2264 #define FORMAT_ENTRY2(magic, type, mask) \
2265 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2268 i_test_format_probe(io_glue *data, int length) {
2269 static const struct magic_entry formats[] = {
2270 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2271 FORMAT_ENTRY("GIF87a", "gif"),
2272 FORMAT_ENTRY("GIF89a", "gif"),
2273 FORMAT_ENTRY("MM\0*", "tiff"),
2274 FORMAT_ENTRY("II*\0", "tiff"),
2275 FORMAT_ENTRY("BM", "bmp"),
2276 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2277 FORMAT_ENTRY("P1", "pnm"),
2278 FORMAT_ENTRY("P2", "pnm"),
2279 FORMAT_ENTRY("P3", "pnm"),
2280 FORMAT_ENTRY("P4", "pnm"),
2281 FORMAT_ENTRY("P5", "pnm"),
2282 FORMAT_ENTRY("P6", "pnm"),
2283 FORMAT_ENTRY("/* XPM", "xpm"),
2284 FORMAT_ENTRY("\x8aMNG", "mng"),
2285 FORMAT_ENTRY("\x8aJNG", "jng"),
2286 /* SGI RGB - with various possible parameters to avoid false positives
2288 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2290 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2291 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2292 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2293 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2295 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
2297 /* different versions of PCX format
2298 http://www.fileformat.info/format/pcx/
2300 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2301 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2302 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2303 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2304 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2306 /* FITS - http://fits.gsfc.nasa.gov/ */
2307 FORMAT_ENTRY("SIMPLE =", "fits"),
2309 /* PSD - Photoshop */
2310 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2312 /* EPS - Encapsulated Postscript */
2313 /* only reading 18 chars, so we don't include the F in EPSF */
2314 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2317 FORMAT_ENTRY("\x52\xCC", "utah"),
2319 /* GZIP compressed, only matching deflate for now */
2320 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2322 /* bzip2 compressed */
2323 FORMAT_ENTRY("BZh", "bzip2"),
2325 static const struct magic_entry more_formats[] = {
2326 /* these were originally both listed as ico, but cur files can
2327 include hotspot information */
2328 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2329 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2330 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
2331 "xwd", " xxxx"), /* X Windows Dump */
2335 unsigned char head[18];
2338 io_glue_commit_types(data);
2339 rc = data->readcb(data, head, 18);
2340 if (rc == -1) return NULL;
2341 data->seekcb(data, -rc, SEEK_CUR);
2343 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2344 struct magic_entry const *entry = formats + i;
2346 if (test_magic(head, rc, entry))
2351 tga_header_verify(head))
2354 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
2355 struct magic_entry const *entry = more_formats + i;
2357 if (test_magic(head, rc, entry))
2365 =item i_img_is_monochrome(img, &zero_is_white)
2367 Tests an image to check it meets our monochrome tests.
2369 The idea is that a file writer can use this to test where it should
2370 write the image in whatever bi-level format it uses, eg. pbm for pnm.
2372 For performance of encoders we require monochrome images:
2382 have a palette of two colors, containing only (0,0,0) and
2383 (255,255,255) in either order.
2387 zero_is_white is set to non-zero iff the first palette entry is white.
2393 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2394 if (im->type == i_palette_type
2395 && i_colorcount(im) == 2) {
2397 i_getcolors(im, 0, colors, 2);
2398 if (im->channels == 3) {
2399 if (colors[0].rgb.r == 255 &&
2400 colors[0].rgb.g == 255 &&
2401 colors[0].rgb.b == 255 &&
2402 colors[1].rgb.r == 0 &&
2403 colors[1].rgb.g == 0 &&
2404 colors[1].rgb.b == 0) {
2408 else if (colors[0].rgb.r == 0 &&
2409 colors[0].rgb.g == 0 &&
2410 colors[0].rgb.b == 0 &&
2411 colors[1].rgb.r == 255 &&
2412 colors[1].rgb.g == 255 &&
2413 colors[1].rgb.b == 255) {
2418 else if (im->channels == 1) {
2419 if (colors[0].channel[0] == 255 &&
2420 colors[1].channel[0] == 0) {
2424 else if (colors[0].channel[0] == 0 &&
2425 colors[1].channel[0] == 255) {
2441 Arnar M. Hrafnkelsson <addi@umich.edu>
2443 Tony Cook <tony@develop-help.com>