1 #define IMAGER_NO_CONTEXT
9 image.c - implements most of the basic functions of Imager and much of the rest
15 c = i_color_new(red, green, blue, alpha);
23 image.c implements the basic functions to create and destroy image and
24 color objects for Imager.
26 =head1 FUNCTION REFERENCE
28 Some of these functions are internal.
35 im_context_t (*im_get_context)(void) = NULL;
41 #define minmax(a,b,i) ( ((a>=i)?a: ( (b<=i)?b:i )) )
43 /* Hack around an obscure linker bug on solaris - probably due to builtin gcc thingies */
44 void i_linker_bug_fake(void) { ceil(1); }
48 =category Image Implementation
50 Allocates a new i_img structure.
52 When implementing a new image type perform the following steps in your
53 image object creation function:
59 allocate the image with i_img_alloc().
63 initialize any function pointers or other data as needed, you can
64 overwrite the whole block if you need to.
68 initialize Imager's internal data by calling i_img_init() on the image
77 im_img_alloc(pIMCTX) {
78 return mymalloc(sizeof(i_img));
82 =item i_img_init(C<img>)
83 =category Image Implementation
85 Imager internal initialization of images.
87 Currently this does very little, in the future it may be used to
88 support threads, or color profiles.
94 im_img_init(pIMCTX, i_img *img) {
96 img->context = aIMCTX;
97 im_context_refinc(aIMCTX, "img_init");
101 =item ICL_new_internal(r, g, b, a)
103 Return a new color object with values passed to it.
105 r - red component (range: 0 - 255)
106 g - green component (range: 0 - 255)
107 b - blue component (range: 0 - 255)
108 a - alpha component (range: 0 - 255)
114 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
117 mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
119 if ( (cl=mymalloc(sizeof(i_color))) == NULL) i_fatal(2,"malloc() error\n");
124 mm_log((1,"(%p) <- ICL_new_internal\n",cl));
130 =item ICL_set_internal(cl, r, g, b, a)
132 Overwrite a color with new values.
134 cl - pointer to color object
135 r - red component (range: 0 - 255)
136 g - green component (range: 0 - 255)
137 b - blue component (range: 0 - 255)
138 a - alpha component (range: 0 - 255)
144 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
145 mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
147 if ( (cl=mymalloc(sizeof(i_color))) == NULL)
148 i_fatal(2,"malloc() error\n");
153 mm_log((1,"(%p) <- ICL_set_internal\n",cl));
159 =item ICL_add(dst, src, ch)
161 Add src to dst inplace - dst is modified.
163 dst - pointer to destination color object
164 src - pointer to color object that is added
165 ch - number of channels
171 ICL_add(i_color *dst,i_color *src,int ch) {
174 tmp=dst->channel[i]+src->channel[i];
175 dst->channel[i]= tmp>255 ? 255:tmp;
182 Dump color information to log - strictly for debugging.
184 cl - pointer to color object
190 ICL_info(i_color const *cl) {
191 mm_log((1,"i_color_info(cl* %p)\n",cl));
192 mm_log((1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
198 Destroy ancillary data for Color object.
200 cl - pointer to color object
206 ICL_DESTROY(i_color *cl) {
207 mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
212 =item i_fcolor_new(double r, double g, double b, double a)
216 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
219 mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
221 if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) i_fatal(2,"malloc() error\n");
226 mm_log((1,"(%p) <- i_fcolor_new\n",cl));
232 =item i_fcolor_destroy(i_fcolor *cl)
236 void i_fcolor_destroy(i_fcolor *cl) {
241 =item i_img_exorcise(im)
251 i_img_exorcise(i_img *im) {
252 mm_log((1,"i_img_exorcise(im* %p)\n",im));
253 i_tags_destroy(&im->tags);
255 (im->i_f_destroy)(im);
256 if (im->idata != NULL) { myfree(im->idata); }
266 =item i_img_destroy(C<img>)
268 =category Image creation/destruction
269 =synopsis i_img_destroy(img)
271 Destroy an image object
277 i_img_destroy(i_img *im) {
279 mm_log((1,"i_img_destroy(im %p)\n",im));
281 if (im) { myfree(im); }
282 im_context_refdec(aIMCTX, "img_destroy");
286 =item i_img_info(im, info)
290 Return image information
293 info - pointer to array to return data
295 info is an array of 4 integers with the following values:
300 info[3] - channel mask
307 i_img_info(i_img *im, i_img_dim *info) {
308 mm_log((1,"i_img_info(im %p)\n",im));
310 mm_log((1,"i_img_info: xsize=%" i_DF " ysize=%" i_DF " channels=%d "
312 i_DFc(im->xsize), i_DFc(im->ysize), im->channels,im->ch_mask));
313 mm_log((1,"i_img_info: idata=%p\n",im->idata));
316 info[2] = im->channels;
317 info[3] = im->ch_mask;
327 =item i_img_setmask(C<im>, C<ch_mask>)
328 =category Image Information
329 =synopsis // only channel 0 writable
330 =synopsis i_img_setmask(img, 0x01);
332 Set the image channel mask for C<im> to C<ch_mask>.
334 The image channel mask gives some control over which channels can be
335 written to in the image.
340 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
344 =item i_img_getmask(C<im>)
345 =category Image Information
346 =synopsis int mask = i_img_getmask(img);
348 Get the image channel mask for C<im>.
353 i_img_getmask(i_img *im) { return im->ch_mask; }
356 =item i_img_getchannels(C<im>)
357 =category Image Information
358 =synopsis int channels = i_img_getchannels(img);
360 Get the number of channels in C<im>.
365 i_img_getchannels(i_img *im) { return im->channels; }
368 =item i_img_get_width(C<im>)
369 =category Image Information
370 =synopsis i_img_dim width = i_img_get_width(im);
372 Returns the width in pixels of the image.
377 i_img_get_width(i_img *im) {
382 =item i_img_get_height(C<im>)
383 =category Image Information
384 =synopsis i_img_dim height = i_img_get_height(im);
386 Returns the height in pixels of the image.
391 i_img_get_height(i_img *im) {
396 =item i_copyto_trans(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
400 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
401 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
402 the target image. pass NULL in C<trans> for non transparent i_colors.
408 i_copyto_trans(i_img *im,i_img *src,i_img_dim x1,i_img_dim y1,i_img_dim x2,i_img_dim y2,i_img_dim tx,i_img_dim ty,const i_color *trans) {
410 i_img_dim x,y,t,ttx,tty,tt;
413 mm_log((1,"i_copyto_trans(im* %p,src %p, p1(" i_DFp "), p2(" i_DFp "), "
414 "to(" i_DFp "), trans* %p)\n",
415 im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty), trans));
417 if (x2<x1) { t=x1; x1=x2; x2=t; }
418 if (y2<y1) { t=y1; y1=y2; y2=t; }
430 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
431 if (tt) i_ppix(im,ttx,tty,&pv);
432 } else i_ppix(im,ttx,tty,&pv);
444 Creates a new image that is a copy of the image C<source>.
446 Tags are not copied, only the image data.
456 i_img *im = i_sametype(src, src->xsize, src->ysize);
458 mm_log((1,"i_copy(src %p)\n", src));
465 if (src->type == i_direct_type) {
466 if (src->bits == i_8_bits) {
468 pv = mymalloc(sizeof(i_color) * x1);
470 for (y = 0; y < y1; ++y) {
471 i_glin(src, 0, x1, y, pv);
472 i_plin(im, 0, x1, y, pv);
479 pv = mymalloc(sizeof(i_fcolor) * x1);
480 for (y = 0; y < y1; ++y) {
481 i_glinf(src, 0, x1, y, pv);
482 i_plinf(im, 0, x1, y, pv);
490 vals = mymalloc(sizeof(i_palidx) * x1);
491 for (y = 0; y < y1; ++y) {
492 i_gpal(src, 0, x1, y, vals);
493 i_ppal(im, 0, x1, y, vals);
503 http://en.wikipedia.org/wiki/Lanczos_resampling
515 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
516 else if (x == 0.0) return (1.0);
517 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
522 =item i_scaleaxis(im, value, axis)
524 Returns a new image object which is I<im> scaled by I<value> along
525 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
531 i_scaleaxis(i_img *im, double Value, int Axis) {
532 i_img_dim hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
533 i_img_dim LanczosWidthFactor;
538 float F, PictureValue[MAXCHANNELS];
540 i_color val,val1,val2;
542 int has_alpha = i_img_has_alpha(im);
543 int color_chans = i_img_color_channels(im);
547 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
550 hsize = (i_img_dim)(0.5 + im->xsize * Value);
553 Value = 1.0 / im->xsize;
561 vsize = (i_img_dim)(0.5 + im->ysize * Value);
565 Value = 1.0 / im->ysize;
572 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
574 i_push_error(0, "cannot create output image");
578 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
579 LanczosWidthFactor = (Value >= 1) ? 1 : (i_img_dim) (1.4/Value);
580 lMax = LanczosWidthFactor << 1;
582 l0 = mymalloc(lMax * sizeof(float));
583 l1 = mymalloc(lMax * sizeof(float));
585 for (j=0; j<jEnd; j++) {
586 OldLocation = ((double) j) / Value;
587 T = (i_img_dim) (OldLocation);
590 for (l = 0; l<lMax; l++) {
591 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
592 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
595 /* Make sure filter is normalized */
597 for(l=0; l<lMax; l++) {
601 t /= (double)LanczosWidthFactor;
603 for(l=0; l<lMax; l++) {
610 for (i=0; i<iEnd; i++) {
611 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
612 for (l=0; l<lMax; l++) {
613 i_img_dim mx = T-lMax+l+1;
614 i_img_dim Mx = T+l+1;
615 mx = (mx < 0) ? 0 : mx;
616 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
618 i_gpix(im, Mx, i, &val1);
619 i_gpix(im, mx, i, &val2);
622 i_sample_t alpha1 = val1.channel[color_chans];
623 i_sample_t alpha2 = val2.channel[color_chans];
624 for (k=0; k < color_chans; k++) {
625 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
626 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
628 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
629 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
632 for (k=0; k<im->channels; k++) {
633 PictureValue[k] += l1[l] * val1.channel[k];
634 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
640 float fa = PictureValue[color_chans] / LanczosWidthFactor;
641 int alpha = minmax(0, 255, fa+0.5);
643 for (k = 0; k < color_chans; ++k) {
644 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
645 val.channel[k]=minmax(0,255,psave);
647 val.channel[color_chans] = alpha;
650 /* zero alpha, so the pixel has no color */
651 for (k = 0; k < im->channels; ++k)
656 for(k=0;k<im->channels;k++) {
657 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
658 val.channel[k]=minmax(0,255,psave);
661 i_ppix(new_img, j, i, &val);
666 for (i=0; i<iEnd; i++) {
667 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
668 for (l=0; l < lMax; l++) {
669 i_img_dim mx = T-lMax+l+1;
670 i_img_dim Mx = T+l+1;
671 mx = (mx < 0) ? 0 : mx;
672 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
674 i_gpix(im, i, Mx, &val1);
675 i_gpix(im, i, mx, &val2);
677 i_sample_t alpha1 = val1.channel[color_chans];
678 i_sample_t alpha2 = val2.channel[color_chans];
679 for (k=0; k < color_chans; k++) {
680 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
681 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
683 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
684 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
687 for (k=0; k<im->channels; k++) {
688 PictureValue[k] += l1[l] * val1.channel[k];
689 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
694 float fa = PictureValue[color_chans] / LanczosWidthFactor;
695 int alpha = minmax(0, 255, fa+0.5);
697 for (k = 0; k < color_chans; ++k) {
698 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
699 val.channel[k]=minmax(0,255,psave);
701 val.channel[color_chans] = alpha;
704 for (k = 0; k < im->channels; ++k)
709 for(k=0;k<im->channels;k++) {
710 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
711 val.channel[k]=minmax(0,255,psave);
714 i_ppix(new_img, i, j, &val);
722 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
729 =item i_scale_nn(im, scx, scy)
731 Scale by using nearest neighbor
732 Both axes scaled at the same time since
733 nothing is gained by doing it in two steps
740 i_scale_nn(i_img *im, double scx, double scy) {
742 i_img_dim nxsize,nysize,nx,ny;
747 mm_log((1,"i_scale_nn(im %p,scx %.2f,scy %.2f)\n",im,scx,scy));
749 nxsize = (i_img_dim) ((double) im->xsize * scx);
752 scx = 1.0 / im->xsize;
754 nysize = (i_img_dim) ((double) im->ysize * scy);
757 scy = 1.0 / im->ysize;
759 im_assert(scx != 0 && scy != 0);
761 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
763 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
764 i_gpix(im,((double)nx)/scx,((double)ny)/scy,&val);
765 i_ppix(new_img,nx,ny,&val);
768 mm_log((1,"(%p) <- i_scale_nn\n",new_img));
774 =item i_sametype(C<im>, C<xsize>, C<ysize>)
776 =category Image creation/destruction
777 =synopsis i_img *img = i_sametype(src, width, height);
779 Returns an image of the same type (sample size, channels, paletted/direct).
781 For paletted images the palette is copied from the source.
787 i_sametype(i_img *src, i_img_dim xsize, i_img_dim ysize) {
790 if (src->type == i_direct_type) {
791 if (src->bits == 8) {
792 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
794 else if (src->bits == i_16_bits) {
795 return i_img_16_new(xsize, ysize, src->channels);
797 else if (src->bits == i_double_bits) {
798 return i_img_double_new(xsize, ysize, src->channels);
801 i_push_error(0, "Unknown image bits");
809 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
810 for (i = 0; i < i_colorcount(src); ++i) {
811 i_getcolors(src, i, &col, 1);
812 i_addcolors(targ, &col, 1);
820 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
822 =category Image creation/destruction
823 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
825 Returns an image of the same type (sample size).
827 For paletted images the equivalent direct type is returned.
833 i_sametype_chans(i_img *src, i_img_dim xsize, i_img_dim ysize, int channels) {
836 if (src->bits == 8) {
837 return i_img_empty_ch(NULL, xsize, ysize, channels);
839 else if (src->bits == i_16_bits) {
840 return i_img_16_new(xsize, ysize, channels);
842 else if (src->bits == i_double_bits) {
843 return i_img_double_new(xsize, ysize, channels);
846 i_push_error(0, "Unknown image bits");
852 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
854 Spatially transforms I<im> returning a new image.
856 opx for a length of opxl and opy for a length of opy are arrays of
857 operators that modify the x and y positions to retreive the pixel data from.
859 parm and parmlen define extra parameters that the operators may use.
861 Note that this function is largely superseded by the more flexible
862 L<transform.c/i_transform2>.
864 Returns the new image.
866 The operators for this function are defined in L<stackmach.c>.
871 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
873 i_img_dim nxsize,nysize,nx,ny;
878 mm_log((1,"i_transform(im %p, opx %p, opxl %d, opy %p, opyl %d, parm %p, parmlen %d)\n",im,opx,opxl,opy,opyl,parm,parmlen));
883 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
884 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
885 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
886 /* parm[parmlen-2]=(double)nx;
887 parm[parmlen-1]=(double)ny; */
892 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
893 rx=i_op_run(opx,opxl,parm,parmlen);
894 ry=i_op_run(opy,opyl,parm,parmlen);
895 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
896 i_gpix(im,rx,ry,&val);
897 i_ppix(new_img,nx,ny,&val);
900 mm_log((1,"(%p) <- i_transform\n",new_img));
905 =item i_img_diff(im1, im2)
907 Calculates the sum of the squares of the differences between
908 correspoding channels in two images.
910 If the images are not the same size then only the common area is
911 compared, hence even if images are different sizes this function
918 i_img_diff(i_img *im1,i_img *im2) {
919 i_img_dim x, y, xb, yb;
925 mm_log((1,"i_img_diff(im1 %p,im2 %p)\n",im1,im2));
927 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
928 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
929 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
931 mm_log((1,"i_img_diff: b=(" i_DFp ") chb=%d\n",
932 i_DFcp(xb,yb), chb));
935 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
936 i_gpix(im1,x,y,&val1);
937 i_gpix(im2,x,y,&val2);
939 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
941 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
946 =item i_img_diffd(im1, im2)
948 Calculates the sum of the squares of the differences between
949 correspoding channels in two images.
951 If the images are not the same size then only the common area is
952 compared, hence even if images are different sizes this function
955 This is like i_img_diff() but looks at floating point samples instead.
961 i_img_diffd(i_img *im1,i_img *im2) {
962 i_img_dim x, y, xb, yb;
967 mm_log((1,"i_img_diffd(im1 %p,im2 %p)\n",im1,im2));
969 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
970 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
971 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
973 mm_log((1,"i_img_diffd: b(" i_DFp ") chb=%d\n",
974 i_DFcp(xb, yb), chb));
977 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
978 i_gpixf(im1,x,y,&val1);
979 i_gpixf(im2,x,y,&val2);
981 for(ch=0;ch<chb;ch++) {
982 double sdiff = val1.channel[ch]-val2.channel[ch];
983 tdiff += sdiff * sdiff;
986 mm_log((1,"i_img_diffd <- (%.2f)\n",tdiff));
992 i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
1000 mm_log((1,"i_img_samef(im1 %p,im2 %p, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
1002 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1003 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1004 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1006 mm_log((1,"i_img_samef: b(" i_DFp ") chb=%d\n",
1007 i_DFcp(xb, yb), chb));
1009 for(y = 0; y < yb; y++) {
1010 for(x = 0; x < xb; x++) {
1011 i_gpixf(im1, x, y, &val1);
1012 i_gpixf(im2, x, y, &val2);
1014 for(ch = 0; ch < chb; ch++) {
1015 double sdiff = val1.channel[ch] - val2.channel[ch];
1016 if (fabs(sdiff) > epsilon) {
1017 mm_log((1,"i_img_samef <- different %g @(" i_DFp ")\n",
1018 sdiff, i_DFcp(x, y)));
1024 mm_log((1,"i_img_samef <- same\n"));
1029 /* just a tiny demo of haar wavelets */
1037 i_img *new_img,*new_img2;
1038 i_color val1,val2,dval1,dval2;
1047 /* horizontal pass */
1049 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1050 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1053 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1054 i_gpix(im,x*2,y,&val1);
1055 i_gpix(im,x*2+1,y,&val2);
1056 for(ch=0;ch<im->channels;ch++) {
1057 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1058 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1060 i_ppix(new_img,x,y,&dval1);
1061 i_ppix(new_img,x+fx,y,&dval2);
1064 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1065 i_gpix(new_img,x,y*2,&val1);
1066 i_gpix(new_img,x,y*2+1,&val2);
1067 for(ch=0;ch<im->channels;ch++) {
1068 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1069 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1071 i_ppix(new_img2,x,y,&dval1);
1072 i_ppix(new_img2,x,y+fy,&dval2);
1075 i_img_destroy(new_img);
1080 =item i_count_colors(im, maxc)
1082 returns number of colors or -1
1083 to indicate that it was more than max colors
1087 /* This function has been changed and is now faster. It's using
1088 * i_gsamp instead of i_gpix */
1090 i_count_colors(i_img *im,int maxc) {
1097 i_img_dim xsize = im->xsize;
1098 i_img_dim ysize = im->ysize;
1099 int samp_cnt = 3 * xsize;
1101 if (im->channels >= 3) {
1105 channels[0] = channels[1] = channels[2] = 0;
1106 samp_chans = channels;
1111 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1114 for(y = 0; y < ysize; ) {
1115 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1116 for(x = 0; x < samp_cnt; ) {
1117 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1119 if (colorcnt > maxc) {
1130 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1131 * (adapted from the Numerical Recipes)
1133 /* Needed by get_anonymous_color_histo */
1135 hpsort(unsigned int n, unsigned *ra) {
1160 if (j < ir && ra[j] < ra[j+1]) j++;
1172 /* This function constructs an ordered list which represents how much the
1173 * different colors are used. So for instance (100, 100, 500) means that one
1174 * color is used for 500 pixels, another for 100 pixels and another for 100
1175 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1176 * the maxc ;-) and you might want to change the name... */
1177 /* Uses octt_histo */
1179 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1183 unsigned int *col_usage_it;
1188 i_img_dim xsize = im->xsize;
1189 i_img_dim ysize = im->ysize;
1190 int samp_cnt = 3 * xsize;
1193 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1195 if (im->channels >= 3) {
1199 channels[0] = channels[1] = channels[2] = 0;
1200 samp_chans = channels;
1204 for(y = 0; y < ysize; ) {
1205 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1206 for(x = 0; x < samp_cnt; ) {
1207 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1209 if (colorcnt > maxc) {
1216 /* Now that we know the number of colours... */
1217 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1218 octt_histo(ct, &col_usage_it);
1219 hpsort(colorcnt, *col_usage);
1227 =head2 Image method wrappers
1229 These functions provide i_fsample_t functions in terms of their
1230 i_sample_t versions.
1234 =item i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1239 int i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix) {
1243 for (ch = 0; ch < im->channels; ++ch)
1244 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1246 return i_ppix(im, x, y, &temp);
1250 =item i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1254 int i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix) {
1258 if (i_gpix(im, x, y, &temp) == 0) {
1259 for (ch = 0; ch < im->channels; ++ch)
1260 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1268 =item i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1273 i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *pix) {
1276 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1283 work = mymalloc(sizeof(i_color) * (r-l));
1284 for (i = 0; i < r-l; ++i) {
1285 for (ch = 0; ch < im->channels; ++ch)
1286 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1288 ret = i_plin(im, l, r, y, work);
1303 =item i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1308 i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix) {
1311 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1318 work = mymalloc(sizeof(i_color) * (r-l));
1319 ret = i_plin(im, l, r, y, work);
1320 for (i = 0; i < r-l; ++i) {
1321 for (ch = 0; ch < im->channels; ++ch)
1322 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1338 =item i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp, int *chans, int chan_count)
1344 i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
1345 int const *chans, int chan_count) {
1348 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1354 work = mymalloc(sizeof(i_sample_t) * (r-l));
1355 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1356 for (i = 0; i < ret; ++i) {
1357 samp[i] = Sample8ToF(work[i]);
1375 =head2 Palette wrapper functions
1377 Used for virtual images, these forward palette calls to a wrapped image,
1378 assuming the wrapped image is the first pointer in the structure that
1379 im->ext_data points at.
1383 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1387 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1388 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1392 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1396 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1397 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1401 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1405 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1406 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1410 =item i_colorcount_forward(i_img *im)
1414 int i_colorcount_forward(i_img *im) {
1415 return i_colorcount(*(i_img **)im->ext_data);
1419 =item i_maxcolors_forward(i_img *im)
1423 int i_maxcolors_forward(i_img *im) {
1424 return i_maxcolors(*(i_img **)im->ext_data);
1428 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1432 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1433 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1439 =head2 Fallback handler
1443 =item i_gsamp_bits_fb
1449 i_gsamp_bits_fb(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps,
1450 const int *chans, int chan_count, int bits) {
1453 if (bits < 1 || bits > 32) {
1454 i_push_error(0, "Invalid bits, must be 1..32");
1458 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1461 i_img_dim count, i, w;
1464 scale = 4294967295.0;
1466 scale = (double)(1 << bits) - 1;
1474 /* make sure we have good channel numbers */
1475 for (ch = 0; ch < chan_count; ++ch) {
1476 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1477 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1481 for (i = 0; i < w; ++i) {
1483 i_gpixf(im, l+i, y, &c);
1484 for (ch = 0; ch < chan_count; ++ch) {
1485 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1491 if (chan_count <= 0 || chan_count > im->channels) {
1492 i_push_error(0, "Invalid channel count");
1495 for (i = 0; i < w; ++i) {
1497 i_gpixf(im, l+i, y, &c);
1498 for (ch = 0; ch < chan_count; ++ch) {
1499 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1508 i_push_error(0, "Image position outside of image");
1513 struct magic_entry {
1514 unsigned char *magic;
1517 unsigned char *mask;
1521 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
1522 if (length < magic->magic_size)
1526 unsigned char *bufp = buffer,
1527 *maskp = magic->mask,
1528 *magicp = magic->magic;
1530 for (i = 0; i < magic->magic_size; ++i) {
1531 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
1534 if ((*bufp++ & mask) != (*magicp++ & mask))
1541 return !memcmp(magic->magic, buffer, magic->magic_size);
1546 =item i_test_format_probe(io_glue *data, int length)
1548 Check the beginning of the supplied file for a 'magic number'
1553 #define FORMAT_ENTRY(magic, type) \
1554 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
1555 #define FORMAT_ENTRY2(magic, type, mask) \
1556 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
1559 i_test_format_probe(io_glue *data, int length) {
1560 static const struct magic_entry formats[] = {
1561 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
1562 FORMAT_ENTRY("GIF87a", "gif"),
1563 FORMAT_ENTRY("GIF89a", "gif"),
1564 FORMAT_ENTRY("MM\0*", "tiff"),
1565 FORMAT_ENTRY("II*\0", "tiff"),
1566 FORMAT_ENTRY("BM", "bmp"),
1567 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
1568 FORMAT_ENTRY("P1", "pnm"),
1569 FORMAT_ENTRY("P2", "pnm"),
1570 FORMAT_ENTRY("P3", "pnm"),
1571 FORMAT_ENTRY("P4", "pnm"),
1572 FORMAT_ENTRY("P5", "pnm"),
1573 FORMAT_ENTRY("P6", "pnm"),
1574 FORMAT_ENTRY("/* XPM", "xpm"),
1575 FORMAT_ENTRY("\x8aMNG", "mng"),
1576 FORMAT_ENTRY("\x8aJNG", "jng"),
1577 /* SGI RGB - with various possible parameters to avoid false positives
1579 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
1581 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
1582 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
1583 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
1584 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
1586 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
1588 /* different versions of PCX format
1589 http://www.fileformat.info/format/pcx/
1591 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
1592 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
1593 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
1594 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
1595 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
1597 /* FITS - http://fits.gsfc.nasa.gov/ */
1598 FORMAT_ENTRY("SIMPLE =", "fits"),
1600 /* PSD - Photoshop */
1601 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
1603 /* EPS - Encapsulated Postscript */
1604 /* only reading 18 chars, so we don't include the F in EPSF */
1605 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
1608 FORMAT_ENTRY("\x52\xCC", "utah"),
1610 /* GZIP compressed, only matching deflate for now */
1611 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
1613 /* bzip2 compressed */
1614 FORMAT_ENTRY("BZh", "bzip2"),
1617 http://code.google.com/speed/webp/docs/riff_container.html */
1618 FORMAT_ENTRY2("RIFF WEBP", "webp", "xxxx xxxx"),
1621 This might match a little loosely */
1622 FORMAT_ENTRY("\x00\x00\x00\x0CjP \x0D\x0A\x87\x0A", "jp2"),
1624 static const struct magic_entry more_formats[] = {
1625 /* these were originally both listed as ico, but cur files can
1626 include hotspot information */
1627 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
1628 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
1629 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
1630 "xwd", " xxxx"), /* X Windows Dump */
1634 unsigned char head[18];
1637 rc = i_io_peekn(data, head, 18);
1638 if (rc == -1) return NULL;
1642 fprintf(stderr, "%d bytes -", (int)rc);
1643 for (i = 0; i < rc; ++i)
1644 fprintf(stderr, " %02x", head[i]);
1645 fprintf(stderr, "\n");
1649 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
1650 struct magic_entry const *entry = formats + i;
1652 if (test_magic(head, rc, entry))
1657 tga_header_verify(head))
1660 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
1661 struct magic_entry const *entry = more_formats + i;
1663 if (test_magic(head, rc, entry))
1671 =item i_img_is_monochrome(img, &zero_is_white)
1673 =category Image Information
1675 Tests an image to check it meets our monochrome tests.
1677 The idea is that a file writer can use this to test where it should
1678 write the image in whatever bi-level format it uses, eg. C<pbm> for
1681 For performance of encoders we require monochrome images:
1691 have a palette of two colors, containing only C<(0,0,0)> and
1692 C<(255,255,255)> in either order.
1696 C<zero_is_white> is set to non-zero if the first palette entry is white.
1702 i_img_is_monochrome(i_img *im, int *zero_is_white) {
1703 if (im->type == i_palette_type
1704 && i_colorcount(im) == 2) {
1706 i_getcolors(im, 0, colors, 2);
1707 if (im->channels == 3) {
1708 if (colors[0].rgb.r == 255 &&
1709 colors[0].rgb.g == 255 &&
1710 colors[0].rgb.b == 255 &&
1711 colors[1].rgb.r == 0 &&
1712 colors[1].rgb.g == 0 &&
1713 colors[1].rgb.b == 0) {
1717 else if (colors[0].rgb.r == 0 &&
1718 colors[0].rgb.g == 0 &&
1719 colors[0].rgb.b == 0 &&
1720 colors[1].rgb.r == 255 &&
1721 colors[1].rgb.g == 255 &&
1722 colors[1].rgb.b == 255) {
1727 else if (im->channels == 1) {
1728 if (colors[0].channel[0] == 255 &&
1729 colors[1].channel[0] == 0) {
1733 else if (colors[0].channel[0] == 0 &&
1734 colors[1].channel[0] == 255) {
1746 =item i_get_file_background(im, &bg)
1750 Retrieve the file write background color tag from the image.
1752 If not present, C<bg> is set to black.
1754 Returns 1 if the C<i_background> tag was found and valid.
1760 i_get_file_background(i_img *im, i_color *bg) {
1761 int result = i_tags_get_color(&im->tags, "i_background", 0, bg);
1764 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
1766 /* always full alpha */
1767 bg->channel[3] = 255;
1773 =item i_get_file_backgroundf(im, &bg)
1777 Retrieve the file write background color tag from the image as a
1778 floating point color.
1780 Implemented in terms of i_get_file_background().
1782 If not present, C<bg> is set to black.
1784 Returns 1 if the C<i_background> tag was found and valid.
1790 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
1792 int result = i_get_file_background(im, &bg);
1793 fbg->rgba.r = Sample8ToF(bg.rgba.r);
1794 fbg->rgba.g = Sample8ToF(bg.rgba.g);
1795 fbg->rgba.b = Sample8ToF(bg.rgba.b);
1806 Arnar M. Hrafnkelsson <addi@umich.edu>
1808 Tony Cook <tonyc@cpan.org>