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 writeable
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)) {
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");
1495 =head2 Stream reading and writing wrapper functions
1499 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1501 Performs general read buffering for file readers that permit reading
1502 to be done through a callback.
1504 The final callback gets two parameters, a I<need> value, and a I<want>
1505 value, where I<need> is the amount of data that the file library needs
1506 to read, and I<want> is the amount of space available in the buffer
1507 maintained by these functions.
1509 This means if you need to read from a stream that you don't know the
1510 length of, you can return I<need> bytes, taking the performance hit of
1511 possibly expensive callbacks (eg. back to perl code), or if you are
1512 reading from a stream where it doesn't matter if some data is lost, or
1513 if the total length of the stream is known, you can return I<want>
1520 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1523 if (length < gci->length - gci->cpos) {
1525 memcpy(buf, gci->buffer+gci->cpos, length);
1526 gci->cpos += length;
1531 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1532 total += gci->length - gci->cpos;
1533 length -= gci->length - gci->cpos;
1534 buf += gci->length - gci->cpos;
1535 if (length < (int)sizeof(gci->buffer)) {
1539 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
1540 sizeof(gci->buffer))) > 0) {
1542 gci->length = did_read;
1544 copy_size = i_min(length, gci->length);
1545 memcpy(buf, gci->buffer, copy_size);
1546 gci->cpos += copy_size;
1549 length -= copy_size;
1553 /* just read the rest - too big for our buffer*/
1555 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
1565 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
1567 For use by callback file readers to initialize the reader buffer.
1569 Allocates, initializes and returns the reader buffer.
1571 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
1576 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
1577 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
1579 self->userdata = userdata;
1587 =item i_free_gen_read_data(i_gen_read_data *)
1593 void i_free_gen_read_data(i_gen_read_data *self) {
1598 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
1600 Performs write buffering for a callback based file writer.
1602 Failures are considered fatal, if a write fails then data will be
1609 i_gen_write_data *self,
1613 if (self->filledto && self->filledto+size > self->maxlength) {
1614 if (self->cb(self->userdata, self->buffer, self->filledto)) {
1622 if (self->filledto+size <= self->maxlength) {
1624 memcpy(self->buffer+self->filledto, data, size);
1625 self->filledto += size;
1628 /* doesn't fit - hand it off */
1629 return self->cb(self->userdata, data, size);
1633 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
1635 Allocates and initializes the data structure used by i_gen_writer.
1637 This should be released with L<image.c/i_free_gen_write_data>
1641 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
1642 char *userdata, int max_length)
1644 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
1646 self->userdata = userdata;
1647 self->maxlength = i_min(max_length, sizeof(self->buffer));
1648 if (self->maxlength < 0)
1649 self->maxlength = sizeof(self->buffer);
1656 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
1658 Cleans up the write buffer.
1660 Will flush any left-over data if I<flush> is non-zero.
1662 Returns non-zero if flush is zero or if info->cb() returns non-zero.
1664 Return zero only if flush is non-zero and info->cb() returns zero.
1670 int i_free_gen_write_data(i_gen_write_data *info, int flush)
1672 int result = !flush ||
1673 info->filledto == 0 ||
1674 info->cb(info->userdata, info->buffer, info->filledto);
1680 struct magic_entry {
1681 unsigned char *magic;
1684 unsigned char *mask;
1688 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
1689 if (length < magic->magic_size)
1693 unsigned char *bufp = buffer,
1694 *maskp = magic->mask,
1695 *magicp = magic->magic;
1697 for (i = 0; i < magic->magic_size; ++i) {
1698 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
1701 if ((*bufp++ & mask) != (*magicp++ & mask))
1708 return !memcmp(magic->magic, buffer, magic->magic_size);
1713 =item i_test_format_probe(io_glue *data, int length)
1715 Check the beginning of the supplied file for a 'magic number'
1720 #define FORMAT_ENTRY(magic, type) \
1721 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
1722 #define FORMAT_ENTRY2(magic, type, mask) \
1723 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
1726 i_test_format_probe(io_glue *data, int length) {
1727 static const struct magic_entry formats[] = {
1728 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
1729 FORMAT_ENTRY("GIF87a", "gif"),
1730 FORMAT_ENTRY("GIF89a", "gif"),
1731 FORMAT_ENTRY("MM\0*", "tiff"),
1732 FORMAT_ENTRY("II*\0", "tiff"),
1733 FORMAT_ENTRY("BM", "bmp"),
1734 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
1735 FORMAT_ENTRY("P1", "pnm"),
1736 FORMAT_ENTRY("P2", "pnm"),
1737 FORMAT_ENTRY("P3", "pnm"),
1738 FORMAT_ENTRY("P4", "pnm"),
1739 FORMAT_ENTRY("P5", "pnm"),
1740 FORMAT_ENTRY("P6", "pnm"),
1741 FORMAT_ENTRY("/* XPM", "xpm"),
1742 FORMAT_ENTRY("\x8aMNG", "mng"),
1743 FORMAT_ENTRY("\x8aJNG", "jng"),
1744 /* SGI RGB - with various possible parameters to avoid false positives
1746 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
1748 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
1749 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
1750 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
1751 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
1753 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
1755 /* different versions of PCX format
1756 http://www.fileformat.info/format/pcx/
1758 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
1759 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
1760 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
1761 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
1762 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
1764 /* FITS - http://fits.gsfc.nasa.gov/ */
1765 FORMAT_ENTRY("SIMPLE =", "fits"),
1767 /* PSD - Photoshop */
1768 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
1770 /* EPS - Encapsulated Postscript */
1771 /* only reading 18 chars, so we don't include the F in EPSF */
1772 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
1775 FORMAT_ENTRY("\x52\xCC", "utah"),
1777 /* GZIP compressed, only matching deflate for now */
1778 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
1780 /* bzip2 compressed */
1781 FORMAT_ENTRY("BZh", "bzip2"),
1784 http://code.google.com/speed/webp/docs/riff_container.html */
1785 FORMAT_ENTRY2("RIFF WEBP", "webp", "xxxx xxxx"),
1788 This might match a little loosely */
1789 FORMAT_ENTRY("\x00\x00\x00\x0CjP \x0D\x0A\x87\x0A", "jp2"),
1791 static const struct magic_entry more_formats[] = {
1792 /* these were originally both listed as ico, but cur files can
1793 include hotspot information */
1794 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
1795 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
1796 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
1797 "xwd", " xxxx"), /* X Windows Dump */
1801 unsigned char head[18];
1804 io_glue_commit_types(data);
1805 rc = data->readcb(data, head, 18);
1806 if (rc == -1) return NULL;
1807 data->seekcb(data, -rc, SEEK_CUR);
1809 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
1810 struct magic_entry const *entry = formats + i;
1812 if (test_magic(head, rc, entry))
1817 tga_header_verify(head))
1820 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
1821 struct magic_entry const *entry = more_formats + i;
1823 if (test_magic(head, rc, entry))
1831 =item i_img_is_monochrome(img, &zero_is_white)
1833 =category Image Information
1835 Tests an image to check it meets our monochrome tests.
1837 The idea is that a file writer can use this to test where it should
1838 write the image in whatever bi-level format it uses, eg. C<pbm> for
1841 For performance of encoders we require monochrome images:
1851 have a palette of two colors, containing only C<(0,0,0)> and
1852 C<(255,255,255)> in either order.
1856 C<zero_is_white> is set to non-zero if the first palette entry is white.
1862 i_img_is_monochrome(i_img *im, int *zero_is_white) {
1863 if (im->type == i_palette_type
1864 && i_colorcount(im) == 2) {
1866 i_getcolors(im, 0, colors, 2);
1867 if (im->channels == 3) {
1868 if (colors[0].rgb.r == 255 &&
1869 colors[0].rgb.g == 255 &&
1870 colors[0].rgb.b == 255 &&
1871 colors[1].rgb.r == 0 &&
1872 colors[1].rgb.g == 0 &&
1873 colors[1].rgb.b == 0) {
1877 else if (colors[0].rgb.r == 0 &&
1878 colors[0].rgb.g == 0 &&
1879 colors[0].rgb.b == 0 &&
1880 colors[1].rgb.r == 255 &&
1881 colors[1].rgb.g == 255 &&
1882 colors[1].rgb.b == 255) {
1887 else if (im->channels == 1) {
1888 if (colors[0].channel[0] == 255 &&
1889 colors[1].channel[0] == 0) {
1893 else if (colors[0].channel[0] == 0 &&
1894 colors[1].channel[0] == 255) {
1906 =item i_get_file_background(im, &bg)
1910 Retrieve the file write background color tag from the image.
1912 If not present, returns black.
1918 i_get_file_background(i_img *im, i_color *bg) {
1919 if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
1921 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
1923 /* always full alpha */
1924 bg->channel[3] = 255;
1928 =item i_get_file_backgroundf(im, &bg)
1932 Retrieve the file write background color tag from the image as a
1933 floating point color.
1935 Implemented in terms of i_get_file_background().
1937 If not present, returns black.
1943 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
1946 i_get_file_background(im, &bg);
1947 fbg->rgba.r = Sample8ToF(bg.rgba.r);
1948 fbg->rgba.g = Sample8ToF(bg.rgba.g);
1949 fbg->rgba.b = Sample8ToF(bg.rgba.b);
1958 Arnar M. Hrafnkelsson <addi@umich.edu>
1960 Tony Cook <tonyc@cpan.org>