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;
857 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
861 hsize = (int)(0.5 + im->xsize * Value);
864 Value = 1.0 / im->xsize;
872 vsize = (int)(0.5 + im->ysize * Value);
876 Value = 1.0 / im->ysize;
883 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
885 i_push_error(0, "cannot create output image");
889 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
890 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
891 lMax = LanczosWidthFactor << 1;
893 l0 = mymalloc(lMax * sizeof(float));
894 l1 = mymalloc(lMax * sizeof(float));
896 for (j=0; j<jEnd; j++) {
897 OldLocation = ((float) j) / Value;
898 T = (int) (OldLocation);
899 F = OldLocation - (float) T;
901 for (l = 0; l<lMax; l++) {
902 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
903 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
906 /* Make sure filter is normalized */
908 for(l=0; l<lMax; l++) {
912 t /= (float)LanczosWidthFactor;
914 for(l=0; l<lMax; l++) {
921 for (i=0; i<iEnd; i++) {
922 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
923 for (l=0; l<lMax; l++) {
926 mx = (mx < 0) ? 0 : mx;
927 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
929 i_gpix(im, Mx, i, &val1);
930 i_gpix(im, mx, i, &val2);
932 for (k=0; k<im->channels; k++) {
933 PictureValue[k] += l1[l] * val1.channel[k];
934 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
937 for(k=0;k<im->channels;k++) {
938 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
939 val.channel[k]=minmax(0,255,psave);
941 i_ppix(new_img, j, i, &val);
946 for (i=0; i<iEnd; i++) {
947 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
948 for (l=0; l < lMax; l++) {
951 mx = (mx < 0) ? 0 : mx;
952 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
954 i_gpix(im, i, Mx, &val1);
955 i_gpix(im, i, mx, &val2);
956 for (k=0; k<im->channels; k++) {
957 PictureValue[k] += l1[l] * val1.channel[k];
958 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
961 for (k=0; k<im->channels; k++) {
962 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
963 val.channel[k] = minmax(0, 255, psave);
965 i_ppix(new_img, i, j, &val);
973 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
980 =item i_scale_nn(im, scx, scy)
982 Scale by using nearest neighbor
983 Both axes scaled at the same time since
984 nothing is gained by doing it in two steps
991 i_scale_nn(i_img *im, float scx, float scy) {
993 int nxsize,nysize,nx,ny;
997 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
999 nxsize = (int) ((float) im->xsize * scx);
1002 scx = 1 / im->xsize;
1004 nysize = (int) ((float) im->ysize * scy);
1007 scy = 1 / im->ysize;
1010 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1012 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1013 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1014 i_ppix(new_img,nx,ny,&val);
1017 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1023 =item i_sametype(i_img *im, int xsize, int ysize)
1025 =category Image creation/destruction
1026 =synopsis i_img *img = i_sametype(src, width, height);
1028 Returns an image of the same type (sample size, channels, paletted/direct).
1030 For paletted images the palette is copied from the source.
1035 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1036 if (src->type == i_direct_type) {
1037 if (src->bits == 8) {
1038 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1040 else if (src->bits == i_16_bits) {
1041 return i_img_16_new(xsize, ysize, src->channels);
1043 else if (src->bits == i_double_bits) {
1044 return i_img_double_new(xsize, ysize, src->channels);
1047 i_push_error(0, "Unknown image bits");
1055 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1056 for (i = 0; i < i_colorcount(src); ++i) {
1057 i_getcolors(src, i, &col, 1);
1058 i_addcolors(targ, &col, 1);
1066 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1068 =category Image creation/destruction
1069 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
1071 Returns an image of the same type (sample size).
1073 For paletted images the equivalent direct type is returned.
1078 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1079 if (src->bits == 8) {
1080 return i_img_empty_ch(NULL, xsize, ysize, channels);
1082 else if (src->bits == i_16_bits) {
1083 return i_img_16_new(xsize, ysize, channels);
1085 else if (src->bits == i_double_bits) {
1086 return i_img_double_new(xsize, ysize, channels);
1089 i_push_error(0, "Unknown image bits");
1095 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1097 Spatially transforms I<im> returning a new image.
1099 opx for a length of opxl and opy for a length of opy are arrays of
1100 operators that modify the x and y positions to retreive the pixel data from.
1102 parm and parmlen define extra parameters that the operators may use.
1104 Note that this function is largely superseded by the more flexible
1105 L<transform.c/i_transform2>.
1107 Returns the new image.
1109 The operators for this function are defined in L<stackmach.c>.
1114 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1116 int nxsize,nysize,nx,ny;
1120 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));
1123 nysize = im->ysize ;
1125 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1126 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1127 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1128 /* parm[parmlen-2]=(double)nx;
1129 parm[parmlen-1]=(double)ny; */
1134 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1135 rx=i_op_run(opx,opxl,parm,parmlen);
1136 ry=i_op_run(opy,opyl,parm,parmlen);
1137 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1138 i_gpix(im,rx,ry,&val);
1139 i_ppix(new_img,nx,ny,&val);
1142 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1147 =item i_img_diff(im1, im2)
1149 Calculates the sum of the squares of the differences between
1150 correspoding channels in two images.
1152 If the images are not the same size then only the common area is
1153 compared, hence even if images are different sizes this function
1159 i_img_diff(i_img *im1,i_img *im2) {
1160 int x,y,ch,xb,yb,chb;
1164 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1166 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1167 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1168 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1170 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1173 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1174 i_gpix(im1,x,y,&val1);
1175 i_gpix(im2,x,y,&val2);
1177 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1179 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1183 /* just a tiny demo of haar wavelets */
1191 i_img *new_img,*new_img2;
1192 i_color val1,val2,dval1,dval2;
1200 /* horizontal pass */
1202 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1203 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1206 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1207 i_gpix(im,x*2,y,&val1);
1208 i_gpix(im,x*2+1,y,&val2);
1209 for(ch=0;ch<im->channels;ch++) {
1210 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1211 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1213 i_ppix(new_img,x,y,&dval1);
1214 i_ppix(new_img,x+fx,y,&dval2);
1217 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1218 i_gpix(new_img,x,y*2,&val1);
1219 i_gpix(new_img,x,y*2+1,&val2);
1220 for(ch=0;ch<im->channels;ch++) {
1221 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1222 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1224 i_ppix(new_img2,x,y,&dval1);
1225 i_ppix(new_img2,x,y+fy,&dval2);
1228 i_img_destroy(new_img);
1233 =item i_count_colors(im, maxc)
1235 returns number of colors or -1
1236 to indicate that it was more than max colors
1240 /* This function has been changed and is now faster. It's using
1241 * i_gsamp instead of i_gpix */
1243 i_count_colors(i_img *im,int maxc) {
1250 int xsize = im->xsize;
1251 int ysize = im->ysize;
1252 int samp_cnt = 3 * xsize;
1254 if (im->channels >= 3) {
1258 channels[0] = channels[1] = channels[2] = 0;
1259 samp_chans = channels;
1264 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1267 for(y = 0; y < ysize; ) {
1268 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1269 for(x = 0; x < samp_cnt; ) {
1270 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1272 if (colorcnt > maxc) {
1283 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1284 * (adapted from the Numerical Recipes)
1286 /* Needed by get_anonymous_color_histo */
1288 hpsort(unsigned int n, unsigned *ra) {
1313 if (j < ir && ra[j] < ra[j+1]) j++;
1325 /* This function constructs an ordered list which represents how much the
1326 * different colors are used. So for instance (100, 100, 500) means that one
1327 * color is used for 500 pixels, another for 100 pixels and another for 100
1328 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1329 * the maxc ;-) and you might want to change the name... */
1330 /* Uses octt_histo */
1332 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1336 unsigned int *col_usage_it;
1341 int xsize = im->xsize;
1342 int ysize = im->ysize;
1343 int samp_cnt = 3 * xsize;
1346 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1348 if (im->channels >= 3) {
1352 channels[0] = channels[1] = channels[2] = 0;
1353 samp_chans = channels;
1357 for(y = 0; y < ysize; ) {
1358 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1359 for(x = 0; x < samp_cnt; ) {
1360 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1362 if (colorcnt > maxc) {
1369 /* Now that we know the number of colours... */
1370 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1371 octt_histo(ct, &col_usage_it);
1372 hpsort(colorcnt, *col_usage);
1380 =head2 8-bit per sample image internal functions
1382 These are the functions installed in an 8-bit per sample image.
1386 =item i_ppix_d(im, x, y, col)
1390 This is the function kept in the i_f_ppix member of an i_img object.
1391 It does a normal store of a pixel into the image with range checking.
1393 Returns 0 if the pixel could be set, -1 otherwise.
1399 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1402 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1403 for(ch=0;ch<im->channels;ch++)
1404 if (im->ch_mask&(1<<ch))
1405 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1408 return -1; /* error was clipped */
1412 =item i_gpix_d(im, x, y, &col)
1416 This is the function kept in the i_f_gpix member of an i_img object.
1417 It does normal retrieval of a pixel from the image with range checking.
1419 Returns 0 if the pixel could be set, -1 otherwise.
1425 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1427 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1428 for(ch=0;ch<im->channels;ch++)
1429 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1432 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1433 return -1; /* error was cliped */
1437 =item i_glin_d(im, l, r, y, vals)
1439 Reads a line of data from the image, storing the pixels at vals.
1441 The line runs from (l,y) inclusive to (r,y) non-inclusive
1443 vals should point at space for (r-l) pixels.
1445 l should never be less than zero (to avoid confusion about where to
1446 put the pixels in vals).
1448 Returns the number of pixels copied (eg. if r, l or y is out of range)
1454 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1456 unsigned char *data;
1457 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1460 data = im->idata + (l+y*im->xsize) * im->channels;
1462 for (i = 0; i < count; ++i) {
1463 for (ch = 0; ch < im->channels; ++ch)
1464 vals[i].channel[ch] = *data++;
1474 =item i_plin_d(im, l, r, y, vals)
1476 Writes a line of data into the image, using the pixels at vals.
1478 The line runs from (l,y) inclusive to (r,y) non-inclusive
1480 vals should point at (r-l) pixels.
1482 l should never be less than zero (to avoid confusion about where to
1483 get the pixels in vals).
1485 Returns the number of pixels copied (eg. if r, l or y is out of range)
1491 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1493 unsigned char *data;
1494 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1497 data = im->idata + (l+y*im->xsize) * im->channels;
1499 for (i = 0; i < count; ++i) {
1500 for (ch = 0; ch < im->channels; ++ch) {
1501 if (im->ch_mask & (1 << ch))
1502 *data = vals[i].channel[ch];
1514 =item i_ppixf_d(im, x, y, val)
1520 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1523 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1524 for(ch=0;ch<im->channels;ch++)
1525 if (im->ch_mask&(1<<ch)) {
1526 im->idata[(x+y*im->xsize)*im->channels+ch] =
1527 SampleFTo8(val->channel[ch]);
1531 return -1; /* error was clipped */
1535 =item i_gpixf_d(im, x, y, val)
1541 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1543 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1544 for(ch=0;ch<im->channels;ch++) {
1546 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1550 return -1; /* error was cliped */
1554 =item i_glinf_d(im, l, r, y, vals)
1556 Reads a line of data from the image, storing the pixels at vals.
1558 The line runs from (l,y) inclusive to (r,y) non-inclusive
1560 vals should point at space for (r-l) pixels.
1562 l should never be less than zero (to avoid confusion about where to
1563 put the pixels in vals).
1565 Returns the number of pixels copied (eg. if r, l or y is out of range)
1571 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1573 unsigned char *data;
1574 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1577 data = im->idata + (l+y*im->xsize) * im->channels;
1579 for (i = 0; i < count; ++i) {
1580 for (ch = 0; ch < im->channels; ++ch)
1581 vals[i].channel[ch] = Sample8ToF(*data++);
1591 =item i_plinf_d(im, l, r, y, vals)
1593 Writes a line of data into the image, using the pixels at vals.
1595 The line runs from (l,y) inclusive to (r,y) non-inclusive
1597 vals should point at (r-l) pixels.
1599 l should never be less than zero (to avoid confusion about where to
1600 get the pixels in vals).
1602 Returns the number of pixels copied (eg. if r, l or y is out of range)
1608 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1610 unsigned char *data;
1611 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1614 data = im->idata + (l+y*im->xsize) * im->channels;
1616 for (i = 0; i < count; ++i) {
1617 for (ch = 0; ch < im->channels; ++ch) {
1618 if (im->ch_mask & (1 << ch))
1619 *data = SampleFTo8(vals[i].channel[ch]);
1631 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1633 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1634 for the channels specified by chans, an array of int with chan_count
1637 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1643 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1644 const int *chans, int chan_count) {
1645 int ch, count, i, w;
1646 unsigned char *data;
1648 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1651 data = im->idata + (l+y*im->xsize) * im->channels;
1656 /* make sure we have good channel numbers */
1657 for (ch = 0; ch < chan_count; ++ch) {
1658 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1659 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1663 for (i = 0; i < w; ++i) {
1664 for (ch = 0; ch < chan_count; ++ch) {
1665 *samps++ = data[chans[ch]];
1668 data += im->channels;
1672 if (chan_count <= 0 || chan_count > im->channels) {
1673 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1677 for (i = 0; i < w; ++i) {
1678 for (ch = 0; ch < chan_count; ++ch) {
1679 *samps++ = data[ch];
1682 data += im->channels;
1694 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1696 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1697 for the channels specified by chan_mask, where bit 0 is the first
1700 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1706 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1707 const int *chans, int chan_count) {
1708 int ch, count, i, w;
1709 unsigned char *data;
1710 for (ch = 0; ch < chan_count; ++ch) {
1711 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1712 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1715 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1718 data = im->idata + (l+y*im->xsize) * im->channels;
1723 /* make sure we have good channel numbers */
1724 for (ch = 0; ch < chan_count; ++ch) {
1725 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1726 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1730 for (i = 0; i < w; ++i) {
1731 for (ch = 0; ch < chan_count; ++ch) {
1732 *samps++ = Sample8ToF(data[chans[ch]]);
1735 data += im->channels;
1739 if (chan_count <= 0 || chan_count > im->channels) {
1740 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1744 for (i = 0; i < w; ++i) {
1745 for (ch = 0; ch < chan_count; ++ch) {
1746 *samps++ = Sample8ToF(data[ch]);
1749 data += im->channels;
1762 =head2 Image method wrappers
1764 These functions provide i_fsample_t functions in terms of their
1765 i_sample_t versions.
1769 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1774 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1778 for (ch = 0; ch < im->channels; ++ch)
1779 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1781 return i_ppix(im, x, y, &temp);
1785 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1789 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1793 if (i_gpix(im, x, y, &temp)) {
1794 for (ch = 0; ch < im->channels; ++ch)
1795 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1803 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1807 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1810 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1816 work = mymalloc(sizeof(i_color) * (r-l));
1817 for (i = 0; i < r-l; ++i) {
1818 for (ch = 0; ch < im->channels; ++ch)
1819 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1821 ret = i_plin(im, l, r, y, work);
1836 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1840 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1843 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1849 work = mymalloc(sizeof(i_color) * (r-l));
1850 ret = i_plin(im, l, r, y, work);
1851 for (i = 0; i < r-l; ++i) {
1852 for (ch = 0; ch < im->channels; ++ch)
1853 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1869 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1873 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1874 int const *chans, int chan_count) {
1877 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1883 work = mymalloc(sizeof(i_sample_t) * (r-l));
1884 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1885 for (i = 0; i < ret; ++i) {
1886 samp[i] = Sample8ToF(work[i]);
1904 =head2 Palette wrapper functions
1906 Used for virtual images, these forward palette calls to a wrapped image,
1907 assuming the wrapped image is the first pointer in the structure that
1908 im->ext_data points at.
1912 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1916 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1917 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1921 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1925 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1926 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1930 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1934 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1935 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1939 =item i_colorcount_forward(i_img *im)
1943 int i_colorcount_forward(i_img *im) {
1944 return i_colorcount(*(i_img **)im->ext_data);
1948 =item i_maxcolors_forward(i_img *im)
1952 int i_maxcolors_forward(i_img *im) {
1953 return i_maxcolors(*(i_img **)im->ext_data);
1957 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1961 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1962 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1968 =head2 Fallback handler
1972 =item i_gsamp_bits_fb
1978 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps,
1979 const int *chans, int chan_count, int bits) {
1980 if (bits < 1 || bits > 32) {
1981 i_push_error(0, "Invalid bits, must be 1..32");
1985 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1987 int ch, count, i, w;
1990 scale = 4294967295.0;
1992 scale = (double)(1 << bits) - 1;
2000 /* make sure we have good channel numbers */
2001 for (ch = 0; ch < chan_count; ++ch) {
2002 if (chans[ch] < 0 || chans[ch] >= im->channels) {
2003 i_push_errorf(0, "No channel %d in this image", chans[ch]);
2007 for (i = 0; i < w; ++i) {
2009 i_gpixf(im, l+i, y, &c);
2010 for (ch = 0; ch < chan_count; ++ch) {
2011 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2017 if (chan_count <= 0 || chan_count > im->channels) {
2018 i_push_error(0, "Invalid channel count");
2021 for (i = 0; i < w; ++i) {
2023 i_gpixf(im, l+i, y, &c);
2024 for (ch = 0; ch < chan_count; ++ch) {
2025 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2034 i_push_error(0, "Image position outside of image");
2042 =head2 Stream reading and writing wrapper functions
2046 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
2048 Performs general read buffering for file readers that permit reading
2049 to be done through a callback.
2051 The final callback gets two parameters, a I<need> value, and a I<want>
2052 value, where I<need> is the amount of data that the file library needs
2053 to read, and I<want> is the amount of space available in the buffer
2054 maintained by these functions.
2056 This means if you need to read from a stream that you don't know the
2057 length of, you can return I<need> bytes, taking the performance hit of
2058 possibly expensive callbacks (eg. back to perl code), or if you are
2059 reading from a stream where it doesn't matter if some data is lost, or
2060 if the total length of the stream is known, you can return I<want>
2067 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2070 if (length < gci->length - gci->cpos) {
2072 memcpy(buf, gci->buffer+gci->cpos, length);
2073 gci->cpos += length;
2078 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2079 total += gci->length - gci->cpos;
2080 length -= gci->length - gci->cpos;
2081 buf += gci->length - gci->cpos;
2082 if (length < (int)sizeof(gci->buffer)) {
2086 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
2087 sizeof(gci->buffer))) > 0) {
2089 gci->length = did_read;
2091 copy_size = i_min(length, gci->length);
2092 memcpy(buf, gci->buffer, copy_size);
2093 gci->cpos += copy_size;
2096 length -= copy_size;
2100 /* just read the rest - too big for our buffer*/
2102 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2112 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2114 For use by callback file readers to initialize the reader buffer.
2116 Allocates, initializes and returns the reader buffer.
2118 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2123 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2124 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2126 self->userdata = userdata;
2134 =item i_free_gen_read_data(i_gen_read_data *)
2140 void i_free_gen_read_data(i_gen_read_data *self) {
2145 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2147 Performs write buffering for a callback based file writer.
2149 Failures are considered fatal, if a write fails then data will be
2156 i_gen_write_data *self,
2160 if (self->filledto && self->filledto+size > self->maxlength) {
2161 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2169 if (self->filledto+size <= self->maxlength) {
2171 memcpy(self->buffer+self->filledto, data, size);
2172 self->filledto += size;
2175 /* doesn't fit - hand it off */
2176 return self->cb(self->userdata, data, size);
2180 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2182 Allocates and initializes the data structure used by i_gen_writer.
2184 This should be released with L<image.c/i_free_gen_write_data>
2188 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2189 char *userdata, int max_length)
2191 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2193 self->userdata = userdata;
2194 self->maxlength = i_min(max_length, sizeof(self->buffer));
2195 if (self->maxlength < 0)
2196 self->maxlength = sizeof(self->buffer);
2203 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2205 Cleans up the write buffer.
2207 Will flush any left-over data if I<flush> is non-zero.
2209 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2211 Return zero only if flush is non-zero and info->cb() returns zero.
2217 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2219 int result = !flush ||
2220 info->filledto == 0 ||
2221 info->cb(info->userdata, info->buffer, info->filledto);
2227 struct magic_entry {
2228 unsigned char *magic;
2231 unsigned char *mask;
2235 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2236 if (length < magic->magic_size)
2240 unsigned char *bufp = buffer,
2241 *maskp = magic->mask,
2242 *magicp = magic->magic;
2244 for (i = 0; i < magic->magic_size; ++i) {
2245 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2248 if ((*bufp++ & mask) != (*magicp++ & mask))
2255 return !memcmp(magic->magic, buffer, magic->magic_size);
2260 =item i_test_format_probe(io_glue *data, int length)
2262 Check the beginning of the supplied file for a 'magic number'
2267 #define FORMAT_ENTRY(magic, type) \
2268 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2269 #define FORMAT_ENTRY2(magic, type, mask) \
2270 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2273 i_test_format_probe(io_glue *data, int length) {
2274 static const struct magic_entry formats[] = {
2275 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2276 FORMAT_ENTRY("GIF87a", "gif"),
2277 FORMAT_ENTRY("GIF89a", "gif"),
2278 FORMAT_ENTRY("MM\0*", "tiff"),
2279 FORMAT_ENTRY("II*\0", "tiff"),
2280 FORMAT_ENTRY("BM", "bmp"),
2281 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2282 FORMAT_ENTRY("P1", "pnm"),
2283 FORMAT_ENTRY("P2", "pnm"),
2284 FORMAT_ENTRY("P3", "pnm"),
2285 FORMAT_ENTRY("P4", "pnm"),
2286 FORMAT_ENTRY("P5", "pnm"),
2287 FORMAT_ENTRY("P6", "pnm"),
2288 FORMAT_ENTRY("/* XPM", "xpm"),
2289 FORMAT_ENTRY("\x8aMNG", "mng"),
2290 FORMAT_ENTRY("\x8aJNG", "jng"),
2291 /* SGI RGB - with various possible parameters to avoid false positives
2293 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2295 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2296 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2297 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2298 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2300 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
2302 /* different versions of PCX format
2303 http://www.fileformat.info/format/pcx/
2305 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2306 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2307 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2308 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2309 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2311 /* FITS - http://fits.gsfc.nasa.gov/ */
2312 FORMAT_ENTRY("SIMPLE =", "fits"),
2314 /* PSD - Photoshop */
2315 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2317 /* EPS - Encapsulated Postscript */
2318 /* only reading 18 chars, so we don't include the F in EPSF */
2319 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2322 FORMAT_ENTRY("\x52\xCC", "utah"),
2324 /* GZIP compressed, only matching deflate for now */
2325 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2327 /* bzip2 compressed */
2328 FORMAT_ENTRY("BZh", "bzip2"),
2330 static const struct magic_entry more_formats[] = {
2331 /* these were originally both listed as ico, but cur files can
2332 include hotspot information */
2333 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2334 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2335 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
2336 "xwd", " xxxx"), /* X Windows Dump */
2340 unsigned char head[18];
2343 io_glue_commit_types(data);
2344 rc = data->readcb(data, head, 18);
2345 if (rc == -1) return NULL;
2346 data->seekcb(data, -rc, SEEK_CUR);
2348 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2349 struct magic_entry const *entry = formats + i;
2351 if (test_magic(head, rc, entry))
2356 tga_header_verify(head))
2359 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
2360 struct magic_entry const *entry = more_formats + i;
2362 if (test_magic(head, rc, entry))
2370 =item i_img_is_monochrome(img, &zero_is_white)
2372 Tests an image to check it meets our monochrome tests.
2374 The idea is that a file writer can use this to test where it should
2375 write the image in whatever bi-level format it uses, eg. pbm for pnm.
2377 For performance of encoders we require monochrome images:
2387 have a palette of two colors, containing only (0,0,0) and
2388 (255,255,255) in either order.
2392 zero_is_white is set to non-zero iff the first palette entry is white.
2398 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2399 if (im->type == i_palette_type
2400 && i_colorcount(im) == 2) {
2402 i_getcolors(im, 0, colors, 2);
2403 if (im->channels == 3) {
2404 if (colors[0].rgb.r == 255 &&
2405 colors[0].rgb.g == 255 &&
2406 colors[0].rgb.b == 255 &&
2407 colors[1].rgb.r == 0 &&
2408 colors[1].rgb.g == 0 &&
2409 colors[1].rgb.b == 0) {
2413 else if (colors[0].rgb.r == 0 &&
2414 colors[0].rgb.g == 0 &&
2415 colors[0].rgb.b == 0 &&
2416 colors[1].rgb.r == 255 &&
2417 colors[1].rgb.g == 255 &&
2418 colors[1].rgb.b == 255) {
2423 else if (im->channels == 1) {
2424 if (colors[0].channel[0] == 255 &&
2425 colors[1].channel[0] == 0) {
2429 else if (colors[0].channel[0] == 0 &&
2430 colors[1].channel[0] == 255) {
2442 =item i_get_file_background(im, &bg)
2444 Retrieve the file write background color tag from the image.
2446 If not present, returns black.
2452 i_get_file_background(i_img *im, i_color *bg) {
2453 if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
2455 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
2457 /* always full alpha */
2458 bg->channel[3] = 255;
2462 =item i_get_file_backgroundf(im, &bg)
2464 Retrieve the file write background color tag from the image as a
2465 floating point color.
2467 Implemented in terms of i_get_file_background().
2469 If not present, returns black.
2475 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
2478 i_get_file_background(im, &bg);
2479 fbg->rgba.r = Sample8ToF(bg.rgba.r);
2480 fbg->rgba.g = Sample8ToF(bg.rgba.g);
2481 fbg->rgba.b = Sample8ToF(bg.rgba.b);
2490 Arnar M. Hrafnkelsson <addi@umich.edu>
2492 Tony Cook <tony@develop-help.com>