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); }
47 =item im_img_alloc(aIMCTX)
48 X<im_img_alloc API>X<i_img_alloc API>
49 =category Image Implementation
50 =synopsis i_img *im = im_img_alloc(aIMCTX);
51 =synopsis i_img *im = i_img_alloc();
53 Allocates a new i_img structure.
55 When implementing a new image type perform the following steps in your
56 image object creation function:
62 allocate the image with i_img_alloc().
66 initialize any function pointers or other data as needed, you can
67 overwrite the whole block if you need to.
71 initialize Imager's internal data by calling i_img_init() on the image
80 im_img_alloc(pIMCTX) {
81 return mymalloc(sizeof(i_img));
85 =item im_img_init(aIMCTX, image)
86 X<im_img_init API>X<i_img_init API>
87 =category Image Implementation
88 =synopsis im_img_init(aIMCTX, im);
89 =synopsis i_img_init(im);
91 Imager internal initialization of images.
93 See L</im_img_alloc(aIMCTX)> for more information.
99 im_img_init(pIMCTX, i_img *img) {
101 img->context = aIMCTX;
102 im_context_refinc(aIMCTX, "img_init");
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) {
123 im_log((aIMCTX,1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
125 if ( (cl=mymalloc(sizeof(i_color))) == NULL) im_fatal(aIMCTX, 2,"malloc() error\n");
130 im_log((aIMCTX,1,"(%p) <- ICL_new_internal\n",cl));
136 =item ICL_set_internal(cl, r, g, b, a)
138 Overwrite a color with new values.
140 cl - pointer to color object
141 r - red component (range: 0 - 255)
142 g - green component (range: 0 - 255)
143 b - blue component (range: 0 - 255)
144 a - alpha component (range: 0 - 255)
150 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
152 im_log((aIMCTX,1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
154 if ( (cl=mymalloc(sizeof(i_color))) == NULL)
155 im_fatal(aIMCTX, 2,"malloc() error\n");
160 im_log((aIMCTX,1,"(%p) <- ICL_set_internal\n",cl));
166 =item ICL_add(dst, src, ch)
168 Add src to dst inplace - dst is modified.
170 dst - pointer to destination color object
171 src - pointer to color object that is added
172 ch - number of channels
178 ICL_add(i_color *dst,i_color *src,int ch) {
181 tmp=dst->channel[i]+src->channel[i];
182 dst->channel[i]= tmp>255 ? 255:tmp;
189 Dump color information to log - strictly for debugging.
191 cl - pointer to color object
197 ICL_info(i_color const *cl) {
199 im_log((aIMCTX, 1,"i_color_info(cl* %p)\n",cl));
200 im_log((aIMCTX, 1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
206 Destroy ancillary data for Color object.
208 cl - pointer to color object
214 ICL_DESTROY(i_color *cl) {
216 im_log((aIMCTX, 1,"ICL_DESTROY(cl* %p)\n",cl));
221 =item i_fcolor_new(double r, double g, double b, double a)
225 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
229 im_log((aIMCTX, 1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
231 if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) im_fatal(aIMCTX, 2,"malloc() error\n");
236 im_log((aIMCTX, 1,"(%p) <- i_fcolor_new\n",cl));
242 =item i_fcolor_destroy(i_fcolor *cl)
246 void i_fcolor_destroy(i_fcolor *cl) {
251 =item i_img_exorcise(im)
261 i_img_exorcise(i_img *im) {
263 im_log((aIMCTX,1,"i_img_exorcise(im* %p)\n",im));
264 i_tags_destroy(&im->tags);
266 (im->i_f_destroy)(im);
267 if (im->idata != NULL) { myfree(im->idata); }
277 =item i_img_destroy(C<img>)
279 =category Image creation/destruction
280 =synopsis i_img_destroy(img)
282 Destroy an image object
288 i_img_destroy(i_img *im) {
290 im_log((aIMCTX, 1,"i_img_destroy(im %p)\n",im));
292 if (im) { myfree(im); }
293 im_context_refdec(aIMCTX, "img_destroy");
297 =item i_img_info(im, info)
301 Return image information
304 info - pointer to array to return data
306 info is an array of 4 integers with the following values:
311 info[3] - channel mask
318 i_img_info(i_img *im, i_img_dim *info) {
320 im_log((aIMCTX,1,"i_img_info(im %p)\n",im));
322 im_log((aIMCTX,1,"i_img_info: xsize=%" i_DF " ysize=%" i_DF " channels=%d "
324 i_DFc(im->xsize), i_DFc(im->ysize), im->channels,im->ch_mask));
325 im_log((aIMCTX,1,"i_img_info: idata=%p\n",im->idata));
328 info[2] = im->channels;
329 info[3] = im->ch_mask;
339 =item i_img_setmask(C<im>, C<ch_mask>)
340 =category Image Information
341 =synopsis // only channel 0 writable
342 =synopsis i_img_setmask(img, 0x01);
344 Set the image channel mask for C<im> to C<ch_mask>.
346 The image channel mask gives some control over which channels can be
347 written to in the image.
352 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
356 =item i_img_getmask(C<im>)
357 =category Image Information
358 =synopsis int mask = i_img_getmask(img);
360 Get the image channel mask for C<im>.
365 i_img_getmask(i_img *im) { return im->ch_mask; }
368 =item i_img_getchannels(C<im>)
369 =category Image Information
370 =synopsis int channels = i_img_getchannels(img);
372 Get the number of channels in C<im>.
377 i_img_getchannels(i_img *im) { return im->channels; }
380 =item i_img_get_width(C<im>)
381 =category Image Information
382 =synopsis i_img_dim width = i_img_get_width(im);
384 Returns the width in pixels of the image.
389 i_img_get_width(i_img *im) {
394 =item i_img_get_height(C<im>)
395 =category Image Information
396 =synopsis i_img_dim height = i_img_get_height(im);
398 Returns the height in pixels of the image.
403 i_img_get_height(i_img *im) {
408 =item i_copyto_trans(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
412 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
413 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
414 the target image. pass NULL in C<trans> for non transparent i_colors.
420 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) {
422 i_img_dim x,y,t,ttx,tty,tt;
426 im_log((aIMCTX, 1,"i_copyto_trans(im* %p,src %p, p1(" i_DFp "), p2(" i_DFp "), "
427 "to(" i_DFp "), trans* %p)\n",
428 im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty), trans));
430 if (x2<x1) { t=x1; x1=x2; x2=t; }
431 if (y2<y1) { t=y1; y1=y2; y2=t; }
443 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
444 if (tt) i_ppix(im,ttx,tty,&pv);
445 } else i_ppix(im,ttx,tty,&pv);
457 Creates a new image that is a copy of the image C<source>.
459 Tags are not copied, only the image data.
470 i_img *im = i_sametype(src, src->xsize, src->ysize);
472 im_log((aIMCTX,1,"i_copy(src %p)\n", src));
479 if (src->type == i_direct_type) {
480 if (src->bits == i_8_bits) {
482 pv = mymalloc(sizeof(i_color) * x1);
484 for (y = 0; y < y1; ++y) {
485 i_glin(src, 0, x1, y, pv);
486 i_plin(im, 0, x1, y, pv);
493 pv = mymalloc(sizeof(i_fcolor) * x1);
494 for (y = 0; y < y1; ++y) {
495 i_glinf(src, 0, x1, y, pv);
496 i_plinf(im, 0, x1, y, pv);
504 vals = mymalloc(sizeof(i_palidx) * x1);
505 for (y = 0; y < y1; ++y) {
506 i_gpal(src, 0, x1, y, vals);
507 i_ppal(im, 0, x1, y, vals);
517 http://en.wikipedia.org/wiki/Lanczos_resampling
529 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
530 else if (x == 0.0) return (1.0);
531 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
536 =item i_scaleaxis(im, value, axis)
538 Returns a new image object which is I<im> scaled by I<value> along
539 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
545 i_scaleaxis(i_img *im, double Value, int Axis) {
546 i_img_dim hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
547 i_img_dim LanczosWidthFactor;
552 float F, PictureValue[MAXCHANNELS];
554 i_color val,val1,val2;
556 int has_alpha = i_img_has_alpha(im);
557 int color_chans = i_img_color_channels(im);
561 im_log((aIMCTX, 1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
564 hsize = (i_img_dim)(0.5 + im->xsize * Value);
567 Value = 1.0 / im->xsize;
575 vsize = (i_img_dim)(0.5 + im->ysize * Value);
579 Value = 1.0 / im->ysize;
586 new_img = i_img_8_new(hsize, vsize, im->channels);
588 i_push_error(0, "cannot create output image");
592 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
593 LanczosWidthFactor = (Value >= 1) ? 1 : (i_img_dim) (1.4/Value);
594 lMax = LanczosWidthFactor << 1;
596 l0 = mymalloc(lMax * sizeof(float));
597 l1 = mymalloc(lMax * sizeof(float));
599 for (j=0; j<jEnd; j++) {
600 OldLocation = ((double) j) / Value;
601 T = (i_img_dim) (OldLocation);
604 for (l = 0; l<lMax; l++) {
605 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
606 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
609 /* Make sure filter is normalized */
611 for(l=0; l<lMax; l++) {
615 t /= (double)LanczosWidthFactor;
617 for(l=0; l<lMax; l++) {
624 for (i=0; i<iEnd; i++) {
625 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
626 for (l=0; l<lMax; l++) {
627 i_img_dim mx = T-lMax+l+1;
628 i_img_dim Mx = T+l+1;
629 mx = (mx < 0) ? 0 : mx;
630 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
632 i_gpix(im, Mx, i, &val1);
633 i_gpix(im, mx, i, &val2);
636 i_sample_t alpha1 = val1.channel[color_chans];
637 i_sample_t alpha2 = val2.channel[color_chans];
638 for (k=0; k < color_chans; k++) {
639 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
640 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
642 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
643 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
646 for (k=0; k<im->channels; k++) {
647 PictureValue[k] += l1[l] * val1.channel[k];
648 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
654 float fa = PictureValue[color_chans] / LanczosWidthFactor;
655 int alpha = minmax(0, 255, fa+0.5);
657 for (k = 0; k < color_chans; ++k) {
658 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
659 val.channel[k]=minmax(0,255,psave);
661 val.channel[color_chans] = alpha;
664 /* zero alpha, so the pixel has no color */
665 for (k = 0; k < im->channels; ++k)
670 for(k=0;k<im->channels;k++) {
671 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
672 val.channel[k]=minmax(0,255,psave);
675 i_ppix(new_img, j, i, &val);
680 for (i=0; i<iEnd; i++) {
681 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
682 for (l=0; l < lMax; l++) {
683 i_img_dim mx = T-lMax+l+1;
684 i_img_dim Mx = T+l+1;
685 mx = (mx < 0) ? 0 : mx;
686 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
688 i_gpix(im, i, Mx, &val1);
689 i_gpix(im, i, mx, &val2);
691 i_sample_t alpha1 = val1.channel[color_chans];
692 i_sample_t alpha2 = val2.channel[color_chans];
693 for (k=0; k < color_chans; k++) {
694 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
695 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
697 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
698 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
701 for (k=0; k<im->channels; k++) {
702 PictureValue[k] += l1[l] * val1.channel[k];
703 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
708 float fa = PictureValue[color_chans] / LanczosWidthFactor;
709 int alpha = minmax(0, 255, fa+0.5);
711 for (k = 0; k < color_chans; ++k) {
712 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
713 val.channel[k]=minmax(0,255,psave);
715 val.channel[color_chans] = alpha;
718 for (k = 0; k < im->channels; ++k)
723 for(k=0;k<im->channels;k++) {
724 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
725 val.channel[k]=minmax(0,255,psave);
728 i_ppix(new_img, i, j, &val);
736 im_log((aIMCTX, 1,"(%p) <- i_scaleaxis\n", new_img));
743 =item i_scale_nn(im, scx, scy)
745 Scale by using nearest neighbor
746 Both axes scaled at the same time since
747 nothing is gained by doing it in two steps
754 i_scale_nn(i_img *im, double scx, double scy) {
756 i_img_dim nxsize,nysize,nx,ny;
761 im_log((aIMCTX, 1,"i_scale_nn(im %p,scx %.2f,scy %.2f)\n",im,scx,scy));
763 nxsize = (i_img_dim) ((double) im->xsize * scx);
766 scx = 1.0 / im->xsize;
768 nysize = (i_img_dim) ((double) im->ysize * scy);
771 scy = 1.0 / im->ysize;
773 im_assert(scx != 0 && scy != 0);
775 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
777 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
778 i_gpix(im,((double)nx)/scx,((double)ny)/scy,&val);
779 i_ppix(new_img,nx,ny,&val);
782 im_log((aIMCTX, 1,"(%p) <- i_scale_nn\n",new_img));
788 =item i_sametype(C<im>, C<xsize>, C<ysize>)
790 =category Image creation/destruction
791 =synopsis i_img *img = i_sametype(src, width, height);
793 Returns an image of the same type (sample size, channels, paletted/direct).
795 For paletted images the palette is copied from the source.
801 i_sametype(i_img *src, i_img_dim xsize, i_img_dim ysize) {
804 if (src->type == i_direct_type) {
805 if (src->bits == 8) {
806 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
808 else if (src->bits == i_16_bits) {
809 return i_img_16_new(xsize, ysize, src->channels);
811 else if (src->bits == i_double_bits) {
812 return i_img_double_new(xsize, ysize, src->channels);
815 i_push_error(0, "Unknown image bits");
823 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
824 for (i = 0; i < i_colorcount(src); ++i) {
825 i_getcolors(src, i, &col, 1);
826 i_addcolors(targ, &col, 1);
834 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
836 =category Image creation/destruction
837 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
839 Returns an image of the same type (sample size).
841 For paletted images the equivalent direct type is returned.
847 i_sametype_chans(i_img *src, i_img_dim xsize, i_img_dim ysize, int channels) {
850 if (src->bits == 8) {
851 return i_img_empty_ch(NULL, xsize, ysize, channels);
853 else if (src->bits == i_16_bits) {
854 return i_img_16_new(xsize, ysize, channels);
856 else if (src->bits == i_double_bits) {
857 return i_img_double_new(xsize, ysize, channels);
860 i_push_error(0, "Unknown image bits");
866 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
868 Spatially transforms I<im> returning a new image.
870 opx for a length of opxl and opy for a length of opy are arrays of
871 operators that modify the x and y positions to retreive the pixel data from.
873 parm and parmlen define extra parameters that the operators may use.
875 Note that this function is largely superseded by the more flexible
876 L<transform.c/i_transform2>.
878 Returns the new image.
880 The operators for this function are defined in L<stackmach.c>.
885 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
887 i_img_dim nxsize,nysize,nx,ny;
892 im_log((aIMCTX, 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));
897 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
898 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
899 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
900 /* parm[parmlen-2]=(double)nx;
901 parm[parmlen-1]=(double)ny; */
906 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
907 rx=i_op_run(opx,opxl,parm,parmlen);
908 ry=i_op_run(opy,opyl,parm,parmlen);
909 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
910 i_gpix(im,rx,ry,&val);
911 i_ppix(new_img,nx,ny,&val);
914 im_log((aIMCTX, 1,"(%p) <- i_transform\n",new_img));
919 =item i_img_diff(im1, im2)
921 Calculates the sum of the squares of the differences between
922 correspoding channels in two images.
924 If the images are not the same size then only the common area is
925 compared, hence even if images are different sizes this function
932 i_img_diff(i_img *im1,i_img *im2) {
933 i_img_dim x, y, xb, yb;
939 im_log((aIMCTX, 1,"i_img_diff(im1 %p,im2 %p)\n",im1,im2));
941 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
942 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
943 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
945 im_log((aIMCTX, 1,"i_img_diff: b=(" i_DFp ") chb=%d\n",
946 i_DFcp(xb,yb), chb));
949 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
950 i_gpix(im1,x,y,&val1);
951 i_gpix(im2,x,y,&val2);
953 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
955 im_log((aIMCTX, 1,"i_img_diff <- (%.2f)\n",tdiff));
960 =item i_img_diffd(im1, im2)
962 Calculates the sum of the squares of the differences between
963 correspoding channels in two images.
965 If the images are not the same size then only the common area is
966 compared, hence even if images are different sizes this function
969 This is like i_img_diff() but looks at floating point samples instead.
975 i_img_diffd(i_img *im1,i_img *im2) {
976 i_img_dim x, y, xb, yb;
982 im_log((aIMCTX, 1,"i_img_diffd(im1 %p,im2 %p)\n",im1,im2));
984 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
985 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
986 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
988 im_log((aIMCTX, 1,"i_img_diffd: b(" i_DFp ") chb=%d\n",
989 i_DFcp(xb, yb), chb));
992 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
993 i_gpixf(im1,x,y,&val1);
994 i_gpixf(im2,x,y,&val2);
996 for(ch=0;ch<chb;ch++) {
997 double sdiff = val1.channel[ch]-val2.channel[ch];
998 tdiff += sdiff * sdiff;
1001 im_log((aIMCTX, 1,"i_img_diffd <- (%.2f)\n",tdiff));
1007 i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
1008 i_img_dim x,y,xb,yb;
1016 im_log((aIMCTX,1,"i_img_samef(im1 %p,im2 %p, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
1018 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1019 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1020 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1022 im_log((aIMCTX, 1,"i_img_samef: b(" i_DFp ") chb=%d\n",
1023 i_DFcp(xb, yb), chb));
1025 for(y = 0; y < yb; y++) {
1026 for(x = 0; x < xb; x++) {
1027 i_gpixf(im1, x, y, &val1);
1028 i_gpixf(im2, x, y, &val2);
1030 for(ch = 0; ch < chb; ch++) {
1031 double sdiff = val1.channel[ch] - val2.channel[ch];
1032 if (fabs(sdiff) > epsilon) {
1033 im_log((aIMCTX, 1,"i_img_samef <- different %g @(" i_DFp ")\n",
1034 sdiff, i_DFcp(x, y)));
1040 im_log((aIMCTX, 1,"i_img_samef <- same\n"));
1045 /* just a tiny demo of haar wavelets */
1053 i_img *new_img,*new_img2;
1054 i_color val1,val2,dval1,dval2;
1063 /* horizontal pass */
1065 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1066 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1069 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1070 i_gpix(im,x*2,y,&val1);
1071 i_gpix(im,x*2+1,y,&val2);
1072 for(ch=0;ch<im->channels;ch++) {
1073 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1074 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1076 i_ppix(new_img,x,y,&dval1);
1077 i_ppix(new_img,x+fx,y,&dval2);
1080 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1081 i_gpix(new_img,x,y*2,&val1);
1082 i_gpix(new_img,x,y*2+1,&val2);
1083 for(ch=0;ch<im->channels;ch++) {
1084 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1085 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1087 i_ppix(new_img2,x,y,&dval1);
1088 i_ppix(new_img2,x,y+fy,&dval2);
1091 i_img_destroy(new_img);
1096 =item i_count_colors(im, maxc)
1098 returns number of colors or -1
1099 to indicate that it was more than max colors
1103 /* This function has been changed and is now faster. It's using
1104 * i_gsamp instead of i_gpix */
1106 i_count_colors(i_img *im,int maxc) {
1113 i_img_dim xsize = im->xsize;
1114 i_img_dim ysize = im->ysize;
1115 int samp_cnt = 3 * xsize;
1117 if (im->channels >= 3) {
1121 channels[0] = channels[1] = channels[2] = 0;
1122 samp_chans = channels;
1127 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1130 for(y = 0; y < ysize; ) {
1131 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1132 for(x = 0; x < samp_cnt; ) {
1133 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1135 if (colorcnt > maxc) {
1146 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1147 * (adapted from the Numerical Recipes)
1149 /* Needed by get_anonymous_color_histo */
1151 hpsort(unsigned int n, unsigned *ra) {
1176 if (j < ir && ra[j] < ra[j+1]) j++;
1188 /* This function constructs an ordered list which represents how much the
1189 * different colors are used. So for instance (100, 100, 500) means that one
1190 * color is used for 500 pixels, another for 100 pixels and another for 100
1191 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1192 * the maxc ;-) and you might want to change the name... */
1193 /* Uses octt_histo */
1195 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1199 unsigned int *col_usage_it;
1204 i_img_dim xsize = im->xsize;
1205 i_img_dim ysize = im->ysize;
1206 int samp_cnt = 3 * xsize;
1209 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1211 if (im->channels >= 3) {
1215 channels[0] = channels[1] = channels[2] = 0;
1216 samp_chans = channels;
1220 for(y = 0; y < ysize; ) {
1221 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1222 for(x = 0; x < samp_cnt; ) {
1223 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1225 if (colorcnt > maxc) {
1232 /* Now that we know the number of colours... */
1233 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1234 octt_histo(ct, &col_usage_it);
1235 hpsort(colorcnt, *col_usage);
1243 =head2 Image method wrappers
1245 These functions provide i_fsample_t functions in terms of their
1246 i_sample_t versions.
1250 =item i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1255 int i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix) {
1259 for (ch = 0; ch < im->channels; ++ch)
1260 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1262 return i_ppix(im, x, y, &temp);
1266 =item i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1270 int i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix) {
1274 if (i_gpix(im, x, y, &temp) == 0) {
1275 for (ch = 0; ch < im->channels; ++ch)
1276 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1284 =item i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1289 i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *pix) {
1292 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1299 work = mymalloc(sizeof(i_color) * (r-l));
1300 for (i = 0; i < r-l; ++i) {
1301 for (ch = 0; ch < im->channels; ++ch)
1302 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1304 ret = i_plin(im, l, r, y, work);
1319 =item i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1324 i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix) {
1327 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1334 work = mymalloc(sizeof(i_color) * (r-l));
1335 ret = i_plin(im, l, r, y, work);
1336 for (i = 0; i < r-l; ++i) {
1337 for (ch = 0; ch < im->channels; ++ch)
1338 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1354 =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)
1360 i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
1361 int const *chans, int chan_count) {
1364 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1370 work = mymalloc(sizeof(i_sample_t) * (r-l));
1371 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1372 for (i = 0; i < ret; ++i) {
1373 samp[i] = Sample8ToF(work[i]);
1391 =head2 Palette wrapper functions
1393 Used for virtual images, these forward palette calls to a wrapped image,
1394 assuming the wrapped image is the first pointer in the structure that
1395 im->ext_data points at.
1399 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1403 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1404 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1408 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1412 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1413 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1417 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1421 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1422 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1426 =item i_colorcount_forward(i_img *im)
1430 int i_colorcount_forward(i_img *im) {
1431 return i_colorcount(*(i_img **)im->ext_data);
1435 =item i_maxcolors_forward(i_img *im)
1439 int i_maxcolors_forward(i_img *im) {
1440 return i_maxcolors(*(i_img **)im->ext_data);
1444 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1448 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1449 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1455 =head2 Fallback handler
1459 =item i_gsamp_bits_fb
1465 i_gsamp_bits_fb(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps,
1466 const int *chans, int chan_count, int bits) {
1469 if (bits < 1 || bits > 32) {
1470 i_push_error(0, "Invalid bits, must be 1..32");
1474 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1477 i_img_dim count, i, w;
1480 scale = 4294967295.0;
1482 scale = (double)(1 << bits) - 1;
1490 /* make sure we have good channel numbers */
1491 for (ch = 0; ch < chan_count; ++ch) {
1492 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1493 im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
1497 for (i = 0; i < w; ++i) {
1499 i_gpixf(im, l+i, y, &c);
1500 for (ch = 0; ch < chan_count; ++ch) {
1501 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1507 if (chan_count <= 0 || chan_count > im->channels) {
1508 i_push_error(0, "Invalid channel count");
1511 for (i = 0; i < w; ++i) {
1513 i_gpixf(im, l+i, y, &c);
1514 for (ch = 0; ch < chan_count; ++ch) {
1515 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1524 i_push_error(0, "Image position outside of image");
1529 struct magic_entry {
1530 unsigned char *magic;
1533 unsigned char *mask;
1537 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
1538 if (length < magic->magic_size)
1542 unsigned char *bufp = buffer,
1543 *maskp = magic->mask,
1544 *magicp = magic->magic;
1546 for (i = 0; i < magic->magic_size; ++i) {
1547 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
1550 if ((*bufp++ & mask) != (*magicp++ & mask))
1557 return !memcmp(magic->magic, buffer, magic->magic_size);
1562 =item i_test_format_probe(io_glue *data, int length)
1564 Check the beginning of the supplied file for a 'magic number'
1569 #define FORMAT_ENTRY(magic, type) \
1570 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
1571 #define FORMAT_ENTRY2(magic, type, mask) \
1572 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
1575 i_test_format_probe(io_glue *data, int length) {
1576 static const struct magic_entry formats[] = {
1577 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
1578 FORMAT_ENTRY("GIF87a", "gif"),
1579 FORMAT_ENTRY("GIF89a", "gif"),
1580 FORMAT_ENTRY("MM\0*", "tiff"),
1581 FORMAT_ENTRY("II*\0", "tiff"),
1582 FORMAT_ENTRY("BM", "bmp"),
1583 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
1584 FORMAT_ENTRY("P1", "pnm"),
1585 FORMAT_ENTRY("P2", "pnm"),
1586 FORMAT_ENTRY("P3", "pnm"),
1587 FORMAT_ENTRY("P4", "pnm"),
1588 FORMAT_ENTRY("P5", "pnm"),
1589 FORMAT_ENTRY("P6", "pnm"),
1590 FORMAT_ENTRY("/* XPM", "xpm"),
1591 FORMAT_ENTRY("\x8aMNG", "mng"),
1592 FORMAT_ENTRY("\x8aJNG", "jng"),
1593 /* SGI RGB - with various possible parameters to avoid false positives
1595 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
1597 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
1598 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
1599 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
1600 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
1602 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
1604 /* different versions of PCX format
1605 http://www.fileformat.info/format/pcx/
1607 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
1608 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
1609 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
1610 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
1611 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
1613 /* FITS - http://fits.gsfc.nasa.gov/ */
1614 FORMAT_ENTRY("SIMPLE =", "fits"),
1616 /* PSD - Photoshop */
1617 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
1619 /* EPS - Encapsulated Postscript */
1620 /* only reading 18 chars, so we don't include the F in EPSF */
1621 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
1624 FORMAT_ENTRY("\x52\xCC", "utah"),
1626 /* GZIP compressed, only matching deflate for now */
1627 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
1629 /* bzip2 compressed */
1630 FORMAT_ENTRY("BZh", "bzip2"),
1633 http://code.google.com/speed/webp/docs/riff_container.html */
1634 FORMAT_ENTRY2("RIFF WEBP", "webp", "xxxx xxxx"),
1637 This might match a little loosely */
1638 FORMAT_ENTRY("\x00\x00\x00\x0CjP \x0D\x0A\x87\x0A", "jp2"),
1640 static const struct magic_entry more_formats[] = {
1641 /* these were originally both listed as ico, but cur files can
1642 include hotspot information */
1643 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
1644 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
1645 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
1646 "xwd", " xxxx"), /* X Windows Dump */
1650 unsigned char head[18];
1653 rc = i_io_peekn(data, head, 18);
1654 if (rc == -1) return NULL;
1658 fprintf(stderr, "%d bytes -", (int)rc);
1659 for (i = 0; i < rc; ++i)
1660 fprintf(stderr, " %02x", head[i]);
1661 fprintf(stderr, "\n");
1665 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
1666 struct magic_entry const *entry = formats + i;
1668 if (test_magic(head, rc, entry))
1673 tga_header_verify(head))
1676 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
1677 struct magic_entry const *entry = more_formats + i;
1679 if (test_magic(head, rc, entry))
1687 =item i_img_is_monochrome(img, &zero_is_white)
1689 =category Image Information
1691 Tests an image to check it meets our monochrome tests.
1693 The idea is that a file writer can use this to test where it should
1694 write the image in whatever bi-level format it uses, eg. C<pbm> for
1697 For performance of encoders we require monochrome images:
1707 have a palette of two colors, containing only C<(0,0,0)> and
1708 C<(255,255,255)> in either order.
1712 C<zero_is_white> is set to non-zero if the first palette entry is white.
1718 i_img_is_monochrome(i_img *im, int *zero_is_white) {
1719 if (im->type == i_palette_type
1720 && i_colorcount(im) == 2) {
1722 i_getcolors(im, 0, colors, 2);
1723 if (im->channels == 3) {
1724 if (colors[0].rgb.r == 255 &&
1725 colors[0].rgb.g == 255 &&
1726 colors[0].rgb.b == 255 &&
1727 colors[1].rgb.r == 0 &&
1728 colors[1].rgb.g == 0 &&
1729 colors[1].rgb.b == 0) {
1733 else if (colors[0].rgb.r == 0 &&
1734 colors[0].rgb.g == 0 &&
1735 colors[0].rgb.b == 0 &&
1736 colors[1].rgb.r == 255 &&
1737 colors[1].rgb.g == 255 &&
1738 colors[1].rgb.b == 255) {
1743 else if (im->channels == 1) {
1744 if (colors[0].channel[0] == 255 &&
1745 colors[1].channel[0] == 0) {
1749 else if (colors[0].channel[0] == 0 &&
1750 colors[1].channel[0] == 255) {
1762 =item i_get_file_background(im, &bg)
1766 Retrieve the file write background color tag from the image.
1768 If not present, C<bg> is set to black.
1770 Returns 1 if the C<i_background> tag was found and valid.
1776 i_get_file_background(i_img *im, i_color *bg) {
1777 int result = i_tags_get_color(&im->tags, "i_background", 0, bg);
1780 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
1782 /* always full alpha */
1783 bg->channel[3] = 255;
1789 =item i_get_file_backgroundf(im, &bg)
1793 Retrieve the file write background color tag from the image as a
1794 floating point color.
1796 Implemented in terms of i_get_file_background().
1798 If not present, C<bg> is set to black.
1800 Returns 1 if the C<i_background> tag was found and valid.
1806 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
1808 int result = i_get_file_background(im, &bg);
1809 fbg->rgba.r = Sample8ToF(bg.rgba.r);
1810 fbg->rgba.g = Sample8ToF(bg.rgba.g);
1811 fbg->rgba.b = Sample8ToF(bg.rgba.b);
1822 Arnar M. Hrafnkelsson <addi@umich.edu>
1824 Tony Cook <tonyc@cpan.org>