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 void i_linker_bug_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* %p)\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, i_img_dim *info) {
300 mm_log((1,"i_img_info(im %p)\n",im));
302 mm_log((1,"i_img_info: xsize=%" i_DF " ysize=%" i_DF " channels=%d "
304 i_DFc(im->xsize), i_DFc(im->ysize), im->channels,im->ch_mask));
305 mm_log((1,"i_img_info: idata=%p\n",im->idata));
308 info[2] = im->channels;
309 info[3] = im->ch_mask;
319 =item i_img_setmask(C<im>, C<ch_mask>)
320 =category Image Information
321 =synopsis // only channel 0 writable
322 =synopsis i_img_setmask(img, 0x01);
324 Set the image channel mask for C<im> to C<ch_mask>.
326 The image channel mask gives some control over which channels can be
327 written to in the image.
332 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
336 =item i_img_getmask(C<im>)
337 =category Image Information
338 =synopsis int mask = i_img_getmask(img);
340 Get the image channel mask for C<im>.
345 i_img_getmask(i_img *im) { return im->ch_mask; }
348 =item i_img_getchannels(C<im>)
349 =category Image Information
350 =synopsis int channels = i_img_getchannels(img);
352 Get the number of channels in C<im>.
357 i_img_getchannels(i_img *im) { return im->channels; }
360 =item i_img_get_width(C<im>)
361 =category Image Information
362 =synopsis i_img_dim width = i_img_get_width(im);
364 Returns the width in pixels of the image.
369 i_img_get_width(i_img *im) {
374 =item i_img_get_height(C<im>)
375 =category Image Information
376 =synopsis i_img_dim height = i_img_get_height(im);
378 Returns the height in pixels of the image.
383 i_img_get_height(i_img *im) {
388 =item i_copyto_trans(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
392 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
393 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
394 the target image. pass NULL in C<trans> for non transparent i_colors.
400 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) {
402 i_img_dim x,y,t,ttx,tty,tt;
405 mm_log((1,"i_copyto_trans(im* %p,src %p, p1(" i_DFp "), p2(" i_DFp "), "
406 "to(" i_DFp "), trans* %p)\n",
407 im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty), trans));
409 if (x2<x1) { t=x1; x1=x2; x2=t; }
410 if (y2<y1) { t=y1; y1=y2; y2=t; }
422 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
423 if (tt) i_ppix(im,ttx,tty,&pv);
424 } else i_ppix(im,ttx,tty,&pv);
436 Creates a new image that is a copy of the image C<source>.
438 Tags are not copied, only the image data.
448 i_img *im = i_sametype(src, src->xsize, src->ysize);
450 mm_log((1,"i_copy(src %p)\n", src));
457 if (src->type == i_direct_type) {
458 if (src->bits == i_8_bits) {
460 pv = mymalloc(sizeof(i_color) * x1);
462 for (y = 0; y < y1; ++y) {
463 i_glin(src, 0, x1, y, pv);
464 i_plin(im, 0, x1, y, pv);
471 pv = mymalloc(sizeof(i_fcolor) * x1);
472 for (y = 0; y < y1; ++y) {
473 i_glinf(src, 0, x1, y, pv);
474 i_plinf(im, 0, x1, y, pv);
482 vals = mymalloc(sizeof(i_palidx) * x1);
483 for (y = 0; y < y1; ++y) {
484 i_gpal(src, 0, x1, y, vals);
485 i_ppal(im, 0, x1, y, vals);
495 http://en.wikipedia.org/wiki/Lanczos_resampling
507 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
508 else if (x == 0.0) return (1.0);
509 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
514 =item i_scaleaxis(im, value, axis)
516 Returns a new image object which is I<im> scaled by I<value> along
517 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
523 i_scaleaxis(i_img *im, double Value, int Axis) {
524 i_img_dim hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
525 i_img_dim LanczosWidthFactor;
530 float F, PictureValue[MAXCHANNELS];
532 i_color val,val1,val2;
534 int has_alpha = i_img_has_alpha(im);
535 int color_chans = i_img_color_channels(im);
538 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
541 hsize = (i_img_dim)(0.5 + im->xsize * Value);
544 Value = 1.0 / im->xsize;
552 vsize = (i_img_dim)(0.5 + im->ysize * Value);
556 Value = 1.0 / im->ysize;
563 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
565 i_push_error(0, "cannot create output image");
569 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
570 LanczosWidthFactor = (Value >= 1) ? 1 : (i_img_dim) (1.4/Value);
571 lMax = LanczosWidthFactor << 1;
573 l0 = mymalloc(lMax * sizeof(float));
574 l1 = mymalloc(lMax * sizeof(float));
576 for (j=0; j<jEnd; j++) {
577 OldLocation = ((double) j) / Value;
578 T = (i_img_dim) (OldLocation);
581 for (l = 0; l<lMax; l++) {
582 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
583 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
586 /* Make sure filter is normalized */
588 for(l=0; l<lMax; l++) {
592 t /= (double)LanczosWidthFactor;
594 for(l=0; l<lMax; l++) {
601 for (i=0; i<iEnd; i++) {
602 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
603 for (l=0; l<lMax; l++) {
604 i_img_dim mx = T-lMax+l+1;
605 i_img_dim Mx = T+l+1;
606 mx = (mx < 0) ? 0 : mx;
607 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
609 i_gpix(im, Mx, i, &val1);
610 i_gpix(im, mx, i, &val2);
613 i_sample_t alpha1 = val1.channel[color_chans];
614 i_sample_t alpha2 = val2.channel[color_chans];
615 for (k=0; k < color_chans; k++) {
616 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
617 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
619 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
620 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
623 for (k=0; k<im->channels; k++) {
624 PictureValue[k] += l1[l] * val1.channel[k];
625 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
631 float fa = PictureValue[color_chans] / LanczosWidthFactor;
632 int alpha = minmax(0, 255, fa+0.5);
634 for (k = 0; k < color_chans; ++k) {
635 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
636 val.channel[k]=minmax(0,255,psave);
638 val.channel[color_chans] = alpha;
641 /* zero alpha, so the pixel has no color */
642 for (k = 0; k < im->channels; ++k)
647 for(k=0;k<im->channels;k++) {
648 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
649 val.channel[k]=minmax(0,255,psave);
652 i_ppix(new_img, j, i, &val);
657 for (i=0; i<iEnd; i++) {
658 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
659 for (l=0; l < lMax; l++) {
660 i_img_dim mx = T-lMax+l+1;
661 i_img_dim Mx = T+l+1;
662 mx = (mx < 0) ? 0 : mx;
663 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
665 i_gpix(im, i, Mx, &val1);
666 i_gpix(im, i, mx, &val2);
668 i_sample_t alpha1 = val1.channel[color_chans];
669 i_sample_t alpha2 = val2.channel[color_chans];
670 for (k=0; k < color_chans; k++) {
671 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
672 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
674 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
675 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
678 for (k=0; k<im->channels; k++) {
679 PictureValue[k] += l1[l] * val1.channel[k];
680 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
685 float fa = PictureValue[color_chans] / LanczosWidthFactor;
686 int alpha = minmax(0, 255, fa+0.5);
688 for (k = 0; k < color_chans; ++k) {
689 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
690 val.channel[k]=minmax(0,255,psave);
692 val.channel[color_chans] = alpha;
695 for (k = 0; k < im->channels; ++k)
700 for(k=0;k<im->channels;k++) {
701 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
702 val.channel[k]=minmax(0,255,psave);
705 i_ppix(new_img, i, j, &val);
713 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
720 =item i_scale_nn(im, scx, scy)
722 Scale by using nearest neighbor
723 Both axes scaled at the same time since
724 nothing is gained by doing it in two steps
731 i_scale_nn(i_img *im, double scx, double scy) {
733 i_img_dim nxsize,nysize,nx,ny;
737 mm_log((1,"i_scale_nn(im %p,scx %.2f,scy %.2f)\n",im,scx,scy));
739 nxsize = (i_img_dim) ((double) im->xsize * scx);
742 scx = 1.0 / im->xsize;
744 nysize = (i_img_dim) ((double) im->ysize * scy);
747 scy = 1.0 / im->ysize;
749 im_assert(scx != 0 && scy != 0);
751 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
753 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
754 i_gpix(im,((double)nx)/scx,((double)ny)/scy,&val);
755 i_ppix(new_img,nx,ny,&val);
758 mm_log((1,"(%p) <- i_scale_nn\n",new_img));
764 =item i_sametype(C<im>, C<xsize>, C<ysize>)
766 =category Image creation/destruction
767 =synopsis i_img *img = i_sametype(src, width, height);
769 Returns an image of the same type (sample size, channels, paletted/direct).
771 For paletted images the palette is copied from the source.
776 i_img *i_sametype(i_img *src, i_img_dim xsize, i_img_dim ysize) {
777 if (src->type == i_direct_type) {
778 if (src->bits == 8) {
779 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
781 else if (src->bits == i_16_bits) {
782 return i_img_16_new(xsize, ysize, src->channels);
784 else if (src->bits == i_double_bits) {
785 return i_img_double_new(xsize, ysize, src->channels);
788 i_push_error(0, "Unknown image bits");
796 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
797 for (i = 0; i < i_colorcount(src); ++i) {
798 i_getcolors(src, i, &col, 1);
799 i_addcolors(targ, &col, 1);
807 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
809 =category Image creation/destruction
810 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
812 Returns an image of the same type (sample size).
814 For paletted images the equivalent direct type is returned.
819 i_img *i_sametype_chans(i_img *src, i_img_dim xsize, i_img_dim ysize, int channels) {
820 if (src->bits == 8) {
821 return i_img_empty_ch(NULL, xsize, ysize, channels);
823 else if (src->bits == i_16_bits) {
824 return i_img_16_new(xsize, ysize, channels);
826 else if (src->bits == i_double_bits) {
827 return i_img_double_new(xsize, ysize, channels);
830 i_push_error(0, "Unknown image bits");
836 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
838 Spatially transforms I<im> returning a new image.
840 opx for a length of opxl and opy for a length of opy are arrays of
841 operators that modify the x and y positions to retreive the pixel data from.
843 parm and parmlen define extra parameters that the operators may use.
845 Note that this function is largely superseded by the more flexible
846 L<transform.c/i_transform2>.
848 Returns the new image.
850 The operators for this function are defined in L<stackmach.c>.
855 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
857 i_img_dim nxsize,nysize,nx,ny;
861 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));
866 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
867 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
868 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
869 /* parm[parmlen-2]=(double)nx;
870 parm[parmlen-1]=(double)ny; */
875 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
876 rx=i_op_run(opx,opxl,parm,parmlen);
877 ry=i_op_run(opy,opyl,parm,parmlen);
878 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
879 i_gpix(im,rx,ry,&val);
880 i_ppix(new_img,nx,ny,&val);
883 mm_log((1,"(%p) <- i_transform\n",new_img));
888 =item i_img_diff(im1, im2)
890 Calculates the sum of the squares of the differences between
891 correspoding channels in two images.
893 If the images are not the same size then only the common area is
894 compared, hence even if images are different sizes this function
901 i_img_diff(i_img *im1,i_img *im2) {
902 i_img_dim x, y, xb, yb;
907 mm_log((1,"i_img_diff(im1 %p,im2 %p)\n",im1,im2));
909 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
910 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
911 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
913 mm_log((1,"i_img_diff: b=(" i_DFp ") chb=%d\n",
914 i_DFcp(xb,yb), chb));
917 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
918 i_gpix(im1,x,y,&val1);
919 i_gpix(im2,x,y,&val2);
921 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
923 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
928 =item i_img_diffd(im1, im2)
930 Calculates the sum of the squares of the differences between
931 correspoding channels in two images.
933 If the images are not the same size then only the common area is
934 compared, hence even if images are different sizes this function
937 This is like i_img_diff() but looks at floating point samples instead.
943 i_img_diffd(i_img *im1,i_img *im2) {
944 i_img_dim x, y, xb, yb;
949 mm_log((1,"i_img_diffd(im1 %p,im2 %p)\n",im1,im2));
951 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
952 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
953 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
955 mm_log((1,"i_img_diffd: b(" i_DFp ") chb=%d\n",
956 i_DFcp(xb, yb), chb));
959 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
960 i_gpixf(im1,x,y,&val1);
961 i_gpixf(im2,x,y,&val2);
963 for(ch=0;ch<chb;ch++) {
964 double sdiff = val1.channel[ch]-val2.channel[ch];
965 tdiff += sdiff * sdiff;
968 mm_log((1,"i_img_diffd <- (%.2f)\n",tdiff));
974 i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
982 mm_log((1,"i_img_samef(im1 %p,im2 %p, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
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 mm_log((1,"i_img_samef: b(" i_DFp ") chb=%d\n",
989 i_DFcp(xb, yb), chb));
991 for(y = 0; y < yb; y++) {
992 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 if (fabs(sdiff) > epsilon) {
999 mm_log((1,"i_img_samef <- different %g @(" i_DFp ")\n",
1000 sdiff, i_DFcp(x, y)));
1006 mm_log((1,"i_img_samef <- same\n"));
1011 /* just a tiny demo of haar wavelets */
1019 i_img *new_img,*new_img2;
1020 i_color val1,val2,dval1,dval2;
1028 /* horizontal pass */
1030 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1031 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1034 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1035 i_gpix(im,x*2,y,&val1);
1036 i_gpix(im,x*2+1,y,&val2);
1037 for(ch=0;ch<im->channels;ch++) {
1038 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1039 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1041 i_ppix(new_img,x,y,&dval1);
1042 i_ppix(new_img,x+fx,y,&dval2);
1045 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1046 i_gpix(new_img,x,y*2,&val1);
1047 i_gpix(new_img,x,y*2+1,&val2);
1048 for(ch=0;ch<im->channels;ch++) {
1049 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1050 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1052 i_ppix(new_img2,x,y,&dval1);
1053 i_ppix(new_img2,x,y+fy,&dval2);
1056 i_img_destroy(new_img);
1061 =item i_count_colors(im, maxc)
1063 returns number of colors or -1
1064 to indicate that it was more than max colors
1068 /* This function has been changed and is now faster. It's using
1069 * i_gsamp instead of i_gpix */
1071 i_count_colors(i_img *im,int maxc) {
1078 i_img_dim xsize = im->xsize;
1079 i_img_dim ysize = im->ysize;
1080 int samp_cnt = 3 * xsize;
1082 if (im->channels >= 3) {
1086 channels[0] = channels[1] = channels[2] = 0;
1087 samp_chans = channels;
1092 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1095 for(y = 0; y < ysize; ) {
1096 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1097 for(x = 0; x < samp_cnt; ) {
1098 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1100 if (colorcnt > maxc) {
1111 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1112 * (adapted from the Numerical Recipes)
1114 /* Needed by get_anonymous_color_histo */
1116 hpsort(unsigned int n, unsigned *ra) {
1141 if (j < ir && ra[j] < ra[j+1]) j++;
1153 /* This function constructs an ordered list which represents how much the
1154 * different colors are used. So for instance (100, 100, 500) means that one
1155 * color is used for 500 pixels, another for 100 pixels and another for 100
1156 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1157 * the maxc ;-) and you might want to change the name... */
1158 /* Uses octt_histo */
1160 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1164 unsigned int *col_usage_it;
1169 i_img_dim xsize = im->xsize;
1170 i_img_dim ysize = im->ysize;
1171 int samp_cnt = 3 * xsize;
1174 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1176 if (im->channels >= 3) {
1180 channels[0] = channels[1] = channels[2] = 0;
1181 samp_chans = channels;
1185 for(y = 0; y < ysize; ) {
1186 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1187 for(x = 0; x < samp_cnt; ) {
1188 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1190 if (colorcnt > maxc) {
1197 /* Now that we know the number of colours... */
1198 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1199 octt_histo(ct, &col_usage_it);
1200 hpsort(colorcnt, *col_usage);
1208 =head2 Image method wrappers
1210 These functions provide i_fsample_t functions in terms of their
1211 i_sample_t versions.
1215 =item i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1220 int i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix) {
1224 for (ch = 0; ch < im->channels; ++ch)
1225 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1227 return i_ppix(im, x, y, &temp);
1231 =item i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1235 int i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix) {
1239 if (i_gpix(im, x, y, &temp) == 0) {
1240 for (ch = 0; ch < im->channels; ++ch)
1241 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1249 =item i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1254 i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *pix) {
1257 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1264 work = mymalloc(sizeof(i_color) * (r-l));
1265 for (i = 0; i < r-l; ++i) {
1266 for (ch = 0; ch < im->channels; ++ch)
1267 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1269 ret = i_plin(im, l, r, y, work);
1284 =item i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1289 i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix) {
1292 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1299 work = mymalloc(sizeof(i_color) * (r-l));
1300 ret = i_plin(im, l, r, y, work);
1301 for (i = 0; i < r-l; ++i) {
1302 for (ch = 0; ch < im->channels; ++ch)
1303 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1319 =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)
1325 i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
1326 int const *chans, int chan_count) {
1329 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1335 work = mymalloc(sizeof(i_sample_t) * (r-l));
1336 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1337 for (i = 0; i < ret; ++i) {
1338 samp[i] = Sample8ToF(work[i]);
1356 =head2 Palette wrapper functions
1358 Used for virtual images, these forward palette calls to a wrapped image,
1359 assuming the wrapped image is the first pointer in the structure that
1360 im->ext_data points at.
1364 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1368 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1369 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1373 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1377 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1378 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1382 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1386 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1387 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1391 =item i_colorcount_forward(i_img *im)
1395 int i_colorcount_forward(i_img *im) {
1396 return i_colorcount(*(i_img **)im->ext_data);
1400 =item i_maxcolors_forward(i_img *im)
1404 int i_maxcolors_forward(i_img *im) {
1405 return i_maxcolors(*(i_img **)im->ext_data);
1409 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1413 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1414 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1420 =head2 Fallback handler
1424 =item i_gsamp_bits_fb
1430 i_gsamp_bits_fb(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps,
1431 const int *chans, int chan_count, int bits) {
1432 if (bits < 1 || bits > 32) {
1433 i_push_error(0, "Invalid bits, must be 1..32");
1437 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1440 i_img_dim count, i, w;
1443 scale = 4294967295.0;
1445 scale = (double)(1 << bits) - 1;
1453 /* make sure we have good channel numbers */
1454 for (ch = 0; ch < chan_count; ++ch) {
1455 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1456 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1460 for (i = 0; i < w; ++i) {
1462 i_gpixf(im, l+i, y, &c);
1463 for (ch = 0; ch < chan_count; ++ch) {
1464 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1470 if (chan_count <= 0 || chan_count > im->channels) {
1471 i_push_error(0, "Invalid channel count");
1474 for (i = 0; i < w; ++i) {
1476 i_gpixf(im, l+i, y, &c);
1477 for (ch = 0; ch < chan_count; ++ch) {
1478 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1487 i_push_error(0, "Image position outside of image");
1492 struct magic_entry {
1493 unsigned char *magic;
1496 unsigned char *mask;
1500 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
1501 if (length < magic->magic_size)
1505 unsigned char *bufp = buffer,
1506 *maskp = magic->mask,
1507 *magicp = magic->magic;
1509 for (i = 0; i < magic->magic_size; ++i) {
1510 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
1513 if ((*bufp++ & mask) != (*magicp++ & mask))
1520 return !memcmp(magic->magic, buffer, magic->magic_size);
1525 =item i_test_format_probe(io_glue *data, int length)
1527 Check the beginning of the supplied file for a 'magic number'
1532 #define FORMAT_ENTRY(magic, type) \
1533 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
1534 #define FORMAT_ENTRY2(magic, type, mask) \
1535 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
1538 i_test_format_probe(io_glue *data, int length) {
1539 static const struct magic_entry formats[] = {
1540 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
1541 FORMAT_ENTRY("GIF87a", "gif"),
1542 FORMAT_ENTRY("GIF89a", "gif"),
1543 FORMAT_ENTRY("MM\0*", "tiff"),
1544 FORMAT_ENTRY("II*\0", "tiff"),
1545 FORMAT_ENTRY("BM", "bmp"),
1546 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
1547 FORMAT_ENTRY("P1", "pnm"),
1548 FORMAT_ENTRY("P2", "pnm"),
1549 FORMAT_ENTRY("P3", "pnm"),
1550 FORMAT_ENTRY("P4", "pnm"),
1551 FORMAT_ENTRY("P5", "pnm"),
1552 FORMAT_ENTRY("P6", "pnm"),
1553 FORMAT_ENTRY("/* XPM", "xpm"),
1554 FORMAT_ENTRY("\x8aMNG", "mng"),
1555 FORMAT_ENTRY("\x8aJNG", "jng"),
1556 /* SGI RGB - with various possible parameters to avoid false positives
1558 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
1560 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
1561 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
1562 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
1563 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
1565 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
1567 /* different versions of PCX format
1568 http://www.fileformat.info/format/pcx/
1570 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
1571 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
1572 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
1573 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
1574 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
1576 /* FITS - http://fits.gsfc.nasa.gov/ */
1577 FORMAT_ENTRY("SIMPLE =", "fits"),
1579 /* PSD - Photoshop */
1580 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
1582 /* EPS - Encapsulated Postscript */
1583 /* only reading 18 chars, so we don't include the F in EPSF */
1584 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
1587 FORMAT_ENTRY("\x52\xCC", "utah"),
1589 /* GZIP compressed, only matching deflate for now */
1590 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
1592 /* bzip2 compressed */
1593 FORMAT_ENTRY("BZh", "bzip2"),
1596 http://code.google.com/speed/webp/docs/riff_container.html */
1597 FORMAT_ENTRY2("RIFF WEBP", "webp", "xxxx xxxx"),
1600 This might match a little loosely */
1601 FORMAT_ENTRY("\x00\x00\x00\x0CjP \x0D\x0A\x87\x0A", "jp2"),
1603 static const struct magic_entry more_formats[] = {
1604 /* these were originally both listed as ico, but cur files can
1605 include hotspot information */
1606 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
1607 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
1608 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
1609 "xwd", " xxxx"), /* X Windows Dump */
1613 unsigned char head[18];
1616 rc = i_io_peekn(data, head, 18);
1617 if (rc == -1) return NULL;
1621 fprintf(stderr, "%d bytes -", (int)rc);
1622 for (i = 0; i < rc; ++i)
1623 fprintf(stderr, " %02x", head[i]);
1624 fprintf(stderr, "\n");
1628 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
1629 struct magic_entry const *entry = formats + i;
1631 if (test_magic(head, rc, entry))
1636 tga_header_verify(head))
1639 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
1640 struct magic_entry const *entry = more_formats + i;
1642 if (test_magic(head, rc, entry))
1650 =item i_img_is_monochrome(img, &zero_is_white)
1652 =category Image Information
1654 Tests an image to check it meets our monochrome tests.
1656 The idea is that a file writer can use this to test where it should
1657 write the image in whatever bi-level format it uses, eg. C<pbm> for
1660 For performance of encoders we require monochrome images:
1670 have a palette of two colors, containing only C<(0,0,0)> and
1671 C<(255,255,255)> in either order.
1675 C<zero_is_white> is set to non-zero if the first palette entry is white.
1681 i_img_is_monochrome(i_img *im, int *zero_is_white) {
1682 if (im->type == i_palette_type
1683 && i_colorcount(im) == 2) {
1685 i_getcolors(im, 0, colors, 2);
1686 if (im->channels == 3) {
1687 if (colors[0].rgb.r == 255 &&
1688 colors[0].rgb.g == 255 &&
1689 colors[0].rgb.b == 255 &&
1690 colors[1].rgb.r == 0 &&
1691 colors[1].rgb.g == 0 &&
1692 colors[1].rgb.b == 0) {
1696 else if (colors[0].rgb.r == 0 &&
1697 colors[0].rgb.g == 0 &&
1698 colors[0].rgb.b == 0 &&
1699 colors[1].rgb.r == 255 &&
1700 colors[1].rgb.g == 255 &&
1701 colors[1].rgb.b == 255) {
1706 else if (im->channels == 1) {
1707 if (colors[0].channel[0] == 255 &&
1708 colors[1].channel[0] == 0) {
1712 else if (colors[0].channel[0] == 0 &&
1713 colors[1].channel[0] == 255) {
1725 =item i_get_file_background(im, &bg)
1729 Retrieve the file write background color tag from the image.
1731 If not present, returns black.
1737 i_get_file_background(i_img *im, i_color *bg) {
1738 if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
1740 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
1742 /* always full alpha */
1743 bg->channel[3] = 255;
1747 =item i_get_file_backgroundf(im, &bg)
1751 Retrieve the file write background color tag from the image as a
1752 floating point color.
1754 Implemented in terms of i_get_file_background().
1756 If not present, returns black.
1762 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
1765 i_get_file_background(im, &bg);
1766 fbg->rgba.r = Sample8ToF(bg.rgba.r);
1767 fbg->rgba.g = Sample8ToF(bg.rgba.g);
1768 fbg->rgba.b = Sample8ToF(bg.rgba.b);
1777 Arnar M. Hrafnkelsson <addi@umich.edu>
1779 Tony Cook <tonyc@cpan.org>