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));
89 =item i_img_init(C<img>)
90 =category Image Implementation
92 Imager internal 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(C<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(C<im>, C<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 C<im> to C<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(C<im>)
557 =category Image Information
558 =synopsis int mask = i_img_getmask(img);
560 Get the image channel mask for C<im>.
565 i_img_getmask(i_img *im) { return im->ch_mask; }
568 =item i_img_getchannels(C<im>)
569 =category Image Information
570 =synopsis int channels = i_img_getchannels(img);
572 Get the number of channels in C<im>.
577 i_img_getchannels(i_img *im) { return im->channels; }
580 =item i_img_get_width(C<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(C<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(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
612 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
613 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
614 the target image. pass NULL in C<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 the image C<source>.
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);
724 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
725 else if (x == 0.0) return (1.0);
726 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
731 =item i_scaleaxis(im, value, axis)
733 Returns a new image object which is I<im> scaled by I<value> along
734 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
740 i_scaleaxis(i_img *im, float Value, int Axis) {
741 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
742 int LanczosWidthFactor;
743 float *l0, *l1, OldLocation;
746 float F, PictureValue[MAXCHANNELS];
748 i_color val,val1,val2;
750 int has_alpha = i_img_has_alpha(im);
751 int color_chans = i_img_color_channels(im);
754 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
757 hsize = (int)(0.5 + im->xsize * Value);
760 Value = 1.0 / im->xsize;
768 vsize = (int)(0.5 + im->ysize * Value);
772 Value = 1.0 / im->ysize;
779 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
781 i_push_error(0, "cannot create output image");
785 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
786 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
787 lMax = LanczosWidthFactor << 1;
789 l0 = mymalloc(lMax * sizeof(float));
790 l1 = mymalloc(lMax * sizeof(float));
792 for (j=0; j<jEnd; j++) {
793 OldLocation = ((float) j) / Value;
794 T = (int) (OldLocation);
795 F = OldLocation - (float) T;
797 for (l = 0; l<lMax; l++) {
798 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
799 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
802 /* Make sure filter is normalized */
804 for(l=0; l<lMax; l++) {
808 t /= (float)LanczosWidthFactor;
810 for(l=0; l<lMax; l++) {
817 for (i=0; i<iEnd; i++) {
818 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
819 for (l=0; l<lMax; l++) {
822 mx = (mx < 0) ? 0 : mx;
823 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
825 i_gpix(im, Mx, i, &val1);
826 i_gpix(im, mx, i, &val2);
829 i_sample_t alpha1 = val1.channel[color_chans];
830 i_sample_t alpha2 = val2.channel[color_chans];
831 for (k=0; k < color_chans; k++) {
832 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
833 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
835 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
836 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
839 for (k=0; k<im->channels; k++) {
840 PictureValue[k] += l1[l] * val1.channel[k];
841 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
847 float fa = PictureValue[color_chans] / LanczosWidthFactor;
848 int alpha = minmax(0, 255, fa+0.5);
850 for (k = 0; k < color_chans; ++k) {
851 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
852 val.channel[k]=minmax(0,255,psave);
854 val.channel[color_chans] = alpha;
857 /* zero alpha, so the pixel has no color */
858 for (k = 0; k < im->channels; ++k)
863 for(k=0;k<im->channels;k++) {
864 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
865 val.channel[k]=minmax(0,255,psave);
868 i_ppix(new_img, j, i, &val);
873 for (i=0; i<iEnd; i++) {
874 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
875 for (l=0; l < lMax; l++) {
878 mx = (mx < 0) ? 0 : mx;
879 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
881 i_gpix(im, i, Mx, &val1);
882 i_gpix(im, i, mx, &val2);
884 i_sample_t alpha1 = val1.channel[color_chans];
885 i_sample_t alpha2 = val2.channel[color_chans];
886 for (k=0; k < color_chans; k++) {
887 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
888 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
890 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
891 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
894 for (k=0; k<im->channels; k++) {
895 PictureValue[k] += l1[l] * val1.channel[k];
896 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
901 float fa = PictureValue[color_chans] / LanczosWidthFactor;
902 int alpha = minmax(0, 255, fa+0.5);
904 for (k = 0; k < color_chans; ++k) {
905 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
906 val.channel[k]=minmax(0,255,psave);
908 val.channel[color_chans] = alpha;
911 for (k = 0; k < im->channels; ++k)
916 for(k=0;k<im->channels;k++) {
917 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
918 val.channel[k]=minmax(0,255,psave);
921 i_ppix(new_img, i, j, &val);
929 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
936 =item i_scale_nn(im, scx, scy)
938 Scale by using nearest neighbor
939 Both axes scaled at the same time since
940 nothing is gained by doing it in two steps
947 i_scale_nn(i_img *im, float scx, float scy) {
949 int nxsize,nysize,nx,ny;
953 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
955 nxsize = (int) ((float) im->xsize * scx);
958 scx = 1.0 / im->xsize;
960 nysize = (int) ((float) im->ysize * scy);
963 scy = 1.0 / im->ysize;
965 im_assert(scx != 0 && scy != 0);
967 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
969 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
970 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
971 i_ppix(new_img,nx,ny,&val);
974 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
980 =item i_sametype(C<im>, C<xsize>, C<ysize>)
982 =category Image creation/destruction
983 =synopsis i_img *img = i_sametype(src, width, height);
985 Returns an image of the same type (sample size, channels, paletted/direct).
987 For paletted images the palette is copied from the source.
992 i_img *i_sametype(i_img *src, int xsize, int ysize) {
993 if (src->type == i_direct_type) {
994 if (src->bits == 8) {
995 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
997 else if (src->bits == i_16_bits) {
998 return i_img_16_new(xsize, ysize, src->channels);
1000 else if (src->bits == i_double_bits) {
1001 return i_img_double_new(xsize, ysize, src->channels);
1004 i_push_error(0, "Unknown image bits");
1012 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1013 for (i = 0; i < i_colorcount(src); ++i) {
1014 i_getcolors(src, i, &col, 1);
1015 i_addcolors(targ, &col, 1);
1023 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
1025 =category Image creation/destruction
1026 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
1028 Returns an image of the same type (sample size).
1030 For paletted images the equivalent direct type is returned.
1035 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1036 if (src->bits == 8) {
1037 return i_img_empty_ch(NULL, xsize, ysize, channels);
1039 else if (src->bits == i_16_bits) {
1040 return i_img_16_new(xsize, ysize, channels);
1042 else if (src->bits == i_double_bits) {
1043 return i_img_double_new(xsize, ysize, channels);
1046 i_push_error(0, "Unknown image bits");
1052 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1054 Spatially transforms I<im> returning a new image.
1056 opx for a length of opxl and opy for a length of opy are arrays of
1057 operators that modify the x and y positions to retreive the pixel data from.
1059 parm and parmlen define extra parameters that the operators may use.
1061 Note that this function is largely superseded by the more flexible
1062 L<transform.c/i_transform2>.
1064 Returns the new image.
1066 The operators for this function are defined in L<stackmach.c>.
1071 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1073 int nxsize,nysize,nx,ny;
1077 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));
1080 nysize = im->ysize ;
1082 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1083 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1084 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1085 /* parm[parmlen-2]=(double)nx;
1086 parm[parmlen-1]=(double)ny; */
1091 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1092 rx=i_op_run(opx,opxl,parm,parmlen);
1093 ry=i_op_run(opy,opyl,parm,parmlen);
1094 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1095 i_gpix(im,rx,ry,&val);
1096 i_ppix(new_img,nx,ny,&val);
1099 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1104 =item i_img_diff(im1, im2)
1106 Calculates the sum of the squares of the differences between
1107 correspoding channels in two images.
1109 If the images are not the same size then only the common area is
1110 compared, hence even if images are different sizes this function
1117 i_img_diff(i_img *im1,i_img *im2) {
1118 int x,y,ch,xb,yb,chb;
1122 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1124 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1125 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1126 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1128 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1131 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1132 i_gpix(im1,x,y,&val1);
1133 i_gpix(im2,x,y,&val2);
1135 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1137 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1142 =item i_img_diffd(im1, im2)
1144 Calculates the sum of the squares of the differences between
1145 correspoding channels in two images.
1147 If the images are not the same size then only the common area is
1148 compared, hence even if images are different sizes this function
1151 This is like i_img_diff() but looks at floating point samples instead.
1157 i_img_diffd(i_img *im1,i_img *im2) {
1158 int x,y,ch,xb,yb,chb;
1162 mm_log((1,"i_img_diffd(im1 0x%x,im2 0x%x)\n",im1,im2));
1164 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1165 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1166 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1168 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1171 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1172 i_gpixf(im1,x,y,&val1);
1173 i_gpixf(im2,x,y,&val2);
1175 for(ch=0;ch<chb;ch++) {
1176 double sdiff = val1.channel[ch]-val2.channel[ch];
1177 tdiff += sdiff * sdiff;
1180 mm_log((1,"i_img_diffd <- (%.2f)\n",tdiff));
1185 /* just a tiny demo of haar wavelets */
1193 i_img *new_img,*new_img2;
1194 i_color val1,val2,dval1,dval2;
1202 /* horizontal pass */
1204 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1205 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1208 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1209 i_gpix(im,x*2,y,&val1);
1210 i_gpix(im,x*2+1,y,&val2);
1211 for(ch=0;ch<im->channels;ch++) {
1212 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1213 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1215 i_ppix(new_img,x,y,&dval1);
1216 i_ppix(new_img,x+fx,y,&dval2);
1219 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1220 i_gpix(new_img,x,y*2,&val1);
1221 i_gpix(new_img,x,y*2+1,&val2);
1222 for(ch=0;ch<im->channels;ch++) {
1223 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1224 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1226 i_ppix(new_img2,x,y,&dval1);
1227 i_ppix(new_img2,x,y+fy,&dval2);
1230 i_img_destroy(new_img);
1235 =item i_count_colors(im, maxc)
1237 returns number of colors or -1
1238 to indicate that it was more than max colors
1242 /* This function has been changed and is now faster. It's using
1243 * i_gsamp instead of i_gpix */
1245 i_count_colors(i_img *im,int maxc) {
1252 int xsize = im->xsize;
1253 int ysize = im->ysize;
1254 int samp_cnt = 3 * xsize;
1256 if (im->channels >= 3) {
1260 channels[0] = channels[1] = channels[2] = 0;
1261 samp_chans = channels;
1266 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1269 for(y = 0; y < ysize; ) {
1270 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1271 for(x = 0; x < samp_cnt; ) {
1272 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1274 if (colorcnt > maxc) {
1285 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1286 * (adapted from the Numerical Recipes)
1288 /* Needed by get_anonymous_color_histo */
1290 hpsort(unsigned int n, unsigned *ra) {
1315 if (j < ir && ra[j] < ra[j+1]) j++;
1327 /* This function constructs an ordered list which represents how much the
1328 * different colors are used. So for instance (100, 100, 500) means that one
1329 * color is used for 500 pixels, another for 100 pixels and another for 100
1330 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1331 * the maxc ;-) and you might want to change the name... */
1332 /* Uses octt_histo */
1334 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1338 unsigned int *col_usage_it;
1343 int xsize = im->xsize;
1344 int ysize = im->ysize;
1345 int samp_cnt = 3 * xsize;
1348 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1350 if (im->channels >= 3) {
1354 channels[0] = channels[1] = channels[2] = 0;
1355 samp_chans = channels;
1359 for(y = 0; y < ysize; ) {
1360 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1361 for(x = 0; x < samp_cnt; ) {
1362 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1364 if (colorcnt > maxc) {
1371 /* Now that we know the number of colours... */
1372 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1373 octt_histo(ct, &col_usage_it);
1374 hpsort(colorcnt, *col_usage);
1382 =head2 8-bit per sample image internal functions
1384 These are the functions installed in an 8-bit per sample image.
1388 =item i_ppix_d(im, x, y, col)
1392 This is the function kept in the i_f_ppix member of an i_img object.
1393 It does a normal store of a pixel into the image with range checking.
1395 Returns 0 if the pixel could be set, -1 otherwise.
1401 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1404 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1405 for(ch=0;ch<im->channels;ch++)
1406 if (im->ch_mask&(1<<ch))
1407 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1410 return -1; /* error was clipped */
1414 =item i_gpix_d(im, x, y, &col)
1418 This is the function kept in the i_f_gpix member of an i_img object.
1419 It does normal retrieval of a pixel from the image with range checking.
1421 Returns 0 if the pixel could be set, -1 otherwise.
1427 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1429 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1430 for(ch=0;ch<im->channels;ch++)
1431 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1434 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1435 return -1; /* error was cliped */
1439 =item i_glin_d(im, l, r, y, vals)
1441 Reads a line of data from the image, storing the pixels at vals.
1443 The line runs from (l,y) inclusive to (r,y) non-inclusive
1445 vals should point at space for (r-l) pixels.
1447 l should never be less than zero (to avoid confusion about where to
1448 put the pixels in vals).
1450 Returns the number of pixels copied (eg. if r, l or y is out of range)
1456 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1458 unsigned char *data;
1459 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1462 data = im->idata + (l+y*im->xsize) * im->channels;
1464 for (i = 0; i < count; ++i) {
1465 for (ch = 0; ch < im->channels; ++ch)
1466 vals[i].channel[ch] = *data++;
1476 =item i_plin_d(im, l, r, y, vals)
1478 Writes a line of data into the image, using the pixels at vals.
1480 The line runs from (l,y) inclusive to (r,y) non-inclusive
1482 vals should point at (r-l) pixels.
1484 l should never be less than zero (to avoid confusion about where to
1485 get the pixels in vals).
1487 Returns the number of pixels copied (eg. if r, l or y is out of range)
1493 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1495 unsigned char *data;
1496 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1499 data = im->idata + (l+y*im->xsize) * im->channels;
1501 for (i = 0; i < count; ++i) {
1502 for (ch = 0; ch < im->channels; ++ch) {
1503 if (im->ch_mask & (1 << ch))
1504 *data = vals[i].channel[ch];
1516 =item i_ppixf_d(im, x, y, val)
1522 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1525 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1526 for(ch=0;ch<im->channels;ch++)
1527 if (im->ch_mask&(1<<ch)) {
1528 im->idata[(x+y*im->xsize)*im->channels+ch] =
1529 SampleFTo8(val->channel[ch]);
1533 return -1; /* error was clipped */
1537 =item i_gpixf_d(im, x, y, val)
1543 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1545 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1546 for(ch=0;ch<im->channels;ch++) {
1548 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1552 return -1; /* error was cliped */
1556 =item i_glinf_d(im, l, r, y, vals)
1558 Reads a line of data from the image, storing the pixels at vals.
1560 The line runs from (l,y) inclusive to (r,y) non-inclusive
1562 vals should point at space for (r-l) pixels.
1564 l should never be less than zero (to avoid confusion about where to
1565 put the pixels in vals).
1567 Returns the number of pixels copied (eg. if r, l or y is out of range)
1573 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1575 unsigned char *data;
1576 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1579 data = im->idata + (l+y*im->xsize) * im->channels;
1581 for (i = 0; i < count; ++i) {
1582 for (ch = 0; ch < im->channels; ++ch)
1583 vals[i].channel[ch] = Sample8ToF(*data++);
1593 =item i_plinf_d(im, l, r, y, vals)
1595 Writes a line of data into the image, using the pixels at vals.
1597 The line runs from (l,y) inclusive to (r,y) non-inclusive
1599 vals should point at (r-l) pixels.
1601 l should never be less than zero (to avoid confusion about where to
1602 get the pixels in vals).
1604 Returns the number of pixels copied (eg. if r, l or y is out of range)
1610 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1612 unsigned char *data;
1613 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1616 data = im->idata + (l+y*im->xsize) * im->channels;
1618 for (i = 0; i < count; ++i) {
1619 for (ch = 0; ch < im->channels; ++ch) {
1620 if (im->ch_mask & (1 << ch))
1621 *data = SampleFTo8(vals[i].channel[ch]);
1633 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1635 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1636 for the channels specified by chans, an array of int with chan_count
1639 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1645 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1646 const int *chans, int chan_count) {
1647 int ch, count, i, w;
1648 unsigned char *data;
1650 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1653 data = im->idata + (l+y*im->xsize) * im->channels;
1658 /* make sure we have good channel numbers */
1659 for (ch = 0; ch < chan_count; ++ch) {
1660 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1661 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1665 for (i = 0; i < w; ++i) {
1666 for (ch = 0; ch < chan_count; ++ch) {
1667 *samps++ = data[chans[ch]];
1670 data += im->channels;
1674 if (chan_count <= 0 || chan_count > im->channels) {
1675 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1679 for (i = 0; i < w; ++i) {
1680 for (ch = 0; ch < chan_count; ++ch) {
1681 *samps++ = data[ch];
1684 data += im->channels;
1696 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1698 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1699 for the channels specified by chan_mask, where bit 0 is the first
1702 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1708 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1709 const int *chans, int chan_count) {
1710 int ch, count, i, w;
1711 unsigned char *data;
1712 for (ch = 0; ch < chan_count; ++ch) {
1713 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1714 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1717 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1720 data = im->idata + (l+y*im->xsize) * im->channels;
1725 /* make sure we have good channel numbers */
1726 for (ch = 0; ch < chan_count; ++ch) {
1727 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1728 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1732 for (i = 0; i < w; ++i) {
1733 for (ch = 0; ch < chan_count; ++ch) {
1734 *samps++ = Sample8ToF(data[chans[ch]]);
1737 data += im->channels;
1741 if (chan_count <= 0 || chan_count > im->channels) {
1742 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
1746 for (i = 0; i < w; ++i) {
1747 for (ch = 0; ch < chan_count; ++ch) {
1748 *samps++ = Sample8ToF(data[ch]);
1751 data += im->channels;
1764 =head2 Image method wrappers
1766 These functions provide i_fsample_t functions in terms of their
1767 i_sample_t versions.
1771 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1776 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1780 for (ch = 0; ch < im->channels; ++ch)
1781 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1783 return i_ppix(im, x, y, &temp);
1787 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1791 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1795 if (i_gpix(im, x, y, &temp)) {
1796 for (ch = 0; ch < im->channels; ++ch)
1797 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1805 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1809 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1812 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1818 work = mymalloc(sizeof(i_color) * (r-l));
1819 for (i = 0; i < r-l; ++i) {
1820 for (ch = 0; ch < im->channels; ++ch)
1821 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1823 ret = i_plin(im, l, r, y, work);
1838 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1842 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1845 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1851 work = mymalloc(sizeof(i_color) * (r-l));
1852 ret = i_plin(im, l, r, y, work);
1853 for (i = 0; i < r-l; ++i) {
1854 for (ch = 0; ch < im->channels; ++ch)
1855 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1871 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1875 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1876 int const *chans, int chan_count) {
1879 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1885 work = mymalloc(sizeof(i_sample_t) * (r-l));
1886 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1887 for (i = 0; i < ret; ++i) {
1888 samp[i] = Sample8ToF(work[i]);
1906 =head2 Palette wrapper functions
1908 Used for virtual images, these forward palette calls to a wrapped image,
1909 assuming the wrapped image is the first pointer in the structure that
1910 im->ext_data points at.
1914 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1918 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1919 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1923 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1927 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1928 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1932 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1936 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1937 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1941 =item i_colorcount_forward(i_img *im)
1945 int i_colorcount_forward(i_img *im) {
1946 return i_colorcount(*(i_img **)im->ext_data);
1950 =item i_maxcolors_forward(i_img *im)
1954 int i_maxcolors_forward(i_img *im) {
1955 return i_maxcolors(*(i_img **)im->ext_data);
1959 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1963 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1964 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1970 =head2 Fallback handler
1974 =item i_gsamp_bits_fb
1980 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps,
1981 const int *chans, int chan_count, int bits) {
1982 if (bits < 1 || bits > 32) {
1983 i_push_error(0, "Invalid bits, must be 1..32");
1987 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1989 int ch, count, i, w;
1992 scale = 4294967295.0;
1994 scale = (double)(1 << bits) - 1;
2002 /* make sure we have good channel numbers */
2003 for (ch = 0; ch < chan_count; ++ch) {
2004 if (chans[ch] < 0 || chans[ch] >= im->channels) {
2005 i_push_errorf(0, "No channel %d in this image", chans[ch]);
2009 for (i = 0; i < w; ++i) {
2011 i_gpixf(im, l+i, y, &c);
2012 for (ch = 0; ch < chan_count; ++ch) {
2013 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2019 if (chan_count <= 0 || chan_count > im->channels) {
2020 i_push_error(0, "Invalid channel count");
2023 for (i = 0; i < w; ++i) {
2025 i_gpixf(im, l+i, y, &c);
2026 for (ch = 0; ch < chan_count; ++ch) {
2027 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2036 i_push_error(0, "Image position outside of image");
2044 =head2 Stream reading and writing wrapper functions
2048 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
2050 Performs general read buffering for file readers that permit reading
2051 to be done through a callback.
2053 The final callback gets two parameters, a I<need> value, and a I<want>
2054 value, where I<need> is the amount of data that the file library needs
2055 to read, and I<want> is the amount of space available in the buffer
2056 maintained by these functions.
2058 This means if you need to read from a stream that you don't know the
2059 length of, you can return I<need> bytes, taking the performance hit of
2060 possibly expensive callbacks (eg. back to perl code), or if you are
2061 reading from a stream where it doesn't matter if some data is lost, or
2062 if the total length of the stream is known, you can return I<want>
2069 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2072 if (length < gci->length - gci->cpos) {
2074 memcpy(buf, gci->buffer+gci->cpos, length);
2075 gci->cpos += length;
2080 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2081 total += gci->length - gci->cpos;
2082 length -= gci->length - gci->cpos;
2083 buf += gci->length - gci->cpos;
2084 if (length < (int)sizeof(gci->buffer)) {
2088 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
2089 sizeof(gci->buffer))) > 0) {
2091 gci->length = did_read;
2093 copy_size = i_min(length, gci->length);
2094 memcpy(buf, gci->buffer, copy_size);
2095 gci->cpos += copy_size;
2098 length -= copy_size;
2102 /* just read the rest - too big for our buffer*/
2104 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2114 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2116 For use by callback file readers to initialize the reader buffer.
2118 Allocates, initializes and returns the reader buffer.
2120 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2125 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2126 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2128 self->userdata = userdata;
2136 =item i_free_gen_read_data(i_gen_read_data *)
2142 void i_free_gen_read_data(i_gen_read_data *self) {
2147 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2149 Performs write buffering for a callback based file writer.
2151 Failures are considered fatal, if a write fails then data will be
2158 i_gen_write_data *self,
2162 if (self->filledto && self->filledto+size > self->maxlength) {
2163 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2171 if (self->filledto+size <= self->maxlength) {
2173 memcpy(self->buffer+self->filledto, data, size);
2174 self->filledto += size;
2177 /* doesn't fit - hand it off */
2178 return self->cb(self->userdata, data, size);
2182 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2184 Allocates and initializes the data structure used by i_gen_writer.
2186 This should be released with L<image.c/i_free_gen_write_data>
2190 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2191 char *userdata, int max_length)
2193 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2195 self->userdata = userdata;
2196 self->maxlength = i_min(max_length, sizeof(self->buffer));
2197 if (self->maxlength < 0)
2198 self->maxlength = sizeof(self->buffer);
2205 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2207 Cleans up the write buffer.
2209 Will flush any left-over data if I<flush> is non-zero.
2211 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2213 Return zero only if flush is non-zero and info->cb() returns zero.
2219 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2221 int result = !flush ||
2222 info->filledto == 0 ||
2223 info->cb(info->userdata, info->buffer, info->filledto);
2229 struct magic_entry {
2230 unsigned char *magic;
2233 unsigned char *mask;
2237 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2238 if (length < magic->magic_size)
2242 unsigned char *bufp = buffer,
2243 *maskp = magic->mask,
2244 *magicp = magic->magic;
2246 for (i = 0; i < magic->magic_size; ++i) {
2247 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2250 if ((*bufp++ & mask) != (*magicp++ & mask))
2257 return !memcmp(magic->magic, buffer, magic->magic_size);
2262 =item i_test_format_probe(io_glue *data, int length)
2264 Check the beginning of the supplied file for a 'magic number'
2269 #define FORMAT_ENTRY(magic, type) \
2270 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2271 #define FORMAT_ENTRY2(magic, type, mask) \
2272 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2275 i_test_format_probe(io_glue *data, int length) {
2276 static const struct magic_entry formats[] = {
2277 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2278 FORMAT_ENTRY("GIF87a", "gif"),
2279 FORMAT_ENTRY("GIF89a", "gif"),
2280 FORMAT_ENTRY("MM\0*", "tiff"),
2281 FORMAT_ENTRY("II*\0", "tiff"),
2282 FORMAT_ENTRY("BM", "bmp"),
2283 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2284 FORMAT_ENTRY("P1", "pnm"),
2285 FORMAT_ENTRY("P2", "pnm"),
2286 FORMAT_ENTRY("P3", "pnm"),
2287 FORMAT_ENTRY("P4", "pnm"),
2288 FORMAT_ENTRY("P5", "pnm"),
2289 FORMAT_ENTRY("P6", "pnm"),
2290 FORMAT_ENTRY("/* XPM", "xpm"),
2291 FORMAT_ENTRY("\x8aMNG", "mng"),
2292 FORMAT_ENTRY("\x8aJNG", "jng"),
2293 /* SGI RGB - with various possible parameters to avoid false positives
2295 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2297 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2298 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2299 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2300 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2302 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
2304 /* different versions of PCX format
2305 http://www.fileformat.info/format/pcx/
2307 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2308 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2309 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2310 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2311 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2313 /* FITS - http://fits.gsfc.nasa.gov/ */
2314 FORMAT_ENTRY("SIMPLE =", "fits"),
2316 /* PSD - Photoshop */
2317 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2319 /* EPS - Encapsulated Postscript */
2320 /* only reading 18 chars, so we don't include the F in EPSF */
2321 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2324 FORMAT_ENTRY("\x52\xCC", "utah"),
2326 /* GZIP compressed, only matching deflate for now */
2327 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2329 /* bzip2 compressed */
2330 FORMAT_ENTRY("BZh", "bzip2"),
2333 http://code.google.com/speed/webp/docs/riff_container.html */
2334 FORMAT_ENTRY2("RIFF WEBP", "webp", "xxxx xxxx"),
2337 This might match a little loosely */
2338 FORMAT_ENTRY("\x00\x00\x00\x0CjP \x0D\x0A\x87\x0A", "jp2"),
2340 static const struct magic_entry more_formats[] = {
2341 /* these were originally both listed as ico, but cur files can
2342 include hotspot information */
2343 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2344 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2345 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
2346 "xwd", " xxxx"), /* X Windows Dump */
2350 unsigned char head[18];
2353 io_glue_commit_types(data);
2354 rc = data->readcb(data, head, 18);
2355 if (rc == -1) return NULL;
2356 data->seekcb(data, -rc, SEEK_CUR);
2358 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2359 struct magic_entry const *entry = formats + i;
2361 if (test_magic(head, rc, entry))
2366 tga_header_verify(head))
2369 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
2370 struct magic_entry const *entry = more_formats + i;
2372 if (test_magic(head, rc, entry))
2380 =item i_img_is_monochrome(img, &zero_is_white)
2382 =category Image Information
2384 Tests an image to check it meets our monochrome tests.
2386 The idea is that a file writer can use this to test where it should
2387 write the image in whatever bi-level format it uses, eg. C<pbm> for
2390 For performance of encoders we require monochrome images:
2400 have a palette of two colors, containing only C<(0,0,0)> and
2401 C<(255,255,255)> in either order.
2405 C<zero_is_white> is set to non-zero if the first palette entry is white.
2411 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2412 if (im->type == i_palette_type
2413 && i_colorcount(im) == 2) {
2415 i_getcolors(im, 0, colors, 2);
2416 if (im->channels == 3) {
2417 if (colors[0].rgb.r == 255 &&
2418 colors[0].rgb.g == 255 &&
2419 colors[0].rgb.b == 255 &&
2420 colors[1].rgb.r == 0 &&
2421 colors[1].rgb.g == 0 &&
2422 colors[1].rgb.b == 0) {
2426 else if (colors[0].rgb.r == 0 &&
2427 colors[0].rgb.g == 0 &&
2428 colors[0].rgb.b == 0 &&
2429 colors[1].rgb.r == 255 &&
2430 colors[1].rgb.g == 255 &&
2431 colors[1].rgb.b == 255) {
2436 else if (im->channels == 1) {
2437 if (colors[0].channel[0] == 255 &&
2438 colors[1].channel[0] == 0) {
2442 else if (colors[0].channel[0] == 0 &&
2443 colors[1].channel[0] == 255) {
2455 =item i_get_file_background(im, &bg)
2459 Retrieve the file write background color tag from the image.
2461 If not present, returns black.
2467 i_get_file_background(i_img *im, i_color *bg) {
2468 if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
2470 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
2472 /* always full alpha */
2473 bg->channel[3] = 255;
2477 =item i_get_file_backgroundf(im, &bg)
2481 Retrieve the file write background color tag from the image as a
2482 floating point color.
2484 Implemented in terms of i_get_file_background().
2486 If not present, returns black.
2492 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
2495 i_get_file_background(im, &bg);
2496 fbg->rgba.r = Sample8ToF(bg.rgba.r);
2497 fbg->rgba.g = Sample8ToF(bg.rgba.g);
2498 fbg->rgba.b = Sample8ToF(bg.rgba.b);
2507 Arnar M. Hrafnkelsson <addi@umich.edu>
2509 Tony Cook <tony@develop-help.com>