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)
540 =category Image Information
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>.
546 The image channel mask gives some control over which channels can be
547 written to in the image.
552 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
556 =item i_img_getmask(im)
557 =category Image Information
558 =synopsis int mask = i_img_getmask(img);
560 Get the image channel mask for I<im>.
565 i_img_getmask(i_img *im) { return im->ch_mask; }
568 =item i_img_getchannels(im)
569 =category Image Information
570 =synopsis int channels = i_img_getchannels(img);
572 Get the number of channels in I<im>.
577 i_img_getchannels(i_img *im) { return im->channels; }
580 =item i_img_get_width(im)
581 =category Image Information
582 =synopsis i_img_dim width = i_img_get_width(im);
584 Returns the width in pixels of the image.
589 i_img_get_width(i_img *im) {
594 =item i_img_get_height(im)
595 =category Image Information
596 =synopsis i_img_dim height = i_img_get_height(im);
598 Returns the height in pixels of the image.
603 i_img_get_height(i_img *im) {
608 =item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
612 (x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
613 (tx,ty) specifies the upper left corner for the target image.
614 pass NULL in trans for non transparent i_colors.
620 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) {
622 int x,y,t,ttx,tty,tt,ch;
624 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",
625 im, src, x1, y1, x2, y2, tx, ty, trans));
627 if (x2<x1) { t=x1; x1=x2; x2=t; }
628 if (y2<y1) { t=y1; y1=y2; y2=t; }
640 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
641 if (tt) i_ppix(im,ttx,tty,&pv);
642 } else i_ppix(im,ttx,tty,&pv);
654 Creates a new image that is a copy of src.
656 Tags are not copied, only the image data.
666 i_img *im = i_sametype(src, src->xsize, src->ysize);
668 mm_log((1,"i_copy(src %p)\n", src));
675 if (src->type == i_direct_type) {
676 if (src->bits == i_8_bits) {
678 pv = mymalloc(sizeof(i_color) * x1);
680 for (y = 0; y < y1; ++y) {
681 i_glin(src, 0, x1, y, pv);
682 i_plin(im, 0, x1, y, pv);
689 pv = mymalloc(sizeof(i_fcolor) * x1);
690 for (y = 0; y < y1; ++y) {
691 i_glinf(src, 0, x1, y, pv);
692 i_plinf(im, 0, x1, y, pv);
700 vals = mymalloc(sizeof(i_palidx) * x1);
701 for (y = 0; y < y1; ++y) {
702 i_gpal(src, 0, x1, y, vals);
703 i_ppal(im, 0, x1, y, vals);
713 =item i_flipxy(im, axis)
715 Flips the image inplace around the axis specified.
716 Returns 0 if parameters are invalid.
719 axis - 0 = x, 1 = y, 2 = both
725 i_flipxy(i_img *im, int direction) {
726 int x, x2, y, y2, xm, ym;
730 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
735 case XAXIS: /* Horizontal flip */
738 for(y=0; y<ym; y++) {
740 for(x=0; x<xm; x++) {
742 i_gpix(im, x, y, &val1);
743 i_gpix(im, x2, y, &val2);
744 i_ppix(im, x, y, &val2);
745 i_ppix(im, x2, y, &val1);
750 case YAXIS: /* Vertical flip */
754 for(y=0; y<ym; y++) {
755 for(x=0; x<xm; x++) {
757 i_gpix(im, x, y, &val1);
758 i_gpix(im, x, y2, &val2);
759 i_ppix(im, x, y, &val2);
760 i_ppix(im, x, y2, &val1);
765 case XYAXIS: /* Horizontal and Vertical flip */
769 for(y=0; y<ym; y++) {
771 for(x=0; x<xm; x++) {
773 i_gpix(im, x, y, &val1);
774 i_gpix(im, x2, y2, &val2);
775 i_ppix(im, x, y, &val2);
776 i_ppix(im, x2, y2, &val1);
778 i_gpix(im, x2, y, &val1);
779 i_gpix(im, x, y2, &val2);
780 i_ppix(im, x2, y, &val2);
781 i_ppix(im, x, y2, &val1);
786 if (xm*2 != xs) { /* odd number of column */
787 mm_log((1, "i_flipxy: odd number of columns\n"));
790 for(y=0; y<ym; y++) {
792 i_gpix(im, x, y, &val1);
793 i_gpix(im, x, y2, &val2);
794 i_ppix(im, x, y, &val2);
795 i_ppix(im, x, y2, &val1);
799 if (ym*2 != ys) { /* odd number of rows */
800 mm_log((1, "i_flipxy: odd number of rows\n"));
803 for(x=0; x<xm; x++) {
805 i_gpix(im, x, y, &val1);
806 i_gpix(im, x2, y, &val2);
807 i_ppix(im, x, y, &val2);
808 i_ppix(im, x2, y, &val1);
814 mm_log((1, "i_flipxy: direction is invalid\n" ));
832 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
833 else if (x == 0.0) return (1.0);
834 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
839 =item i_scaleaxis(im, value, axis)
841 Returns a new image object which is I<im> scaled by I<value> along
842 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
848 i_scaleaxis(i_img *im, float Value, int Axis) {
849 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
850 int LanczosWidthFactor;
851 float *l0, *l1, OldLocation;
854 float F, PictureValue[MAXCHANNELS];
856 i_color val,val1,val2;
860 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
864 hsize = (int)(0.5 + im->xsize * Value);
867 Value = 1.0 / im->xsize;
875 vsize = (int)(0.5 + im->ysize * Value);
879 Value = 1.0 / im->ysize;
886 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
888 i_push_error(0, "cannot create output image");
892 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
893 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
894 lMax = LanczosWidthFactor << 1;
896 l0 = mymalloc(lMax * sizeof(float));
897 l1 = mymalloc(lMax * sizeof(float));
899 for (j=0; j<jEnd; j++) {
900 OldLocation = ((float) j) / Value;
901 T = (int) (OldLocation);
902 F = OldLocation - (float) T;
904 for (l = 0; l<lMax; l++) {
905 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
906 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
909 /* Make sure filter is normalized */
911 for(l=0; l<lMax; l++) {
915 t /= (float)LanczosWidthFactor;
917 for(l=0; l<lMax; l++) {
924 for (i=0; i<iEnd; i++) {
925 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
926 for (l=0; l<lMax; l++) {
929 mx = (mx < 0) ? 0 : mx;
930 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
932 i_gpix(im, Mx, i, &val1);
933 i_gpix(im, mx, i, &val2);
935 for (k=0; k<im->channels; k++) {
936 PictureValue[k] += l1[l] * val1.channel[k];
937 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
940 for(k=0;k<im->channels;k++) {
941 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
942 val.channel[k]=minmax(0,255,psave);
944 i_ppix(new_img, j, i, &val);
949 for (i=0; i<iEnd; i++) {
950 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
951 for (l=0; l < lMax; l++) {
954 mx = (mx < 0) ? 0 : mx;
955 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
957 i_gpix(im, i, Mx, &val1);
958 i_gpix(im, i, mx, &val2);
959 for (k=0; k<im->channels; k++) {
960 PictureValue[k] += l1[l] * val1.channel[k];
961 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
964 for (k=0; k<im->channels; k++) {
965 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
966 val.channel[k] = minmax(0, 255, psave);
968 i_ppix(new_img, i, j, &val);
976 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
983 =item i_scale_nn(im, scx, scy)
985 Scale by using nearest neighbor
986 Both axes scaled at the same time since
987 nothing is gained by doing it in two steps
994 i_scale_nn(i_img *im, float scx, float scy) {
996 int nxsize,nysize,nx,ny;
1000 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
1002 nxsize = (int) ((float) im->xsize * scx);
1005 scx = 1 / im->xsize;
1007 nysize = (int) ((float) im->ysize * scy);
1010 scy = 1 / im->ysize;
1013 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1015 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1016 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1017 i_ppix(new_img,nx,ny,&val);
1020 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1026 =item i_sametype(i_img *im, int xsize, int ysize)
1028 =category Image creation/destruction
1029 =synopsis i_img *img = i_sametype(src, width, height);
1031 Returns an image of the same type (sample size, channels, paletted/direct).
1033 For paletted images the palette is copied from the source.
1038 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1039 if (src->type == i_direct_type) {
1040 if (src->bits == 8) {
1041 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1043 else if (src->bits == i_16_bits) {
1044 return i_img_16_new(xsize, ysize, src->channels);
1046 else if (src->bits == i_double_bits) {
1047 return i_img_double_new(xsize, ysize, src->channels);
1050 i_push_error(0, "Unknown image bits");
1058 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1059 for (i = 0; i < i_colorcount(src); ++i) {
1060 i_getcolors(src, i, &col, 1);
1061 i_addcolors(targ, &col, 1);
1069 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1071 =category Image creation/destruction
1072 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
1074 Returns an image of the same type (sample size).
1076 For paletted images the equivalent direct type is returned.
1081 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1082 if (src->bits == 8) {
1083 return i_img_empty_ch(NULL, xsize, ysize, channels);
1085 else if (src->bits == i_16_bits) {
1086 return i_img_16_new(xsize, ysize, channels);
1088 else if (src->bits == i_double_bits) {
1089 return i_img_double_new(xsize, ysize, channels);
1092 i_push_error(0, "Unknown image bits");
1098 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1100 Spatially transforms I<im> returning a new image.
1102 opx for a length of opxl and opy for a length of opy are arrays of
1103 operators that modify the x and y positions to retreive the pixel data from.
1105 parm and parmlen define extra parameters that the operators may use.
1107 Note that this function is largely superseded by the more flexible
1108 L<transform.c/i_transform2>.
1110 Returns the new image.
1112 The operators for this function are defined in L<stackmach.c>.
1117 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1119 int nxsize,nysize,nx,ny;
1123 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));
1126 nysize = im->ysize ;
1128 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1129 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1130 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1131 /* parm[parmlen-2]=(double)nx;
1132 parm[parmlen-1]=(double)ny; */
1137 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1138 rx=i_op_run(opx,opxl,parm,parmlen);
1139 ry=i_op_run(opy,opyl,parm,parmlen);
1140 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1141 i_gpix(im,rx,ry,&val);
1142 i_ppix(new_img,nx,ny,&val);
1145 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1150 =item i_img_diff(im1, im2)
1152 Calculates the sum of the squares of the differences between
1153 correspoding channels in two images.
1155 If the images are not the same size then only the common area is
1156 compared, hence even if images are different sizes this function
1162 i_img_diff(i_img *im1,i_img *im2) {
1163 int x,y,ch,xb,yb,chb;
1167 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1169 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1170 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1171 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1173 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1176 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1177 i_gpix(im1,x,y,&val1);
1178 i_gpix(im2,x,y,&val2);
1180 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1182 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1186 /* just a tiny demo of haar wavelets */
1194 i_img *new_img,*new_img2;
1195 i_color val1,val2,dval1,dval2;
1203 /* horizontal pass */
1205 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1206 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1209 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1210 i_gpix(im,x*2,y,&val1);
1211 i_gpix(im,x*2+1,y,&val2);
1212 for(ch=0;ch<im->channels;ch++) {
1213 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1214 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1216 i_ppix(new_img,x,y,&dval1);
1217 i_ppix(new_img,x+fx,y,&dval2);
1220 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1221 i_gpix(new_img,x,y*2,&val1);
1222 i_gpix(new_img,x,y*2+1,&val2);
1223 for(ch=0;ch<im->channels;ch++) {
1224 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1225 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1227 i_ppix(new_img2,x,y,&dval1);
1228 i_ppix(new_img2,x,y+fy,&dval2);
1231 i_img_destroy(new_img);
1236 =item i_count_colors(im, maxc)
1238 returns number of colors or -1
1239 to indicate that it was more than max colors
1243 /* This function has been changed and is now faster. It's using
1244 * i_gsamp instead of i_gpix */
1246 i_count_colors(i_img *im,int maxc) {
1253 int xsize = im->xsize;
1254 int ysize = im->ysize;
1255 int samp_cnt = 3 * xsize;
1257 if (im->channels >= 3) {
1261 channels[0] = channels[1] = channels[2] = 0;
1262 samp_chans = channels;
1267 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1270 for(y = 0; y < ysize; ) {
1271 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1272 for(x = 0; x < samp_cnt; ) {
1273 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1275 if (colorcnt > maxc) {
1286 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1287 * (adapted from the Numerical Recipes)
1289 /* Needed by get_anonymous_color_histo */
1291 hpsort(unsigned int n, unsigned *ra) {
1316 if (j < ir && ra[j] < ra[j+1]) j++;
1328 /* This function constructs an ordered list which represents how much the
1329 * different colors are used. So for instance (100, 100, 500) means that one
1330 * color is used for 500 pixels, another for 100 pixels and another for 100
1331 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1332 * the maxc ;-) and you might want to change the name... */
1333 /* Uses octt_histo */
1335 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1339 unsigned int *col_usage_it;
1344 int xsize = im->xsize;
1345 int ysize = im->ysize;
1346 int samp_cnt = 3 * xsize;
1349 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1351 if (im->channels >= 3) {
1355 channels[0] = channels[1] = channels[2] = 0;
1356 samp_chans = channels;
1360 for(y = 0; y < ysize; ) {
1361 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1362 for(x = 0; x < samp_cnt; ) {
1363 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1365 if (colorcnt > maxc) {
1372 /* Now that we know the number of colours... */
1373 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1374 octt_histo(ct, &col_usage_it);
1375 hpsort(colorcnt, *col_usage);
1383 =head2 8-bit per sample image internal functions
1385 These are the functions installed in an 8-bit per sample image.
1389 =item i_ppix_d(im, x, y, col)
1393 This is the function kept in the i_f_ppix member of an i_img object.
1394 It does a normal store of a pixel into the image with range checking.
1396 Returns 0 if the pixel could be set, -1 otherwise.
1402 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1405 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1406 for(ch=0;ch<im->channels;ch++)
1407 if (im->ch_mask&(1<<ch))
1408 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1411 return -1; /* error was clipped */
1415 =item i_gpix_d(im, x, y, &col)
1419 This is the function kept in the i_f_gpix member of an i_img object.
1420 It does normal retrieval of a pixel from the image with range checking.
1422 Returns 0 if the pixel could be set, -1 otherwise.
1428 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1430 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1431 for(ch=0;ch<im->channels;ch++)
1432 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1435 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1436 return -1; /* error was cliped */
1440 =item i_glin_d(im, l, r, y, vals)
1442 Reads a line of data from the image, storing the pixels at vals.
1444 The line runs from (l,y) inclusive to (r,y) non-inclusive
1446 vals should point at space for (r-l) pixels.
1448 l should never be less than zero (to avoid confusion about where to
1449 put the pixels in vals).
1451 Returns the number of pixels copied (eg. if r, l or y is out of range)
1457 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1459 unsigned char *data;
1460 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1463 data = im->idata + (l+y*im->xsize) * im->channels;
1465 for (i = 0; i < count; ++i) {
1466 for (ch = 0; ch < im->channels; ++ch)
1467 vals[i].channel[ch] = *data++;
1477 =item i_plin_d(im, l, r, y, vals)
1479 Writes a line of data into the image, using the pixels at vals.
1481 The line runs from (l,y) inclusive to (r,y) non-inclusive
1483 vals should point at (r-l) pixels.
1485 l should never be less than zero (to avoid confusion about where to
1486 get the pixels in vals).
1488 Returns the number of pixels copied (eg. if r, l or y is out of range)
1494 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1496 unsigned char *data;
1497 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1500 data = im->idata + (l+y*im->xsize) * im->channels;
1502 for (i = 0; i < count; ++i) {
1503 for (ch = 0; ch < im->channels; ++ch) {
1504 if (im->ch_mask & (1 << ch))
1505 *data = vals[i].channel[ch];
1517 =item i_ppixf_d(im, x, y, val)
1523 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1526 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1527 for(ch=0;ch<im->channels;ch++)
1528 if (im->ch_mask&(1<<ch)) {
1529 im->idata[(x+y*im->xsize)*im->channels+ch] =
1530 SampleFTo8(val->channel[ch]);
1534 return -1; /* error was clipped */
1538 =item i_gpixf_d(im, x, y, val)
1544 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1546 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1547 for(ch=0;ch<im->channels;ch++) {
1549 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1553 return -1; /* error was cliped */
1557 =item i_glinf_d(im, l, r, y, vals)
1559 Reads a line of data from the image, storing the pixels at vals.
1561 The line runs from (l,y) inclusive to (r,y) non-inclusive
1563 vals should point at space for (r-l) pixels.
1565 l should never be less than zero (to avoid confusion about where to
1566 put the pixels in vals).
1568 Returns the number of pixels copied (eg. if r, l or y is out of range)
1574 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1576 unsigned char *data;
1577 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1580 data = im->idata + (l+y*im->xsize) * im->channels;
1582 for (i = 0; i < count; ++i) {
1583 for (ch = 0; ch < im->channels; ++ch)
1584 vals[i].channel[ch] = Sample8ToF(*data++);
1594 =item i_plinf_d(im, l, r, y, vals)
1596 Writes a line of data into the image, using the pixels at vals.
1598 The line runs from (l,y) inclusive to (r,y) non-inclusive
1600 vals should point at (r-l) pixels.
1602 l should never be less than zero (to avoid confusion about where to
1603 get the pixels in vals).
1605 Returns the number of pixels copied (eg. if r, l or y is out of range)
1611 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1613 unsigned char *data;
1614 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1617 data = im->idata + (l+y*im->xsize) * im->channels;
1619 for (i = 0; i < count; ++i) {
1620 for (ch = 0; ch < im->channels; ++ch) {
1621 if (im->ch_mask & (1 << ch))
1622 *data = SampleFTo8(vals[i].channel[ch]);
1634 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1636 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1637 for the channels specified by chans, an array of int with chan_count
1640 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1646 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1647 const int *chans, int chan_count) {
1648 int ch, count, i, w;
1649 unsigned char *data;
1651 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1654 data = im->idata + (l+y*im->xsize) * im->channels;
1659 /* make sure we have good channel numbers */
1660 for (ch = 0; ch < chan_count; ++ch) {
1661 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1662 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1666 for (i = 0; i < w; ++i) {
1667 for (ch = 0; ch < chan_count; ++ch) {
1668 *samps++ = data[chans[ch]];
1671 data += im->channels;
1675 if (chan_count <= 0 || chan_count > im->channels) {
1676 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1680 for (i = 0; i < w; ++i) {
1681 for (ch = 0; ch < chan_count; ++ch) {
1682 *samps++ = data[ch];
1685 data += im->channels;
1697 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1699 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1700 for the channels specified by chan_mask, where bit 0 is the first
1703 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1709 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1710 const int *chans, int chan_count) {
1711 int ch, count, i, w;
1712 unsigned char *data;
1713 for (ch = 0; ch < chan_count; ++ch) {
1714 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1715 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1718 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1721 data = im->idata + (l+y*im->xsize) * im->channels;
1726 /* make sure we have good channel numbers */
1727 for (ch = 0; ch < chan_count; ++ch) {
1728 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1729 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1733 for (i = 0; i < w; ++i) {
1734 for (ch = 0; ch < chan_count; ++ch) {
1735 *samps++ = Sample8ToF(data[chans[ch]]);
1738 data += im->channels;
1742 if (chan_count <= 0 || chan_count > im->channels) {
1743 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1747 for (i = 0; i < w; ++i) {
1748 for (ch = 0; ch < chan_count; ++ch) {
1749 *samps++ = Sample8ToF(data[ch]);
1752 data += im->channels;
1765 =head2 Image method wrappers
1767 These functions provide i_fsample_t functions in terms of their
1768 i_sample_t versions.
1772 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1777 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1781 for (ch = 0; ch < im->channels; ++ch)
1782 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1784 return i_ppix(im, x, y, &temp);
1788 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1792 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1796 if (i_gpix(im, x, y, &temp)) {
1797 for (ch = 0; ch < im->channels; ++ch)
1798 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1806 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1810 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1813 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1819 work = mymalloc(sizeof(i_color) * (r-l));
1820 for (i = 0; i < r-l; ++i) {
1821 for (ch = 0; ch < im->channels; ++ch)
1822 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1824 ret = i_plin(im, l, r, y, work);
1839 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1843 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1846 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1852 work = mymalloc(sizeof(i_color) * (r-l));
1853 ret = i_plin(im, l, r, y, work);
1854 for (i = 0; i < r-l; ++i) {
1855 for (ch = 0; ch < im->channels; ++ch)
1856 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1872 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1876 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1877 int const *chans, int chan_count) {
1880 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1886 work = mymalloc(sizeof(i_sample_t) * (r-l));
1887 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1888 for (i = 0; i < ret; ++i) {
1889 samp[i] = Sample8ToF(work[i]);
1907 =head2 Palette wrapper functions
1909 Used for virtual images, these forward palette calls to a wrapped image,
1910 assuming the wrapped image is the first pointer in the structure that
1911 im->ext_data points at.
1915 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1919 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1920 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1924 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1928 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1929 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1933 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1937 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1938 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1942 =item i_colorcount_forward(i_img *im)
1946 int i_colorcount_forward(i_img *im) {
1947 return i_colorcount(*(i_img **)im->ext_data);
1951 =item i_maxcolors_forward(i_img *im)
1955 int i_maxcolors_forward(i_img *im) {
1956 return i_maxcolors(*(i_img **)im->ext_data);
1960 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1964 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1965 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1971 =head2 Fallback handler
1975 =item i_gsamp_bits_fb
1981 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps,
1982 const int *chans, int chan_count, int bits) {
1983 if (bits < 1 || bits > 32) {
1984 i_push_error(0, "Invalid bits, must be 1..32");
1988 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1990 int ch, count, i, w;
1993 scale = 4294967295.0;
1995 scale = (double)(1 << bits) - 1;
2003 /* make sure we have good channel numbers */
2004 for (ch = 0; ch < chan_count; ++ch) {
2005 if (chans[ch] < 0 || chans[ch] >= im->channels) {
2006 i_push_errorf(0, "No channel %d in this image", chans[ch]);
2010 for (i = 0; i < w; ++i) {
2012 i_gpixf(im, l+i, y, &c);
2013 for (ch = 0; ch < chan_count; ++ch) {
2014 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2020 if (chan_count <= 0 || chan_count > im->channels) {
2021 i_push_error(0, "Invalid channel count");
2024 for (i = 0; i < w; ++i) {
2026 i_gpixf(im, l+i, y, &c);
2027 for (ch = 0; ch < chan_count; ++ch) {
2028 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2037 i_push_error(0, "Image position outside of image");
2045 =head2 Stream reading and writing wrapper functions
2049 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
2051 Performs general read buffering for file readers that permit reading
2052 to be done through a callback.
2054 The final callback gets two parameters, a I<need> value, and a I<want>
2055 value, where I<need> is the amount of data that the file library needs
2056 to read, and I<want> is the amount of space available in the buffer
2057 maintained by these functions.
2059 This means if you need to read from a stream that you don't know the
2060 length of, you can return I<need> bytes, taking the performance hit of
2061 possibly expensive callbacks (eg. back to perl code), or if you are
2062 reading from a stream where it doesn't matter if some data is lost, or
2063 if the total length of the stream is known, you can return I<want>
2070 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2073 if (length < gci->length - gci->cpos) {
2075 memcpy(buf, gci->buffer+gci->cpos, length);
2076 gci->cpos += length;
2081 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2082 total += gci->length - gci->cpos;
2083 length -= gci->length - gci->cpos;
2084 buf += gci->length - gci->cpos;
2085 if (length < (int)sizeof(gci->buffer)) {
2089 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
2090 sizeof(gci->buffer))) > 0) {
2092 gci->length = did_read;
2094 copy_size = i_min(length, gci->length);
2095 memcpy(buf, gci->buffer, copy_size);
2096 gci->cpos += copy_size;
2099 length -= copy_size;
2103 /* just read the rest - too big for our buffer*/
2105 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2115 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2117 For use by callback file readers to initialize the reader buffer.
2119 Allocates, initializes and returns the reader buffer.
2121 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2126 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2127 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2129 self->userdata = userdata;
2137 =item i_free_gen_read_data(i_gen_read_data *)
2143 void i_free_gen_read_data(i_gen_read_data *self) {
2148 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2150 Performs write buffering for a callback based file writer.
2152 Failures are considered fatal, if a write fails then data will be
2159 i_gen_write_data *self,
2163 if (self->filledto && self->filledto+size > self->maxlength) {
2164 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2172 if (self->filledto+size <= self->maxlength) {
2174 memcpy(self->buffer+self->filledto, data, size);
2175 self->filledto += size;
2178 /* doesn't fit - hand it off */
2179 return self->cb(self->userdata, data, size);
2183 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2185 Allocates and initializes the data structure used by i_gen_writer.
2187 This should be released with L<image.c/i_free_gen_write_data>
2191 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2192 char *userdata, int max_length)
2194 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2196 self->userdata = userdata;
2197 self->maxlength = i_min(max_length, sizeof(self->buffer));
2198 if (self->maxlength < 0)
2199 self->maxlength = sizeof(self->buffer);
2206 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2208 Cleans up the write buffer.
2210 Will flush any left-over data if I<flush> is non-zero.
2212 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2214 Return zero only if flush is non-zero and info->cb() returns zero.
2220 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2222 int result = !flush ||
2223 info->filledto == 0 ||
2224 info->cb(info->userdata, info->buffer, info->filledto);
2230 struct magic_entry {
2231 unsigned char *magic;
2234 unsigned char *mask;
2238 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2239 if (length < magic->magic_size)
2243 unsigned char *bufp = buffer,
2244 *maskp = magic->mask,
2245 *magicp = magic->magic;
2247 for (i = 0; i < magic->magic_size; ++i) {
2248 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2251 if ((*bufp++ & mask) != (*magicp++ & mask))
2258 return !memcmp(magic->magic, buffer, magic->magic_size);
2263 =item i_test_format_probe(io_glue *data, int length)
2265 Check the beginning of the supplied file for a 'magic number'
2270 #define FORMAT_ENTRY(magic, type) \
2271 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2272 #define FORMAT_ENTRY2(magic, type, mask) \
2273 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2276 i_test_format_probe(io_glue *data, int length) {
2277 static const struct magic_entry formats[] = {
2278 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2279 FORMAT_ENTRY("GIF87a", "gif"),
2280 FORMAT_ENTRY("GIF89a", "gif"),
2281 FORMAT_ENTRY("MM\0*", "tiff"),
2282 FORMAT_ENTRY("II*\0", "tiff"),
2283 FORMAT_ENTRY("BM", "bmp"),
2284 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2285 FORMAT_ENTRY("P1", "pnm"),
2286 FORMAT_ENTRY("P2", "pnm"),
2287 FORMAT_ENTRY("P3", "pnm"),
2288 FORMAT_ENTRY("P4", "pnm"),
2289 FORMAT_ENTRY("P5", "pnm"),
2290 FORMAT_ENTRY("P6", "pnm"),
2291 FORMAT_ENTRY("/* XPM", "xpm"),
2292 FORMAT_ENTRY("\x8aMNG", "mng"),
2293 FORMAT_ENTRY("\x8aJNG", "jng"),
2294 /* SGI RGB - with various possible parameters to avoid false positives
2296 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2298 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2299 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2300 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2301 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2303 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
2305 /* different versions of PCX format
2306 http://www.fileformat.info/format/pcx/
2308 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2309 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2310 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2311 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2312 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2314 /* FITS - http://fits.gsfc.nasa.gov/ */
2315 FORMAT_ENTRY("SIMPLE =", "fits"),
2317 /* PSD - Photoshop */
2318 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2320 /* EPS - Encapsulated Postscript */
2321 /* only reading 18 chars, so we don't include the F in EPSF */
2322 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2325 FORMAT_ENTRY("\x52\xCC", "utah"),
2327 /* GZIP compressed, only matching deflate for now */
2328 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2330 /* bzip2 compressed */
2331 FORMAT_ENTRY("BZh", "bzip2"),
2333 static const struct magic_entry more_formats[] = {
2334 /* these were originally both listed as ico, but cur files can
2335 include hotspot information */
2336 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2337 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2338 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
2339 "xwd", " xxxx"), /* X Windows Dump */
2343 unsigned char head[18];
2346 io_glue_commit_types(data);
2347 rc = data->readcb(data, head, 18);
2348 if (rc == -1) return NULL;
2349 data->seekcb(data, -rc, SEEK_CUR);
2351 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2352 struct magic_entry const *entry = formats + i;
2354 if (test_magic(head, rc, entry))
2359 tga_header_verify(head))
2362 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
2363 struct magic_entry const *entry = more_formats + i;
2365 if (test_magic(head, rc, entry))
2373 =item i_img_is_monochrome(img, &zero_is_white)
2375 Tests an image to check it meets our monochrome tests.
2377 The idea is that a file writer can use this to test where it should
2378 write the image in whatever bi-level format it uses, eg. pbm for pnm.
2380 For performance of encoders we require monochrome images:
2390 have a palette of two colors, containing only (0,0,0) and
2391 (255,255,255) in either order.
2395 zero_is_white is set to non-zero iff the first palette entry is white.
2401 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2402 if (im->type == i_palette_type
2403 && i_colorcount(im) == 2) {
2405 i_getcolors(im, 0, colors, 2);
2406 if (im->channels == 3) {
2407 if (colors[0].rgb.r == 255 &&
2408 colors[0].rgb.g == 255 &&
2409 colors[0].rgb.b == 255 &&
2410 colors[1].rgb.r == 0 &&
2411 colors[1].rgb.g == 0 &&
2412 colors[1].rgb.b == 0) {
2416 else if (colors[0].rgb.r == 0 &&
2417 colors[0].rgb.g == 0 &&
2418 colors[0].rgb.b == 0 &&
2419 colors[1].rgb.r == 255 &&
2420 colors[1].rgb.g == 255 &&
2421 colors[1].rgb.b == 255) {
2426 else if (im->channels == 1) {
2427 if (colors[0].channel[0] == 255 &&
2428 colors[1].channel[0] == 0) {
2432 else if (colors[0].channel[0] == 0 &&
2433 colors[1].channel[0] == 255) {
2445 =item i_get_file_background(im, &bg)
2447 Retrieve the file write background color tag from the image.
2449 If not present, returns black.
2455 i_get_file_background(i_img *im, i_color *bg) {
2456 if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
2458 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
2460 /* always full alpha */
2461 bg->channel[3] = 255;
2465 =item i_get_file_backgroundf(im, &bg)
2467 Retrieve the file write background color tag from the image as a
2468 floating point color.
2470 Implemented in terms of i_get_file_background().
2472 If not present, returns black.
2478 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
2481 i_get_file_background(im, &bg);
2482 fbg->rgba.r = Sample8ToF(bg.rgba.r);
2483 fbg->rgba.g = Sample8ToF(bg.rgba.g);
2484 fbg->rgba.b = Sample8ToF(bg.rgba.b);
2493 Arnar M. Hrafnkelsson <addi@umich.edu>
2495 Tony Cook <tony@develop-help.com>