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);
647 =item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
651 Copies image data from the area (x1,y1)-[x2,y2] in the source image to
652 a rectangle the same size with it's top-left corner at (tx,ty) in the
655 If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
661 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
662 int x, y, t, ttx, tty;
664 if (x2<x1) { t=x1; x1=x2; x2=t; }
665 if (y2<y1) { t=y1; y1=y2; y2=t; }
667 /* adjust everything equally */
677 if (x1 >= src->xsize || y1 >= src->ysize)
678 return; /* nothing to do */
683 if (x1 == x2 || y1 == y2)
684 return; /* nothing to do */
686 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
687 im, src, x1, y1, x2, y2, tx, ty));
689 if (im->bits == i_8_bits) {
690 i_color *row = mymalloc(sizeof(i_color) * (x2-x1));
692 for(y=y1; y<y2; y++) {
694 i_glin(src, x1, x2, y, row);
695 i_plin(im, tx, tx+x2-x1, tty, row);
703 for(y=y1; y<y2; y++) {
705 for(x=x1; x<x2; x++) {
706 i_gpixf(src, x, y, &pv);
707 i_ppixf(im, ttx, tty, &pv);
720 Creates a new image that is a copy of src.
722 Tags are not copied, only the image data.
732 i_img *im = i_sametype(src, src->xsize, src->ysize);
734 mm_log((1,"i_copy(src %p)\n", src));
741 if (src->type == i_direct_type) {
742 if (src->bits == i_8_bits) {
744 pv = mymalloc(sizeof(i_color) * x1);
746 for (y = 0; y < y1; ++y) {
747 i_glin(src, 0, x1, y, pv);
748 i_plin(im, 0, x1, y, pv);
755 pv = mymalloc(sizeof(i_fcolor) * x1);
756 for (y = 0; y < y1; ++y) {
757 i_glinf(src, 0, x1, y, pv);
758 i_plinf(im, 0, x1, y, pv);
766 vals = mymalloc(sizeof(i_palidx) * x1);
767 for (y = 0; y < y1; ++y) {
768 i_gpal(src, 0, x1, y, vals);
769 i_ppal(im, 0, x1, y, vals);
779 =item i_flipxy(im, axis)
781 Flips the image inplace around the axis specified.
782 Returns 0 if parameters are invalid.
785 axis - 0 = x, 1 = y, 2 = both
791 i_flipxy(i_img *im, int direction) {
792 int x, x2, y, y2, xm, ym;
796 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
801 case XAXIS: /* Horizontal flip */
804 for(y=0; y<ym; y++) {
806 for(x=0; x<xm; x++) {
808 i_gpix(im, x, y, &val1);
809 i_gpix(im, x2, y, &val2);
810 i_ppix(im, x, y, &val2);
811 i_ppix(im, x2, y, &val1);
816 case YAXIS: /* Vertical flip */
820 for(y=0; y<ym; y++) {
821 for(x=0; x<xm; x++) {
823 i_gpix(im, x, y, &val1);
824 i_gpix(im, x, y2, &val2);
825 i_ppix(im, x, y, &val2);
826 i_ppix(im, x, y2, &val1);
831 case XYAXIS: /* Horizontal and Vertical flip */
835 for(y=0; y<ym; y++) {
837 for(x=0; x<xm; x++) {
839 i_gpix(im, x, y, &val1);
840 i_gpix(im, x2, y2, &val2);
841 i_ppix(im, x, y, &val2);
842 i_ppix(im, x2, y2, &val1);
844 i_gpix(im, x2, y, &val1);
845 i_gpix(im, x, y2, &val2);
846 i_ppix(im, x2, y, &val2);
847 i_ppix(im, x, y2, &val1);
852 if (xm*2 != xs) { /* odd number of column */
853 mm_log((1, "i_flipxy: odd number of columns\n"));
856 for(y=0; y<ym; y++) {
858 i_gpix(im, x, y, &val1);
859 i_gpix(im, x, y2, &val2);
860 i_ppix(im, x, y, &val2);
861 i_ppix(im, x, y2, &val1);
865 if (ym*2 != ys) { /* odd number of rows */
866 mm_log((1, "i_flipxy: odd number of rows\n"));
869 for(x=0; x<xm; x++) {
871 i_gpix(im, x, y, &val1);
872 i_gpix(im, x2, y, &val2);
873 i_ppix(im, x, y, &val2);
874 i_ppix(im, x2, y, &val1);
880 mm_log((1, "i_flipxy: direction is invalid\n" ));
898 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
899 else if (x == 0.0) return (1.0);
900 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
905 =item i_scaleaxis(im, value, axis)
907 Returns a new image object which is I<im> scaled by I<value> along
908 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
914 i_scaleaxis(i_img *im, float Value, int Axis) {
915 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
916 int LanczosWidthFactor;
917 float *l0, *l1, OldLocation;
920 float F, PictureValue[MAXCHANNELS];
922 i_color val,val1,val2;
925 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
929 hsize = (int)(0.5 + im->xsize * Value);
932 Value = 1.0 / im->xsize;
940 vsize = (int)(0.5 + im->ysize * Value);
944 Value = 1.0 / im->ysize;
951 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
953 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
954 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
955 lMax = LanczosWidthFactor << 1;
957 l0 = mymalloc(lMax * sizeof(float));
958 l1 = mymalloc(lMax * sizeof(float));
960 for (j=0; j<jEnd; j++) {
961 OldLocation = ((float) j) / Value;
962 T = (int) (OldLocation);
963 F = OldLocation - (float) T;
965 for (l = 0; l<lMax; l++) {
966 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
967 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
970 /* Make sure filter is normalized */
972 for(l=0; l<lMax; l++) {
976 t /= (float)LanczosWidthFactor;
978 for(l=0; l<lMax; l++) {
985 for (i=0; i<iEnd; i++) {
986 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
987 for (l=0; l<lMax; l++) {
990 mx = (mx < 0) ? 0 : mx;
991 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
993 i_gpix(im, Mx, i, &val1);
994 i_gpix(im, mx, i, &val2);
996 for (k=0; k<im->channels; k++) {
997 PictureValue[k] += l1[l] * val1.channel[k];
998 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
1001 for(k=0;k<im->channels;k++) {
1002 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
1003 val.channel[k]=minmax(0,255,psave);
1005 i_ppix(new_img, j, i, &val);
1010 for (i=0; i<iEnd; i++) {
1011 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
1012 for (l=0; l < lMax; l++) {
1013 int mx = T-lMax+l+1;
1015 mx = (mx < 0) ? 0 : mx;
1016 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
1018 i_gpix(im, i, Mx, &val1);
1019 i_gpix(im, i, mx, &val2);
1020 for (k=0; k<im->channels; k++) {
1021 PictureValue[k] += l1[l] * val1.channel[k];
1022 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
1025 for (k=0; k<im->channels; k++) {
1026 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
1027 val.channel[k] = minmax(0, 255, psave);
1029 i_ppix(new_img, i, j, &val);
1037 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
1044 =item i_scale_nn(im, scx, scy)
1046 Scale by using nearest neighbor
1047 Both axes scaled at the same time since
1048 nothing is gained by doing it in two steps
1055 i_scale_nn(i_img *im, float scx, float scy) {
1057 int nxsize,nysize,nx,ny;
1061 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
1063 nxsize = (int) ((float) im->xsize * scx);
1066 scx = 1 / im->xsize;
1068 nysize = (int) ((float) im->ysize * scy);
1071 scy = 1 / im->ysize;
1074 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1076 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1077 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1078 i_ppix(new_img,nx,ny,&val);
1081 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1087 =item i_sametype(i_img *im, int xsize, int ysize)
1089 =category Image creation/destruction
1090 =synopsis i_img *img = i_sametype(src, width, height);
1092 Returns an image of the same type (sample size, channels, paletted/direct).
1094 For paletted images the palette is copied from the source.
1099 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1100 if (src->type == i_direct_type) {
1101 if (src->bits == 8) {
1102 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1104 else if (src->bits == i_16_bits) {
1105 return i_img_16_new(xsize, ysize, src->channels);
1107 else if (src->bits == i_double_bits) {
1108 return i_img_double_new(xsize, ysize, src->channels);
1111 i_push_error(0, "Unknown image bits");
1119 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1120 for (i = 0; i < i_colorcount(src); ++i) {
1121 i_getcolors(src, i, &col, 1);
1122 i_addcolors(targ, &col, 1);
1130 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1132 =category Image creation/destruction
1133 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
1135 Returns an image of the same type (sample size).
1137 For paletted images the equivalent direct type is returned.
1142 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1143 if (src->bits == 8) {
1144 return i_img_empty_ch(NULL, xsize, ysize, channels);
1146 else if (src->bits == i_16_bits) {
1147 return i_img_16_new(xsize, ysize, channels);
1149 else if (src->bits == i_double_bits) {
1150 return i_img_double_new(xsize, ysize, channels);
1153 i_push_error(0, "Unknown image bits");
1159 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1161 Spatially transforms I<im> returning a new image.
1163 opx for a length of opxl and opy for a length of opy are arrays of
1164 operators that modify the x and y positions to retreive the pixel data from.
1166 parm and parmlen define extra parameters that the operators may use.
1168 Note that this function is largely superseded by the more flexible
1169 L<transform.c/i_transform2>.
1171 Returns the new image.
1173 The operators for this function are defined in L<stackmach.c>.
1178 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1180 int nxsize,nysize,nx,ny;
1184 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));
1187 nysize = im->ysize ;
1189 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1190 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1191 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1192 /* parm[parmlen-2]=(double)nx;
1193 parm[parmlen-1]=(double)ny; */
1198 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1199 rx=i_op_run(opx,opxl,parm,parmlen);
1200 ry=i_op_run(opy,opyl,parm,parmlen);
1201 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1202 i_gpix(im,rx,ry,&val);
1203 i_ppix(new_img,nx,ny,&val);
1206 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1211 =item i_img_diff(im1, im2)
1213 Calculates the sum of the squares of the differences between
1214 correspoding channels in two images.
1216 If the images are not the same size then only the common area is
1217 compared, hence even if images are different sizes this function
1223 i_img_diff(i_img *im1,i_img *im2) {
1224 int x,y,ch,xb,yb,chb;
1228 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1230 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1231 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1232 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1234 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1237 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1238 i_gpix(im1,x,y,&val1);
1239 i_gpix(im2,x,y,&val2);
1241 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1243 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1247 /* just a tiny demo of haar wavelets */
1255 i_img *new_img,*new_img2;
1256 i_color val1,val2,dval1,dval2;
1264 /* horizontal pass */
1266 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1267 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1270 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1271 i_gpix(im,x*2,y,&val1);
1272 i_gpix(im,x*2+1,y,&val2);
1273 for(ch=0;ch<im->channels;ch++) {
1274 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1275 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1277 i_ppix(new_img,x,y,&dval1);
1278 i_ppix(new_img,x+fx,y,&dval2);
1281 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1282 i_gpix(new_img,x,y*2,&val1);
1283 i_gpix(new_img,x,y*2+1,&val2);
1284 for(ch=0;ch<im->channels;ch++) {
1285 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1286 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1288 i_ppix(new_img2,x,y,&dval1);
1289 i_ppix(new_img2,x,y+fy,&dval2);
1292 i_img_destroy(new_img);
1297 =item i_count_colors(im, maxc)
1299 returns number of colors or -1
1300 to indicate that it was more than max colors
1304 /* This function has been changed and is now faster. It's using
1305 * i_gsamp instead of i_gpix */
1307 i_count_colors(i_img *im,int maxc) {
1314 int xsize = im->xsize;
1315 int ysize = im->ysize;
1316 int samp_cnt = 3 * xsize;
1318 if (im->channels >= 3) {
1322 channels[0] = channels[1] = channels[2] = 0;
1323 samp_chans = channels;
1328 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1331 for(y = 0; y < ysize; ) {
1332 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1333 for(x = 0; x < samp_cnt; ) {
1334 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1336 if (colorcnt > maxc) {
1347 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1348 * (adapted from the Numerical Recipes)
1350 /* Needed by get_anonymous_color_histo */
1352 hpsort(unsigned int n, unsigned *ra) {
1377 if (j < ir && ra[j] < ra[j+1]) j++;
1389 /* This function constructs an ordered list which represents how much the
1390 * different colors are used. So for instance (100, 100, 500) means that one
1391 * color is used for 500 pixels, another for 100 pixels and another for 100
1392 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1393 * the maxc ;-) and you might want to change the name... */
1394 /* Uses octt_histo */
1396 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1400 unsigned int *col_usage_it;
1405 int xsize = im->xsize;
1406 int ysize = im->ysize;
1407 int samp_cnt = 3 * xsize;
1410 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1412 if (im->channels >= 3) {
1416 channels[0] = channels[1] = channels[2] = 0;
1417 samp_chans = channels;
1421 for(y = 0; y < ysize; ) {
1422 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1423 for(x = 0; x < samp_cnt; ) {
1424 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1426 if (colorcnt > maxc) {
1433 /* Now that we know the number of colours... */
1434 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1435 octt_histo(ct, &col_usage_it);
1436 hpsort(colorcnt, *col_usage);
1444 =head2 8-bit per sample image internal functions
1446 These are the functions installed in an 8-bit per sample image.
1450 =item i_ppix_d(im, x, y, col)
1454 This is the function kept in the i_f_ppix member of an i_img object.
1455 It does a normal store of a pixel into the image with range checking.
1457 Returns 0 if the pixel could be set, -1 otherwise.
1463 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1466 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1467 for(ch=0;ch<im->channels;ch++)
1468 if (im->ch_mask&(1<<ch))
1469 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1472 return -1; /* error was clipped */
1476 =item i_gpix_d(im, x, y, &col)
1480 This is the function kept in the i_f_gpix member of an i_img object.
1481 It does normal retrieval of a pixel from the image with range checking.
1483 Returns 0 if the pixel could be set, -1 otherwise.
1489 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1491 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1492 for(ch=0;ch<im->channels;ch++)
1493 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1496 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1497 return -1; /* error was cliped */
1501 =item i_glin_d(im, l, r, y, vals)
1503 Reads a line of data from the image, storing the pixels at vals.
1505 The line runs from (l,y) inclusive to (r,y) non-inclusive
1507 vals should point at space for (r-l) pixels.
1509 l should never be less than zero (to avoid confusion about where to
1510 put the pixels in vals).
1512 Returns the number of pixels copied (eg. if r, l or y is out of range)
1518 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1520 unsigned char *data;
1521 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1524 data = im->idata + (l+y*im->xsize) * im->channels;
1526 for (i = 0; i < count; ++i) {
1527 for (ch = 0; ch < im->channels; ++ch)
1528 vals[i].channel[ch] = *data++;
1538 =item i_plin_d(im, l, r, y, vals)
1540 Writes a line of data into the image, using the pixels at vals.
1542 The line runs from (l,y) inclusive to (r,y) non-inclusive
1544 vals should point at (r-l) pixels.
1546 l should never be less than zero (to avoid confusion about where to
1547 get the pixels in vals).
1549 Returns the number of pixels copied (eg. if r, l or y is out of range)
1555 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1557 unsigned char *data;
1558 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1561 data = im->idata + (l+y*im->xsize) * im->channels;
1563 for (i = 0; i < count; ++i) {
1564 for (ch = 0; ch < im->channels; ++ch) {
1565 if (im->ch_mask & (1 << ch))
1566 *data = vals[i].channel[ch];
1578 =item i_ppixf_d(im, x, y, val)
1584 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1587 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1588 for(ch=0;ch<im->channels;ch++)
1589 if (im->ch_mask&(1<<ch)) {
1590 im->idata[(x+y*im->xsize)*im->channels+ch] =
1591 SampleFTo8(val->channel[ch]);
1595 return -1; /* error was clipped */
1599 =item i_gpixf_d(im, x, y, val)
1605 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1607 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1608 for(ch=0;ch<im->channels;ch++) {
1610 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1614 return -1; /* error was cliped */
1618 =item i_glinf_d(im, l, r, y, vals)
1620 Reads a line of data from the image, storing the pixels at vals.
1622 The line runs from (l,y) inclusive to (r,y) non-inclusive
1624 vals should point at space for (r-l) pixels.
1626 l should never be less than zero (to avoid confusion about where to
1627 put the pixels in vals).
1629 Returns the number of pixels copied (eg. if r, l or y is out of range)
1635 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1637 unsigned char *data;
1638 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1641 data = im->idata + (l+y*im->xsize) * im->channels;
1643 for (i = 0; i < count; ++i) {
1644 for (ch = 0; ch < im->channels; ++ch)
1645 vals[i].channel[ch] = Sample8ToF(*data++);
1655 =item i_plinf_d(im, l, r, y, vals)
1657 Writes a line of data into the image, using the pixels at vals.
1659 The line runs from (l,y) inclusive to (r,y) non-inclusive
1661 vals should point at (r-l) pixels.
1663 l should never be less than zero (to avoid confusion about where to
1664 get the pixels in vals).
1666 Returns the number of pixels copied (eg. if r, l or y is out of range)
1672 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1674 unsigned char *data;
1675 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1678 data = im->idata + (l+y*im->xsize) * im->channels;
1680 for (i = 0; i < count; ++i) {
1681 for (ch = 0; ch < im->channels; ++ch) {
1682 if (im->ch_mask & (1 << ch))
1683 *data = SampleFTo8(vals[i].channel[ch]);
1695 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1697 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1698 for the channels specified by chans, an array of int with chan_count
1701 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1707 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1708 const int *chans, int chan_count) {
1709 int ch, count, i, w;
1710 unsigned char *data;
1712 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1715 data = im->idata + (l+y*im->xsize) * im->channels;
1720 /* make sure we have good channel numbers */
1721 for (ch = 0; ch < chan_count; ++ch) {
1722 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1723 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1727 for (i = 0; i < w; ++i) {
1728 for (ch = 0; ch < chan_count; ++ch) {
1729 *samps++ = data[chans[ch]];
1732 data += im->channels;
1736 if (chan_count <= 0 || chan_count > im->channels) {
1737 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1741 for (i = 0; i < w; ++i) {
1742 for (ch = 0; ch < chan_count; ++ch) {
1743 *samps++ = data[ch];
1746 data += im->channels;
1758 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1760 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1761 for the channels specified by chan_mask, where bit 0 is the first
1764 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1770 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1771 const int *chans, int chan_count) {
1772 int ch, count, i, w;
1773 unsigned char *data;
1774 for (ch = 0; ch < chan_count; ++ch) {
1775 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1776 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1779 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1782 data = im->idata + (l+y*im->xsize) * im->channels;
1787 /* make sure we have good channel numbers */
1788 for (ch = 0; ch < chan_count; ++ch) {
1789 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1790 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1794 for (i = 0; i < w; ++i) {
1795 for (ch = 0; ch < chan_count; ++ch) {
1796 *samps++ = Sample8ToF(data[chans[ch]]);
1799 data += im->channels;
1803 if (chan_count <= 0 || chan_count > im->channels) {
1804 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1808 for (i = 0; i < w; ++i) {
1809 for (ch = 0; ch < chan_count; ++ch) {
1810 *samps++ = Sample8ToF(data[ch]);
1813 data += im->channels;
1826 =head2 Image method wrappers
1828 These functions provide i_fsample_t functions in terms of their
1829 i_sample_t versions.
1833 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1838 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1842 for (ch = 0; ch < im->channels; ++ch)
1843 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1845 return i_ppix(im, x, y, &temp);
1849 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1853 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1857 if (i_gpix(im, x, y, &temp)) {
1858 for (ch = 0; ch < im->channels; ++ch)
1859 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1867 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1871 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1874 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1880 work = mymalloc(sizeof(i_color) * (r-l));
1881 for (i = 0; i < r-l; ++i) {
1882 for (ch = 0; ch < im->channels; ++ch)
1883 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1885 ret = i_plin(im, l, r, y, work);
1900 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1904 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1907 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1913 work = mymalloc(sizeof(i_color) * (r-l));
1914 ret = i_plin(im, l, r, y, work);
1915 for (i = 0; i < r-l; ++i) {
1916 for (ch = 0; ch < im->channels; ++ch)
1917 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1933 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1937 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1938 int const *chans, int chan_count) {
1941 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1947 work = mymalloc(sizeof(i_sample_t) * (r-l));
1948 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1949 for (i = 0; i < ret; ++i) {
1950 samp[i] = Sample8ToF(work[i]);
1968 =head2 Palette wrapper functions
1970 Used for virtual images, these forward palette calls to a wrapped image,
1971 assuming the wrapped image is the first pointer in the structure that
1972 im->ext_data points at.
1976 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1980 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1981 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1985 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1989 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1990 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1994 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1998 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1999 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
2003 =item i_colorcount_forward(i_img *im)
2007 int i_colorcount_forward(i_img *im) {
2008 return i_colorcount(*(i_img **)im->ext_data);
2012 =item i_maxcolors_forward(i_img *im)
2016 int i_maxcolors_forward(i_img *im) {
2017 return i_maxcolors(*(i_img **)im->ext_data);
2021 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
2025 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
2026 return i_findcolor(*(i_img **)im->ext_data, color, entry);
2032 =head2 Fallback handler
2036 =item i_gsamp_bits_fb
2042 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps,
2043 const int *chans, int chan_count, int bits) {
2044 if (bits < 1 || bits > 32) {
2045 i_push_error(0, "Invalid bits, must be 1..32");
2049 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
2051 int ch, count, i, w;
2054 scale = 4294967295.0;
2056 scale = (double)(1 << bits) - 1;
2064 /* make sure we have good channel numbers */
2065 for (ch = 0; ch < chan_count; ++ch) {
2066 if (chans[ch] < 0 || chans[ch] >= im->channels) {
2067 i_push_errorf(0, "No channel %d in this image", chans[ch]);
2071 for (i = 0; i < w; ++i) {
2073 i_gpixf(im, l+i, y, &c);
2074 for (ch = 0; ch < chan_count; ++ch) {
2075 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2081 if (chan_count <= 0 || chan_count > im->channels) {
2082 i_push_error(0, "Invalid channel count");
2085 for (i = 0; i < w; ++i) {
2087 i_gpixf(im, l+i, y, &c);
2088 for (ch = 0; ch < chan_count; ++ch) {
2089 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2098 i_push_error(0, "Image position outside of image");
2106 =head2 Stream reading and writing wrapper functions
2110 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
2112 Performs general read buffering for file readers that permit reading
2113 to be done through a callback.
2115 The final callback gets two parameters, a I<need> value, and a I<want>
2116 value, where I<need> is the amount of data that the file library needs
2117 to read, and I<want> is the amount of space available in the buffer
2118 maintained by these functions.
2120 This means if you need to read from a stream that you don't know the
2121 length of, you can return I<need> bytes, taking the performance hit of
2122 possibly expensive callbacks (eg. back to perl code), or if you are
2123 reading from a stream where it doesn't matter if some data is lost, or
2124 if the total length of the stream is known, you can return I<want>
2131 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2134 if (length < gci->length - gci->cpos) {
2136 memcpy(buf, gci->buffer+gci->cpos, length);
2137 gci->cpos += length;
2142 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2143 total += gci->length - gci->cpos;
2144 length -= gci->length - gci->cpos;
2145 buf += gci->length - gci->cpos;
2146 if (length < (int)sizeof(gci->buffer)) {
2150 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
2151 sizeof(gci->buffer))) > 0) {
2153 gci->length = did_read;
2155 copy_size = i_min(length, gci->length);
2156 memcpy(buf, gci->buffer, copy_size);
2157 gci->cpos += copy_size;
2160 length -= copy_size;
2164 /* just read the rest - too big for our buffer*/
2166 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2176 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2178 For use by callback file readers to initialize the reader buffer.
2180 Allocates, initializes and returns the reader buffer.
2182 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2187 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2188 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2190 self->userdata = userdata;
2198 =item i_free_gen_read_data(i_gen_read_data *)
2204 void i_free_gen_read_data(i_gen_read_data *self) {
2209 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2211 Performs write buffering for a callback based file writer.
2213 Failures are considered fatal, if a write fails then data will be
2220 i_gen_write_data *self,
2224 if (self->filledto && self->filledto+size > self->maxlength) {
2225 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2233 if (self->filledto+size <= self->maxlength) {
2235 memcpy(self->buffer+self->filledto, data, size);
2236 self->filledto += size;
2239 /* doesn't fit - hand it off */
2240 return self->cb(self->userdata, data, size);
2244 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2246 Allocates and initializes the data structure used by i_gen_writer.
2248 This should be released with L<image.c/i_free_gen_write_data>
2252 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2253 char *userdata, int max_length)
2255 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2257 self->userdata = userdata;
2258 self->maxlength = i_min(max_length, sizeof(self->buffer));
2259 if (self->maxlength < 0)
2260 self->maxlength = sizeof(self->buffer);
2267 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2269 Cleans up the write buffer.
2271 Will flush any left-over data if I<flush> is non-zero.
2273 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2275 Return zero only if flush is non-zero and info->cb() returns zero.
2281 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2283 int result = !flush ||
2284 info->filledto == 0 ||
2285 info->cb(info->userdata, info->buffer, info->filledto);
2291 struct magic_entry {
2292 unsigned char *magic;
2295 unsigned char *mask;
2299 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2300 if (length < magic->magic_size)
2304 unsigned char *bufp = buffer,
2305 *maskp = magic->mask,
2306 *magicp = magic->magic;
2308 for (i = 0; i < magic->magic_size; ++i) {
2309 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2312 if ((*bufp++ & mask) != (*magicp++ & mask))
2319 return !memcmp(magic->magic, buffer, magic->magic_size);
2324 =item i_test_format_probe(io_glue *data, int length)
2326 Check the beginning of the supplied file for a 'magic number'
2331 #define FORMAT_ENTRY(magic, type) \
2332 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2333 #define FORMAT_ENTRY2(magic, type, mask) \
2334 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2337 i_test_format_probe(io_glue *data, int length) {
2338 static const struct magic_entry formats[] = {
2339 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2340 FORMAT_ENTRY("GIF87a", "gif"),
2341 FORMAT_ENTRY("GIF89a", "gif"),
2342 FORMAT_ENTRY("MM\0*", "tiff"),
2343 FORMAT_ENTRY("II*\0", "tiff"),
2344 FORMAT_ENTRY("BM", "bmp"),
2345 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2346 FORMAT_ENTRY("P1", "pnm"),
2347 FORMAT_ENTRY("P2", "pnm"),
2348 FORMAT_ENTRY("P3", "pnm"),
2349 FORMAT_ENTRY("P4", "pnm"),
2350 FORMAT_ENTRY("P5", "pnm"),
2351 FORMAT_ENTRY("P6", "pnm"),
2352 FORMAT_ENTRY("/* XPM", "xpm"),
2353 FORMAT_ENTRY("\x8aMNG", "mng"),
2354 FORMAT_ENTRY("\x8aJNG", "jng"),
2355 /* SGI RGB - with various possible parameters to avoid false positives
2357 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2359 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2360 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2361 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2362 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2364 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
2366 /* different versions of PCX format
2367 http://www.fileformat.info/format/pcx/
2369 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2370 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2371 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2372 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2373 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2375 /* FITS - http://fits.gsfc.nasa.gov/ */
2376 FORMAT_ENTRY("SIMPLE =", "fits"),
2378 /* PSD - Photoshop */
2379 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2381 /* EPS - Encapsulated Postscript */
2382 /* only reading 18 chars, so we don't include the F in EPSF */
2383 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2386 FORMAT_ENTRY("\x52\xCC", "utah"),
2388 /* GZIP compressed, only matching deflate for now */
2389 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2391 /* bzip2 compressed */
2392 FORMAT_ENTRY("BZh", "bzip2"),
2394 static const struct magic_entry more_formats[] = {
2395 /* these were originally both listed as ico, but cur files can
2396 include hotspot information */
2397 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2398 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2399 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
2400 "xwd", " xxxx"), /* X Windows Dump */
2404 unsigned char head[18];
2407 io_glue_commit_types(data);
2408 rc = data->readcb(data, head, 18);
2409 if (rc == -1) return NULL;
2410 data->seekcb(data, -rc, SEEK_CUR);
2412 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2413 struct magic_entry const *entry = formats + i;
2415 if (test_magic(head, rc, entry))
2420 tga_header_verify(head))
2423 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
2424 struct magic_entry const *entry = more_formats + i;
2426 if (test_magic(head, rc, entry))
2434 =item i_img_is_monochrome(img, &zero_is_white)
2436 Tests an image to check it meets our monochrome tests.
2438 The idea is that a file writer can use this to test where it should
2439 write the image in whatever bi-level format it uses, eg. pbm for pnm.
2441 For performance of encoders we require monochrome images:
2451 have a palette of two colors, containing only (0,0,0) and
2452 (255,255,255) in either order.
2456 zero_is_white is set to non-zero iff the first palette entry is white.
2462 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2463 if (im->type == i_palette_type
2464 && i_colorcount(im) == 2) {
2466 i_getcolors(im, 0, colors, 2);
2467 if (im->channels == 3) {
2468 if (colors[0].rgb.r == 255 &&
2469 colors[0].rgb.g == 255 &&
2470 colors[0].rgb.b == 255 &&
2471 colors[1].rgb.r == 0 &&
2472 colors[1].rgb.g == 0 &&
2473 colors[1].rgb.b == 0) {
2477 else if (colors[0].rgb.r == 0 &&
2478 colors[0].rgb.g == 0 &&
2479 colors[0].rgb.b == 0 &&
2480 colors[1].rgb.r == 255 &&
2481 colors[1].rgb.g == 255 &&
2482 colors[1].rgb.b == 255) {
2487 else if (im->channels == 1) {
2488 if (colors[0].channel[0] == 255 &&
2489 colors[1].channel[0] == 0) {
2493 else if (colors[0].channel[0] == 0 &&
2494 colors[1].channel[0] == 255) {
2510 Arnar M. Hrafnkelsson <addi@umich.edu>
2512 Tony Cook <tony@develop-help.com>