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); }
44 =category Image Implementation
46 Allocates a new i_img structure.
48 When implementing a new image type perform the following steps in your
49 image object creation function:
55 allocate the image with i_img_alloc().
59 initialize any function pointers or other data as needed, you can
60 overwrite the whole block if you need to.
64 initialize Imager's internal data by calling i_img_init() on the image
74 return mymalloc(sizeof(i_img));
78 =item i_img_init(C<img>)
79 =category Image Implementation
81 Imager internal initialization of images.
83 Currently this does very little, in the future it may be used to
84 support threads, or color profiles.
90 i_img_init(i_img *img) {
95 =item ICL_new_internal(r, g, b, a)
97 Return a new color object with values passed to it.
99 r - red component (range: 0 - 255)
100 g - green component (range: 0 - 255)
101 b - blue component (range: 0 - 255)
102 a - alpha component (range: 0 - 255)
108 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
111 mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
113 if ( (cl=mymalloc(sizeof(i_color))) == NULL) i_fatal(2,"malloc() error\n");
118 mm_log((1,"(%p) <- ICL_new_internal\n",cl));
124 =item ICL_set_internal(cl, r, g, b, a)
126 Overwrite a color with new values.
128 cl - pointer to color object
129 r - red component (range: 0 - 255)
130 g - green component (range: 0 - 255)
131 b - blue component (range: 0 - 255)
132 a - alpha component (range: 0 - 255)
138 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
139 mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
141 if ( (cl=mymalloc(sizeof(i_color))) == NULL)
142 i_fatal(2,"malloc() error\n");
147 mm_log((1,"(%p) <- ICL_set_internal\n",cl));
153 =item ICL_add(dst, src, ch)
155 Add src to dst inplace - dst is modified.
157 dst - pointer to destination color object
158 src - pointer to color object that is added
159 ch - number of channels
165 ICL_add(i_color *dst,i_color *src,int ch) {
168 tmp=dst->channel[i]+src->channel[i];
169 dst->channel[i]= tmp>255 ? 255:tmp;
176 Dump color information to log - strictly for debugging.
178 cl - pointer to color object
184 ICL_info(i_color const *cl) {
185 mm_log((1,"i_color_info(cl* %p)\n",cl));
186 mm_log((1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
192 Destroy ancillary data for Color object.
194 cl - pointer to color object
200 ICL_DESTROY(i_color *cl) {
201 mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
206 =item i_fcolor_new(double r, double g, double b, double a)
210 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
213 mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
215 if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) i_fatal(2,"malloc() error\n");
220 mm_log((1,"(%p) <- i_fcolor_new\n",cl));
226 =item i_fcolor_destroy(i_fcolor *cl)
230 void i_fcolor_destroy(i_fcolor *cl) {
235 =item i_img_exorcise(im)
245 i_img_exorcise(i_img *im) {
246 mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
247 i_tags_destroy(&im->tags);
249 (im->i_f_destroy)(im);
250 if (im->idata != NULL) { myfree(im->idata); }
260 =item i_img_destroy(C<img>)
262 =category Image creation/destruction
263 =synopsis i_img_destroy(img)
265 Destroy an image object
271 i_img_destroy(i_img *im) {
272 mm_log((1,"i_img_destroy(im %p)\n",im));
274 if (im) { myfree(im); }
278 =item i_img_info(im, info)
282 Return image information
285 info - pointer to array to return data
287 info is an array of 4 integers with the following values:
292 info[3] - channel mask
299 i_img_info(i_img *im,int *info) {
300 mm_log((1,"i_img_info(im 0x%x)\n",im));
302 mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
303 mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
306 info[2] = im->channels;
307 info[3] = im->ch_mask;
317 =item i_img_setmask(C<im>, C<ch_mask>)
318 =category Image Information
319 =synopsis // only channel 0 writeable
320 =synopsis i_img_setmask(img, 0x01);
322 Set the image channel mask for C<im> to C<ch_mask>.
324 The image channel mask gives some control over which channels can be
325 written to in the image.
330 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
334 =item i_img_getmask(C<im>)
335 =category Image Information
336 =synopsis int mask = i_img_getmask(img);
338 Get the image channel mask for C<im>.
343 i_img_getmask(i_img *im) { return im->ch_mask; }
346 =item i_img_getchannels(C<im>)
347 =category Image Information
348 =synopsis int channels = i_img_getchannels(img);
350 Get the number of channels in C<im>.
355 i_img_getchannels(i_img *im) { return im->channels; }
358 =item i_img_get_width(C<im>)
359 =category Image Information
360 =synopsis i_img_dim width = i_img_get_width(im);
362 Returns the width in pixels of the image.
367 i_img_get_width(i_img *im) {
372 =item i_img_get_height(C<im>)
373 =category Image Information
374 =synopsis i_img_dim height = i_img_get_height(im);
376 Returns the height in pixels of the image.
381 i_img_get_height(i_img *im) {
386 =item i_copyto_trans(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
390 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
391 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
392 the target image. pass NULL in C<trans> for non transparent i_colors.
398 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) {
400 int x,y,t,ttx,tty,tt,ch;
402 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",
403 im, src, x1, y1, x2, y2, tx, ty, trans));
405 if (x2<x1) { t=x1; x1=x2; x2=t; }
406 if (y2<y1) { t=y1; y1=y2; y2=t; }
418 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
419 if (tt) i_ppix(im,ttx,tty,&pv);
420 } else i_ppix(im,ttx,tty,&pv);
432 Creates a new image that is a copy of the image C<source>.
434 Tags are not copied, only the image data.
444 i_img *im = i_sametype(src, src->xsize, src->ysize);
446 mm_log((1,"i_copy(src %p)\n", src));
453 if (src->type == i_direct_type) {
454 if (src->bits == i_8_bits) {
456 pv = mymalloc(sizeof(i_color) * x1);
458 for (y = 0; y < y1; ++y) {
459 i_glin(src, 0, x1, y, pv);
460 i_plin(im, 0, x1, y, pv);
467 pv = mymalloc(sizeof(i_fcolor) * x1);
468 for (y = 0; y < y1; ++y) {
469 i_glinf(src, 0, x1, y, pv);
470 i_plinf(im, 0, x1, y, pv);
478 vals = mymalloc(sizeof(i_palidx) * x1);
479 for (y = 0; y < y1; ++y) {
480 i_gpal(src, 0, x1, y, vals);
481 i_ppal(im, 0, x1, y, vals);
502 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
503 else if (x == 0.0) return (1.0);
504 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
509 =item i_scaleaxis(im, value, axis)
511 Returns a new image object which is I<im> scaled by I<value> along
512 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
518 i_scaleaxis(i_img *im, float Value, int Axis) {
519 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
520 int LanczosWidthFactor;
521 float *l0, *l1, OldLocation;
524 float F, PictureValue[MAXCHANNELS];
526 i_color val,val1,val2;
528 int has_alpha = i_img_has_alpha(im);
529 int color_chans = i_img_color_channels(im);
532 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
535 hsize = (int)(0.5 + im->xsize * Value);
538 Value = 1.0 / im->xsize;
546 vsize = (int)(0.5 + im->ysize * Value);
550 Value = 1.0 / im->ysize;
557 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
559 i_push_error(0, "cannot create output image");
563 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
564 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
565 lMax = LanczosWidthFactor << 1;
567 l0 = mymalloc(lMax * sizeof(float));
568 l1 = mymalloc(lMax * sizeof(float));
570 for (j=0; j<jEnd; j++) {
571 OldLocation = ((float) j) / Value;
572 T = (int) (OldLocation);
573 F = OldLocation - (float) T;
575 for (l = 0; l<lMax; l++) {
576 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
577 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
580 /* Make sure filter is normalized */
582 for(l=0; l<lMax; l++) {
586 t /= (float)LanczosWidthFactor;
588 for(l=0; l<lMax; l++) {
595 for (i=0; i<iEnd; i++) {
596 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
597 for (l=0; l<lMax; l++) {
600 mx = (mx < 0) ? 0 : mx;
601 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
603 i_gpix(im, Mx, i, &val1);
604 i_gpix(im, mx, i, &val2);
607 i_sample_t alpha1 = val1.channel[color_chans];
608 i_sample_t alpha2 = val2.channel[color_chans];
609 for (k=0; k < color_chans; k++) {
610 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
611 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
613 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
614 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
617 for (k=0; k<im->channels; k++) {
618 PictureValue[k] += l1[l] * val1.channel[k];
619 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
625 float fa = PictureValue[color_chans] / LanczosWidthFactor;
626 int alpha = minmax(0, 255, fa+0.5);
628 for (k = 0; k < color_chans; ++k) {
629 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
630 val.channel[k]=minmax(0,255,psave);
632 val.channel[color_chans] = alpha;
635 /* zero alpha, so the pixel has no color */
636 for (k = 0; k < im->channels; ++k)
641 for(k=0;k<im->channels;k++) {
642 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
643 val.channel[k]=minmax(0,255,psave);
646 i_ppix(new_img, j, i, &val);
651 for (i=0; i<iEnd; i++) {
652 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
653 for (l=0; l < lMax; l++) {
656 mx = (mx < 0) ? 0 : mx;
657 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
659 i_gpix(im, i, Mx, &val1);
660 i_gpix(im, i, mx, &val2);
662 i_sample_t alpha1 = val1.channel[color_chans];
663 i_sample_t alpha2 = val2.channel[color_chans];
664 for (k=0; k < color_chans; k++) {
665 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
666 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
668 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
669 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
672 for (k=0; k<im->channels; k++) {
673 PictureValue[k] += l1[l] * val1.channel[k];
674 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
679 float fa = PictureValue[color_chans] / LanczosWidthFactor;
680 int alpha = minmax(0, 255, fa+0.5);
682 for (k = 0; k < color_chans; ++k) {
683 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
684 val.channel[k]=minmax(0,255,psave);
686 val.channel[color_chans] = alpha;
689 for (k = 0; k < im->channels; ++k)
694 for(k=0;k<im->channels;k++) {
695 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
696 val.channel[k]=minmax(0,255,psave);
699 i_ppix(new_img, i, j, &val);
707 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
714 =item i_scale_nn(im, scx, scy)
716 Scale by using nearest neighbor
717 Both axes scaled at the same time since
718 nothing is gained by doing it in two steps
725 i_scale_nn(i_img *im, float scx, float scy) {
727 int nxsize,nysize,nx,ny;
731 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
733 nxsize = (int) ((float) im->xsize * scx);
736 scx = 1.0 / im->xsize;
738 nysize = (int) ((float) im->ysize * scy);
741 scy = 1.0 / im->ysize;
743 im_assert(scx != 0 && scy != 0);
745 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
747 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
748 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
749 i_ppix(new_img,nx,ny,&val);
752 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
758 =item i_sametype(C<im>, C<xsize>, C<ysize>)
760 =category Image creation/destruction
761 =synopsis i_img *img = i_sametype(src, width, height);
763 Returns an image of the same type (sample size, channels, paletted/direct).
765 For paletted images the palette is copied from the source.
770 i_img *i_sametype(i_img *src, int xsize, int ysize) {
771 if (src->type == i_direct_type) {
772 if (src->bits == 8) {
773 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
775 else if (src->bits == i_16_bits) {
776 return i_img_16_new(xsize, ysize, src->channels);
778 else if (src->bits == i_double_bits) {
779 return i_img_double_new(xsize, ysize, src->channels);
782 i_push_error(0, "Unknown image bits");
790 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
791 for (i = 0; i < i_colorcount(src); ++i) {
792 i_getcolors(src, i, &col, 1);
793 i_addcolors(targ, &col, 1);
801 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
803 =category Image creation/destruction
804 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
806 Returns an image of the same type (sample size).
808 For paletted images the equivalent direct type is returned.
813 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
814 if (src->bits == 8) {
815 return i_img_empty_ch(NULL, xsize, ysize, channels);
817 else if (src->bits == i_16_bits) {
818 return i_img_16_new(xsize, ysize, channels);
820 else if (src->bits == i_double_bits) {
821 return i_img_double_new(xsize, ysize, channels);
824 i_push_error(0, "Unknown image bits");
830 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
832 Spatially transforms I<im> returning a new image.
834 opx for a length of opxl and opy for a length of opy are arrays of
835 operators that modify the x and y positions to retreive the pixel data from.
837 parm and parmlen define extra parameters that the operators may use.
839 Note that this function is largely superseded by the more flexible
840 L<transform.c/i_transform2>.
842 Returns the new image.
844 The operators for this function are defined in L<stackmach.c>.
849 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
851 int nxsize,nysize,nx,ny;
855 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));
860 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
861 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
862 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
863 /* parm[parmlen-2]=(double)nx;
864 parm[parmlen-1]=(double)ny; */
869 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
870 rx=i_op_run(opx,opxl,parm,parmlen);
871 ry=i_op_run(opy,opyl,parm,parmlen);
872 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
873 i_gpix(im,rx,ry,&val);
874 i_ppix(new_img,nx,ny,&val);
877 mm_log((1,"(0x%x) <- i_transform\n",new_img));
882 =item i_img_diff(im1, im2)
884 Calculates the sum of the squares of the differences between
885 correspoding channels in two images.
887 If the images are not the same size then only the common area is
888 compared, hence even if images are different sizes this function
895 i_img_diff(i_img *im1,i_img *im2) {
896 int x,y,ch,xb,yb,chb;
900 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
902 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
903 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
904 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
906 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
909 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
910 i_gpix(im1,x,y,&val1);
911 i_gpix(im2,x,y,&val2);
913 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
915 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
920 =item i_img_diffd(im1, im2)
922 Calculates the sum of the squares of the differences between
923 correspoding channels in two images.
925 If the images are not the same size then only the common area is
926 compared, hence even if images are different sizes this function
929 This is like i_img_diff() but looks at floating point samples instead.
935 i_img_diffd(i_img *im1,i_img *im2) {
936 int x,y,ch,xb,yb,chb;
940 mm_log((1,"i_img_diffd(im1 0x%x,im2 0x%x)\n",im1,im2));
942 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
943 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
944 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
946 mm_log((1,"i_img_diffd: xb=%d xy=%d chb=%d\n",xb,yb,chb));
949 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
950 i_gpixf(im1,x,y,&val1);
951 i_gpixf(im2,x,y,&val2);
953 for(ch=0;ch<chb;ch++) {
954 double sdiff = val1.channel[ch]-val2.channel[ch];
955 tdiff += sdiff * sdiff;
958 mm_log((1,"i_img_diffd <- (%.2f)\n",tdiff));
964 i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
965 int x,y,ch,xb,yb,chb;
971 mm_log((1,"i_img_samef(im1 0x%x,im2 0x%x, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
973 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
974 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
975 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
977 mm_log((1,"i_img_samef: xb=%d xy=%d chb=%d\n",xb,yb,chb));
979 for(y = 0; y < yb; y++) {
980 for(x = 0; x < xb; x++) {
981 i_gpixf(im1, x, y, &val1);
982 i_gpixf(im2, x, y, &val2);
984 for(ch = 0; ch < chb; ch++) {
985 double sdiff = val1.channel[ch] - val2.channel[ch];
986 if (fabs(sdiff) > epsilon) {
987 mm_log((1,"i_img_samef <- different %g @(%d,%d)\n", sdiff, x, y));
993 mm_log((1,"i_img_samef <- same\n"));
998 /* just a tiny demo of haar wavelets */
1006 i_img *new_img,*new_img2;
1007 i_color val1,val2,dval1,dval2;
1015 /* horizontal pass */
1017 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1018 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1021 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1022 i_gpix(im,x*2,y,&val1);
1023 i_gpix(im,x*2+1,y,&val2);
1024 for(ch=0;ch<im->channels;ch++) {
1025 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1026 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1028 i_ppix(new_img,x,y,&dval1);
1029 i_ppix(new_img,x+fx,y,&dval2);
1032 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1033 i_gpix(new_img,x,y*2,&val1);
1034 i_gpix(new_img,x,y*2+1,&val2);
1035 for(ch=0;ch<im->channels;ch++) {
1036 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1037 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1039 i_ppix(new_img2,x,y,&dval1);
1040 i_ppix(new_img2,x,y+fy,&dval2);
1043 i_img_destroy(new_img);
1048 =item i_count_colors(im, maxc)
1050 returns number of colors or -1
1051 to indicate that it was more than max colors
1055 /* This function has been changed and is now faster. It's using
1056 * i_gsamp instead of i_gpix */
1058 i_count_colors(i_img *im,int maxc) {
1065 int xsize = im->xsize;
1066 int ysize = im->ysize;
1067 int samp_cnt = 3 * xsize;
1069 if (im->channels >= 3) {
1073 channels[0] = channels[1] = channels[2] = 0;
1074 samp_chans = channels;
1079 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1082 for(y = 0; y < ysize; ) {
1083 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1084 for(x = 0; x < samp_cnt; ) {
1085 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1087 if (colorcnt > maxc) {
1098 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1099 * (adapted from the Numerical Recipes)
1101 /* Needed by get_anonymous_color_histo */
1103 hpsort(unsigned int n, unsigned *ra) {
1128 if (j < ir && ra[j] < ra[j+1]) j++;
1140 /* This function constructs an ordered list which represents how much the
1141 * different colors are used. So for instance (100, 100, 500) means that one
1142 * color is used for 500 pixels, another for 100 pixels and another for 100
1143 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1144 * the maxc ;-) and you might want to change the name... */
1145 /* Uses octt_histo */
1147 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1151 unsigned int *col_usage_it;
1156 int xsize = im->xsize;
1157 int ysize = im->ysize;
1158 int samp_cnt = 3 * xsize;
1161 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1163 if (im->channels >= 3) {
1167 channels[0] = channels[1] = channels[2] = 0;
1168 samp_chans = channels;
1172 for(y = 0; y < ysize; ) {
1173 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1174 for(x = 0; x < samp_cnt; ) {
1175 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1177 if (colorcnt > maxc) {
1184 /* Now that we know the number of colours... */
1185 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1186 octt_histo(ct, &col_usage_it);
1187 hpsort(colorcnt, *col_usage);
1195 =head2 Image method wrappers
1197 These functions provide i_fsample_t functions in terms of their
1198 i_sample_t versions.
1202 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1207 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1211 for (ch = 0; ch < im->channels; ++ch)
1212 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1214 return i_ppix(im, x, y, &temp);
1218 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1222 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1226 if (i_gpix(im, x, y, &temp)) {
1227 for (ch = 0; ch < im->channels; ++ch)
1228 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1236 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1240 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1243 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1249 work = mymalloc(sizeof(i_color) * (r-l));
1250 for (i = 0; i < r-l; ++i) {
1251 for (ch = 0; ch < im->channels; ++ch)
1252 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1254 ret = i_plin(im, l, r, y, work);
1269 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1273 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1276 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1282 work = mymalloc(sizeof(i_color) * (r-l));
1283 ret = i_plin(im, l, r, y, work);
1284 for (i = 0; i < r-l; ++i) {
1285 for (ch = 0; ch < im->channels; ++ch)
1286 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1302 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1306 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1307 int const *chans, int chan_count) {
1310 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1316 work = mymalloc(sizeof(i_sample_t) * (r-l));
1317 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1318 for (i = 0; i < ret; ++i) {
1319 samp[i] = Sample8ToF(work[i]);
1337 =head2 Palette wrapper functions
1339 Used for virtual images, these forward palette calls to a wrapped image,
1340 assuming the wrapped image is the first pointer in the structure that
1341 im->ext_data points at.
1345 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1349 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1350 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1354 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1358 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1359 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1363 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1367 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1368 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1372 =item i_colorcount_forward(i_img *im)
1376 int i_colorcount_forward(i_img *im) {
1377 return i_colorcount(*(i_img **)im->ext_data);
1381 =item i_maxcolors_forward(i_img *im)
1385 int i_maxcolors_forward(i_img *im) {
1386 return i_maxcolors(*(i_img **)im->ext_data);
1390 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1394 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1395 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1401 =head2 Fallback handler
1405 =item i_gsamp_bits_fb
1411 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps,
1412 const int *chans, int chan_count, int bits) {
1413 if (bits < 1 || bits > 32) {
1414 i_push_error(0, "Invalid bits, must be 1..32");
1418 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1420 int ch, count, i, w;
1423 scale = 4294967295.0;
1425 scale = (double)(1 << bits) - 1;
1433 /* make sure we have good channel numbers */
1434 for (ch = 0; ch < chan_count; ++ch) {
1435 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1436 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1440 for (i = 0; i < w; ++i) {
1442 i_gpixf(im, l+i, y, &c);
1443 for (ch = 0; ch < chan_count; ++ch) {
1444 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1450 if (chan_count <= 0 || chan_count > im->channels) {
1451 i_push_error(0, "Invalid channel count");
1454 for (i = 0; i < w; ++i) {
1456 i_gpixf(im, l+i, y, &c);
1457 for (ch = 0; ch < chan_count; ++ch) {
1458 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1467 i_push_error(0, "Image position outside of image");
1475 =head2 Stream reading and writing wrapper functions
1479 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1481 Performs general read buffering for file readers that permit reading
1482 to be done through a callback.
1484 The final callback gets two parameters, a I<need> value, and a I<want>
1485 value, where I<need> is the amount of data that the file library needs
1486 to read, and I<want> is the amount of space available in the buffer
1487 maintained by these functions.
1489 This means if you need to read from a stream that you don't know the
1490 length of, you can return I<need> bytes, taking the performance hit of
1491 possibly expensive callbacks (eg. back to perl code), or if you are
1492 reading from a stream where it doesn't matter if some data is lost, or
1493 if the total length of the stream is known, you can return I<want>
1500 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1503 if (length < gci->length - gci->cpos) {
1505 memcpy(buf, gci->buffer+gci->cpos, length);
1506 gci->cpos += length;
1511 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1512 total += gci->length - gci->cpos;
1513 length -= gci->length - gci->cpos;
1514 buf += gci->length - gci->cpos;
1515 if (length < (int)sizeof(gci->buffer)) {
1519 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
1520 sizeof(gci->buffer))) > 0) {
1522 gci->length = did_read;
1524 copy_size = i_min(length, gci->length);
1525 memcpy(buf, gci->buffer, copy_size);
1526 gci->cpos += copy_size;
1529 length -= copy_size;
1533 /* just read the rest - too big for our buffer*/
1535 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
1545 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
1547 For use by callback file readers to initialize the reader buffer.
1549 Allocates, initializes and returns the reader buffer.
1551 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
1556 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
1557 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
1559 self->userdata = userdata;
1567 =item i_free_gen_read_data(i_gen_read_data *)
1573 void i_free_gen_read_data(i_gen_read_data *self) {
1578 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
1580 Performs write buffering for a callback based file writer.
1582 Failures are considered fatal, if a write fails then data will be
1589 i_gen_write_data *self,
1593 if (self->filledto && self->filledto+size > self->maxlength) {
1594 if (self->cb(self->userdata, self->buffer, self->filledto)) {
1602 if (self->filledto+size <= self->maxlength) {
1604 memcpy(self->buffer+self->filledto, data, size);
1605 self->filledto += size;
1608 /* doesn't fit - hand it off */
1609 return self->cb(self->userdata, data, size);
1613 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
1615 Allocates and initializes the data structure used by i_gen_writer.
1617 This should be released with L<image.c/i_free_gen_write_data>
1621 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
1622 char *userdata, int max_length)
1624 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
1626 self->userdata = userdata;
1627 self->maxlength = i_min(max_length, sizeof(self->buffer));
1628 if (self->maxlength < 0)
1629 self->maxlength = sizeof(self->buffer);
1636 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
1638 Cleans up the write buffer.
1640 Will flush any left-over data if I<flush> is non-zero.
1642 Returns non-zero if flush is zero or if info->cb() returns non-zero.
1644 Return zero only if flush is non-zero and info->cb() returns zero.
1650 int i_free_gen_write_data(i_gen_write_data *info, int flush)
1652 int result = !flush ||
1653 info->filledto == 0 ||
1654 info->cb(info->userdata, info->buffer, info->filledto);
1660 struct magic_entry {
1661 unsigned char *magic;
1664 unsigned char *mask;
1668 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
1669 if (length < magic->magic_size)
1673 unsigned char *bufp = buffer,
1674 *maskp = magic->mask,
1675 *magicp = magic->magic;
1677 for (i = 0; i < magic->magic_size; ++i) {
1678 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
1681 if ((*bufp++ & mask) != (*magicp++ & mask))
1688 return !memcmp(magic->magic, buffer, magic->magic_size);
1693 =item i_test_format_probe(io_glue *data, int length)
1695 Check the beginning of the supplied file for a 'magic number'
1700 #define FORMAT_ENTRY(magic, type) \
1701 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
1702 #define FORMAT_ENTRY2(magic, type, mask) \
1703 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
1706 i_test_format_probe(io_glue *data, int length) {
1707 static const struct magic_entry formats[] = {
1708 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
1709 FORMAT_ENTRY("GIF87a", "gif"),
1710 FORMAT_ENTRY("GIF89a", "gif"),
1711 FORMAT_ENTRY("MM\0*", "tiff"),
1712 FORMAT_ENTRY("II*\0", "tiff"),
1713 FORMAT_ENTRY("BM", "bmp"),
1714 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
1715 FORMAT_ENTRY("P1", "pnm"),
1716 FORMAT_ENTRY("P2", "pnm"),
1717 FORMAT_ENTRY("P3", "pnm"),
1718 FORMAT_ENTRY("P4", "pnm"),
1719 FORMAT_ENTRY("P5", "pnm"),
1720 FORMAT_ENTRY("P6", "pnm"),
1721 FORMAT_ENTRY("/* XPM", "xpm"),
1722 FORMAT_ENTRY("\x8aMNG", "mng"),
1723 FORMAT_ENTRY("\x8aJNG", "jng"),
1724 /* SGI RGB - with various possible parameters to avoid false positives
1726 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
1728 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
1729 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
1730 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
1731 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
1733 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
1735 /* different versions of PCX format
1736 http://www.fileformat.info/format/pcx/
1738 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
1739 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
1740 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
1741 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
1742 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
1744 /* FITS - http://fits.gsfc.nasa.gov/ */
1745 FORMAT_ENTRY("SIMPLE =", "fits"),
1747 /* PSD - Photoshop */
1748 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
1750 /* EPS - Encapsulated Postscript */
1751 /* only reading 18 chars, so we don't include the F in EPSF */
1752 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
1755 FORMAT_ENTRY("\x52\xCC", "utah"),
1757 /* GZIP compressed, only matching deflate for now */
1758 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
1760 /* bzip2 compressed */
1761 FORMAT_ENTRY("BZh", "bzip2"),
1764 http://code.google.com/speed/webp/docs/riff_container.html */
1765 FORMAT_ENTRY2("RIFF WEBP", "webp", "xxxx xxxx"),
1768 This might match a little loosely */
1769 FORMAT_ENTRY("\x00\x00\x00\x0CjP \x0D\x0A\x87\x0A", "jp2"),
1771 static const struct magic_entry more_formats[] = {
1772 /* these were originally both listed as ico, but cur files can
1773 include hotspot information */
1774 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
1775 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
1776 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
1777 "xwd", " xxxx"), /* X Windows Dump */
1781 unsigned char head[18];
1784 io_glue_commit_types(data);
1785 rc = data->readcb(data, head, 18);
1786 if (rc == -1) return NULL;
1787 data->seekcb(data, -rc, SEEK_CUR);
1789 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
1790 struct magic_entry const *entry = formats + i;
1792 if (test_magic(head, rc, entry))
1797 tga_header_verify(head))
1800 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
1801 struct magic_entry const *entry = more_formats + i;
1803 if (test_magic(head, rc, entry))
1811 =item i_img_is_monochrome(img, &zero_is_white)
1813 =category Image Information
1815 Tests an image to check it meets our monochrome tests.
1817 The idea is that a file writer can use this to test where it should
1818 write the image in whatever bi-level format it uses, eg. C<pbm> for
1821 For performance of encoders we require monochrome images:
1831 have a palette of two colors, containing only C<(0,0,0)> and
1832 C<(255,255,255)> in either order.
1836 C<zero_is_white> is set to non-zero if the first palette entry is white.
1842 i_img_is_monochrome(i_img *im, int *zero_is_white) {
1843 if (im->type == i_palette_type
1844 && i_colorcount(im) == 2) {
1846 i_getcolors(im, 0, colors, 2);
1847 if (im->channels == 3) {
1848 if (colors[0].rgb.r == 255 &&
1849 colors[0].rgb.g == 255 &&
1850 colors[0].rgb.b == 255 &&
1851 colors[1].rgb.r == 0 &&
1852 colors[1].rgb.g == 0 &&
1853 colors[1].rgb.b == 0) {
1857 else if (colors[0].rgb.r == 0 &&
1858 colors[0].rgb.g == 0 &&
1859 colors[0].rgb.b == 0 &&
1860 colors[1].rgb.r == 255 &&
1861 colors[1].rgb.g == 255 &&
1862 colors[1].rgb.b == 255) {
1867 else if (im->channels == 1) {
1868 if (colors[0].channel[0] == 255 &&
1869 colors[1].channel[0] == 0) {
1873 else if (colors[0].channel[0] == 0 &&
1874 colors[1].channel[0] == 255) {
1886 =item i_get_file_background(im, &bg)
1890 Retrieve the file write background color tag from the image.
1892 If not present, returns black.
1898 i_get_file_background(i_img *im, i_color *bg) {
1899 if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
1901 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
1903 /* always full alpha */
1904 bg->channel[3] = 255;
1908 =item i_get_file_backgroundf(im, &bg)
1912 Retrieve the file write background color tag from the image as a
1913 floating point color.
1915 Implemented in terms of i_get_file_background().
1917 If not present, returns black.
1923 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
1926 i_get_file_background(im, &bg);
1927 fbg->rgba.r = Sample8ToF(bg.rgba.r);
1928 fbg->rgba.g = Sample8ToF(bg.rgba.g);
1929 fbg->rgba.b = Sample8ToF(bg.rgba.b);
1938 Arnar M. Hrafnkelsson <addi@umich.edu>
1940 Tony Cook <tony@develop-help.com>