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_img_color_model(im)
409 =category Image Information
410 =synopsis i_color_model_t cm = i_img_color_model(im);
412 Returns the color model for the image.
414 A future version of Imager will allow for images with extra channels
415 beyond gray/rgb and alpha.
420 i_img_color_model(i_img *im) {
421 return (i_color_model_t)im->channels;
425 =item i_img_alpha_channel(im, &channel)
426 =category Image Information
427 =synopsis int alpha_channel;
428 =synopsis int has_alpha = i_img_alpha_channel(im, &alpha_channel);
430 Work out the alpha channel for an image.
432 If the image has an alpha channel, sets C<*channel> to the alpha
433 channel index and returns non-zero.
435 If the image has no alpha channel, returns zero and C<*channel> is not
438 C<channel> may be C<NULL>.
444 i_img_alpha_channel(i_img *im, int *channel) {
445 i_color_model_t model = i_img_color_model(im);
449 if (channel) *channel = (int)model - 1;
458 =item i_img_color_channels(im)
459 =category Image Information
460 =synopsis int color_channels = i_img_color_channels(im);
462 Returns the number of color channels in the image. For now this is
463 always 1 (for grayscale) or 3 (for RGB) but may be 0 in some special
464 cases in a future release of Imager.
470 i_img_color_channels(i_img *im) {
471 i_color_model_t model = i_img_color_model(im);
475 return (int)model - 1;
487 =item i_copyto_trans(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
491 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
492 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
493 the target image. pass NULL in C<trans> for non transparent i_colors.
499 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) {
501 i_img_dim x,y,t,ttx,tty,tt;
505 im_log((aIMCTX, 1,"i_copyto_trans(im* %p,src %p, p1(" i_DFp "), p2(" i_DFp "), "
506 "to(" i_DFp "), trans* %p)\n",
507 im, src, i_DFcp(x1, y1), i_DFcp(x2, y2), i_DFcp(tx, ty), trans));
509 if (x2<x1) { t=x1; x1=x2; x2=t; }
510 if (y2<y1) { t=y1; y1=y2; y2=t; }
522 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
523 if (tt) i_ppix(im,ttx,tty,&pv);
524 } else i_ppix(im,ttx,tty,&pv);
536 Creates a new image that is a copy of the image C<source>.
538 Tags are not copied, only the image data.
549 i_img *im = i_sametype(src, src->xsize, src->ysize);
551 im_log((aIMCTX,1,"i_copy(src %p)\n", src));
558 if (src->type == i_direct_type) {
559 if (src->bits == i_8_bits) {
561 pv = mymalloc(sizeof(i_color) * x1);
563 for (y = 0; y < y1; ++y) {
564 i_glin(src, 0, x1, y, pv);
565 i_plin(im, 0, x1, y, pv);
572 pv = mymalloc(sizeof(i_fcolor) * x1);
573 for (y = 0; y < y1; ++y) {
574 i_glinf(src, 0, x1, y, pv);
575 i_plinf(im, 0, x1, y, pv);
583 vals = mymalloc(sizeof(i_palidx) * x1);
584 for (y = 0; y < y1; ++y) {
585 i_gpal(src, 0, x1, y, vals);
586 i_ppal(im, 0, x1, y, vals);
596 http://en.wikipedia.org/wiki/Lanczos_resampling
608 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
609 else if (x == 0.0) return (1.0);
610 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
615 =item i_scaleaxis(im, value, axis)
617 Returns a new image object which is I<im> scaled by I<value> along
618 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
624 i_scaleaxis(i_img *im, double Value, int Axis) {
625 i_img_dim hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
626 i_img_dim LanczosWidthFactor;
631 float F, PictureValue[MAXCHANNELS];
633 i_color val,val1,val2;
635 int has_alpha = i_img_has_alpha(im);
636 int color_chans = i_img_color_channels(im);
640 im_log((aIMCTX, 1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
643 hsize = (i_img_dim)(0.5 + im->xsize * Value);
646 Value = 1.0 / im->xsize;
654 vsize = (i_img_dim)(0.5 + im->ysize * Value);
658 Value = 1.0 / im->ysize;
665 new_img = i_img_8_new(hsize, vsize, im->channels);
667 i_push_error(0, "cannot create output image");
671 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
672 LanczosWidthFactor = (Value >= 1) ? 1 : (i_img_dim) (1.4/Value);
673 lMax = LanczosWidthFactor << 1;
675 l0 = mymalloc(lMax * sizeof(float));
676 l1 = mymalloc(lMax * sizeof(float));
678 for (j=0; j<jEnd; j++) {
679 OldLocation = ((double) j) / Value;
680 T = (i_img_dim) (OldLocation);
683 for (l = 0; l<lMax; l++) {
684 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
685 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
688 /* Make sure filter is normalized */
690 for(l=0; l<lMax; l++) {
694 t /= (double)LanczosWidthFactor;
696 for(l=0; l<lMax; l++) {
703 for (i=0; i<iEnd; i++) {
704 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
705 for (l=0; l<lMax; l++) {
706 i_img_dim mx = T-lMax+l+1;
707 i_img_dim Mx = T+l+1;
708 mx = (mx < 0) ? 0 : mx;
709 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
711 i_gpix(im, Mx, i, &val1);
712 i_gpix(im, mx, i, &val2);
715 i_sample_t alpha1 = val1.channel[color_chans];
716 i_sample_t alpha2 = val2.channel[color_chans];
717 for (k=0; k < color_chans; k++) {
718 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
719 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
721 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
722 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
725 for (k=0; k<im->channels; k++) {
726 PictureValue[k] += l1[l] * val1.channel[k];
727 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
733 float fa = PictureValue[color_chans] / LanczosWidthFactor;
734 int alpha = minmax(0, 255, fa+0.5);
736 for (k = 0; k < color_chans; ++k) {
737 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
738 val.channel[k]=minmax(0,255,psave);
740 val.channel[color_chans] = alpha;
743 /* zero alpha, so the pixel has no color */
744 for (k = 0; k < im->channels; ++k)
749 for(k=0;k<im->channels;k++) {
750 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
751 val.channel[k]=minmax(0,255,psave);
754 i_ppix(new_img, j, i, &val);
759 for (i=0; i<iEnd; i++) {
760 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
761 for (l=0; l < lMax; l++) {
762 i_img_dim mx = T-lMax+l+1;
763 i_img_dim Mx = T+l+1;
764 mx = (mx < 0) ? 0 : mx;
765 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
767 i_gpix(im, i, Mx, &val1);
768 i_gpix(im, i, mx, &val2);
770 i_sample_t alpha1 = val1.channel[color_chans];
771 i_sample_t alpha2 = val2.channel[color_chans];
772 for (k=0; k < color_chans; k++) {
773 PictureValue[k] += l1[l] * val1.channel[k] * alpha1 / 255;
774 PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
776 PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
777 PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
780 for (k=0; k<im->channels; k++) {
781 PictureValue[k] += l1[l] * val1.channel[k];
782 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
787 float fa = PictureValue[color_chans] / LanczosWidthFactor;
788 int alpha = minmax(0, 255, fa+0.5);
790 for (k = 0; k < color_chans; ++k) {
791 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
792 val.channel[k]=minmax(0,255,psave);
794 val.channel[color_chans] = alpha;
797 for (k = 0; k < im->channels; ++k)
802 for(k=0;k<im->channels;k++) {
803 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
804 val.channel[k]=minmax(0,255,psave);
807 i_ppix(new_img, i, j, &val);
815 im_log((aIMCTX, 1,"(%p) <- i_scaleaxis\n", new_img));
822 =item i_scale_nn(im, scx, scy)
824 Scale by using nearest neighbor
825 Both axes scaled at the same time since
826 nothing is gained by doing it in two steps
833 i_scale_nn(i_img *im, double scx, double scy) {
835 i_img_dim nxsize,nysize,nx,ny;
840 im_log((aIMCTX, 1,"i_scale_nn(im %p,scx %.2f,scy %.2f)\n",im,scx,scy));
842 nxsize = (i_img_dim) ((double) im->xsize * scx);
845 scx = 1.0 / im->xsize;
847 nysize = (i_img_dim) ((double) im->ysize * scy);
850 scy = 1.0 / im->ysize;
852 im_assert(scx != 0 && scy != 0);
854 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
856 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
857 i_gpix(im,((double)nx)/scx,((double)ny)/scy,&val);
858 i_ppix(new_img,nx,ny,&val);
861 im_log((aIMCTX, 1,"(%p) <- i_scale_nn\n",new_img));
867 =item i_sametype(C<im>, C<xsize>, C<ysize>)
869 =category Image creation/destruction
870 =synopsis i_img *img = i_sametype(src, width, height);
872 Returns an image of the same type (sample size, channels, paletted/direct).
874 For paletted images the palette is copied from the source.
880 i_sametype(i_img *src, i_img_dim xsize, i_img_dim ysize) {
883 if (src->type == i_direct_type) {
884 if (src->bits == 8) {
885 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
887 else if (src->bits == i_16_bits) {
888 return i_img_16_new(xsize, ysize, src->channels);
890 else if (src->bits == i_double_bits) {
891 return i_img_double_new(xsize, ysize, src->channels);
894 i_push_error(0, "Unknown image bits");
902 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
903 for (i = 0; i < i_colorcount(src); ++i) {
904 i_getcolors(src, i, &col, 1);
905 i_addcolors(targ, &col, 1);
913 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
915 =category Image creation/destruction
916 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
918 Returns an image of the same type (sample size).
920 For paletted images the equivalent direct type is returned.
926 i_sametype_chans(i_img *src, i_img_dim xsize, i_img_dim ysize, int channels) {
929 if (src->bits == 8) {
930 return i_img_empty_ch(NULL, xsize, ysize, channels);
932 else if (src->bits == i_16_bits) {
933 return i_img_16_new(xsize, ysize, channels);
935 else if (src->bits == i_double_bits) {
936 return i_img_double_new(xsize, ysize, channels);
939 i_push_error(0, "Unknown image bits");
945 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
947 Spatially transforms I<im> returning a new image.
949 opx for a length of opxl and opy for a length of opy are arrays of
950 operators that modify the x and y positions to retreive the pixel data from.
952 parm and parmlen define extra parameters that the operators may use.
954 Note that this function is largely superseded by the more flexible
955 L<transform.c/i_transform2>.
957 Returns the new image.
959 The operators for this function are defined in L<stackmach.c>.
964 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
966 i_img_dim nxsize,nysize,nx,ny;
971 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));
976 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
977 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
978 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
979 /* parm[parmlen-2]=(double)nx;
980 parm[parmlen-1]=(double)ny; */
985 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
986 rx=i_op_run(opx,opxl,parm,parmlen);
987 ry=i_op_run(opy,opyl,parm,parmlen);
988 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
989 i_gpix(im,rx,ry,&val);
990 i_ppix(new_img,nx,ny,&val);
993 im_log((aIMCTX, 1,"(%p) <- i_transform\n",new_img));
998 =item i_img_diff(im1, im2)
1000 Calculates the sum of the squares of the differences between
1001 correspoding channels in two images.
1003 If the images are not the same size then only the common area is
1004 compared, hence even if images are different sizes this function
1011 i_img_diff(i_img *im1,i_img *im2) {
1012 i_img_dim x, y, xb, yb;
1018 im_log((aIMCTX, 1,"i_img_diff(im1 %p,im2 %p)\n",im1,im2));
1020 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1021 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1022 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1024 im_log((aIMCTX, 1,"i_img_diff: b=(" i_DFp ") chb=%d\n",
1025 i_DFcp(xb,yb), chb));
1028 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1029 i_gpix(im1,x,y,&val1);
1030 i_gpix(im2,x,y,&val2);
1032 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1034 im_log((aIMCTX, 1,"i_img_diff <- (%.2f)\n",tdiff));
1039 =item i_img_diffd(im1, im2)
1041 Calculates the sum of the squares of the differences between
1042 correspoding channels in two images.
1044 If the images are not the same size then only the common area is
1045 compared, hence even if images are different sizes this function
1048 This is like i_img_diff() but looks at floating point samples instead.
1054 i_img_diffd(i_img *im1,i_img *im2) {
1055 i_img_dim x, y, xb, yb;
1061 im_log((aIMCTX, 1,"i_img_diffd(im1 %p,im2 %p)\n",im1,im2));
1063 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1064 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1065 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1067 im_log((aIMCTX, 1,"i_img_diffd: b(" i_DFp ") chb=%d\n",
1068 i_DFcp(xb, yb), chb));
1071 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1072 i_gpixf(im1,x,y,&val1);
1073 i_gpixf(im2,x,y,&val2);
1075 for(ch=0;ch<chb;ch++) {
1076 double sdiff = val1.channel[ch]-val2.channel[ch];
1077 tdiff += sdiff * sdiff;
1080 im_log((aIMCTX, 1,"i_img_diffd <- (%.2f)\n",tdiff));
1086 i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
1087 i_img_dim x,y,xb,yb;
1095 im_log((aIMCTX,1,"i_img_samef(im1 %p,im2 %p, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
1097 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1098 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1099 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1101 im_log((aIMCTX, 1,"i_img_samef: b(" i_DFp ") chb=%d\n",
1102 i_DFcp(xb, yb), chb));
1104 for(y = 0; y < yb; y++) {
1105 for(x = 0; x < xb; x++) {
1106 i_gpixf(im1, x, y, &val1);
1107 i_gpixf(im2, x, y, &val2);
1109 for(ch = 0; ch < chb; ch++) {
1110 double sdiff = val1.channel[ch] - val2.channel[ch];
1111 if (fabs(sdiff) > epsilon) {
1112 im_log((aIMCTX, 1,"i_img_samef <- different %g @(" i_DFp ")\n",
1113 sdiff, i_DFcp(x, y)));
1119 im_log((aIMCTX, 1,"i_img_samef <- same\n"));
1124 /* just a tiny demo of haar wavelets */
1132 i_img *new_img,*new_img2;
1133 i_color val1,val2,dval1,dval2;
1142 /* horizontal pass */
1144 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1145 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1147 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1148 i_gpix(im,x*2,y,&val1);
1149 i_gpix(im,x*2+1,y,&val2);
1150 for(ch=0;ch<im->channels;ch++) {
1151 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1152 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1154 i_ppix(new_img,x,y,&dval1);
1155 i_ppix(new_img,x+fx,y,&dval2);
1158 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1159 i_gpix(new_img,x,y*2,&val1);
1160 i_gpix(new_img,x,y*2+1,&val2);
1161 for(ch=0;ch<im->channels;ch++) {
1162 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1163 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1165 i_ppix(new_img2,x,y,&dval1);
1166 i_ppix(new_img2,x,y+fy,&dval2);
1169 i_img_destroy(new_img);
1174 =item i_count_colors(im, maxc)
1176 returns number of colors or -1
1177 to indicate that it was more than max colors
1181 /* This function has been changed and is now faster. It's using
1182 * i_gsamp instead of i_gpix */
1184 i_count_colors(i_img *im,int maxc) {
1191 i_img_dim xsize = im->xsize;
1192 i_img_dim ysize = im->ysize;
1193 int samp_cnt = 3 * xsize;
1195 if (im->channels >= 3) {
1199 channels[0] = channels[1] = channels[2] = 0;
1200 samp_chans = channels;
1205 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1208 for(y = 0; y < ysize; ) {
1209 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1210 for(x = 0; x < samp_cnt; ) {
1211 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1213 if (colorcnt > maxc) {
1225 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm
1226 * (adapted from the Numerical Recipes)
1228 /* Needed by get_anonymous_color_histo */
1230 hpsort(unsigned int n, unsigned *ra) {
1255 if (j < ir && ra[j] < ra[j+1]) j++;
1267 /* This function constructs an ordered list which represents how much the
1268 * different colors are used. So for instance (100, 100, 500) means that one
1269 * color is used for 500 pixels, another for 100 pixels and another for 100
1270 * pixels. It's tuned for performance. You might not like the way I've hardcoded
1271 * the maxc ;-) and you might want to change the name... */
1272 /* Uses octt_histo */
1274 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1278 unsigned int *col_usage_it;
1283 i_img_dim xsize = im->xsize;
1284 i_img_dim ysize = im->ysize;
1285 int samp_cnt = 3 * xsize;
1288 samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1290 if (im->channels >= 3) {
1294 channels[0] = channels[1] = channels[2] = 0;
1295 samp_chans = channels;
1299 for(y = 0; y < ysize; ) {
1300 i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1301 for(x = 0; x < samp_cnt; ) {
1302 colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1304 if (colorcnt > maxc) {
1312 /* Now that we know the number of colours... */
1313 col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1314 octt_histo(ct, &col_usage_it);
1315 hpsort(colorcnt, *col_usage);
1323 =head2 Image method wrappers
1325 These functions provide i_fsample_t functions in terms of their
1326 i_sample_t versions.
1330 =item i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1335 int i_ppixf_fp(i_img *im, i_img_dim x, i_img_dim y, const i_fcolor *pix) {
1339 for (ch = 0; ch < im->channels; ++ch)
1340 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1342 return i_ppix(im, x, y, &temp);
1346 =item i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix)
1350 int i_gpixf_fp(i_img *im, i_img_dim x, i_img_dim y, i_fcolor *pix) {
1354 if (i_gpix(im, x, y, &temp) == 0) {
1355 for (ch = 0; ch < im->channels; ++ch)
1356 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1364 =item i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1369 i_plinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, const i_fcolor *pix) {
1372 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1379 work = mymalloc(sizeof(i_color) * (r-l));
1380 for (i = 0; i < r-l; ++i) {
1381 for (ch = 0; ch < im->channels; ++ch)
1382 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1384 ret = i_plin(im, l, r, y, work);
1399 =item i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix)
1404 i_glinf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fcolor *pix) {
1407 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1414 work = mymalloc(sizeof(i_color) * (r-l));
1415 ret = i_plin(im, l, r, y, work);
1416 for (i = 0; i < r-l; ++i) {
1417 for (ch = 0; ch < im->channels; ++ch)
1418 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1434 =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)
1440 i_gsampf_fp(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, i_fsample_t *samp,
1441 int const *chans, int chan_count) {
1444 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1450 work = mymalloc(sizeof(i_sample_t) * (r-l));
1451 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1452 for (i = 0; i < ret; ++i) {
1453 samp[i] = Sample8ToF(work[i]);
1471 =head2 Palette wrapper functions
1473 Used for virtual images, these forward palette calls to a wrapped image,
1474 assuming the wrapped image is the first pointer in the structure that
1475 im->ext_data points at.
1479 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1483 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1484 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1488 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1492 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1493 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1497 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1501 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1502 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1506 =item i_colorcount_forward(i_img *im)
1510 int i_colorcount_forward(i_img *im) {
1511 return i_colorcount(*(i_img **)im->ext_data);
1515 =item i_maxcolors_forward(i_img *im)
1519 int i_maxcolors_forward(i_img *im) {
1520 return i_maxcolors(*(i_img **)im->ext_data);
1524 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1528 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1529 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1535 =head2 Fallback handler
1539 =item i_gsamp_bits_fb
1545 i_gsamp_bits_fb(i_img *im, i_img_dim l, i_img_dim r, i_img_dim y, unsigned *samps,
1546 const int *chans, int chan_count, int bits) {
1549 if (bits < 1 || bits > 32) {
1550 i_push_error(0, "Invalid bits, must be 1..32");
1554 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1557 i_img_dim count, i, w;
1560 scale = 4294967295.0;
1562 scale = (double)(1 << bits) - 1;
1570 /* make sure we have good channel numbers */
1571 for (ch = 0; ch < chan_count; ++ch) {
1572 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1573 im_push_errorf(aIMCTX, 0, "No channel %d in this image", chans[ch]);
1577 for (i = 0; i < w; ++i) {
1579 i_gpixf(im, l+i, y, &c);
1580 for (ch = 0; ch < chan_count; ++ch) {
1581 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1587 if (chan_count <= 0 || chan_count > im->channels) {
1588 i_push_error(0, "Invalid channel count");
1591 for (i = 0; i < w; ++i) {
1593 i_gpixf(im, l+i, y, &c);
1594 for (ch = 0; ch < chan_count; ++ch) {
1595 *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1604 i_push_error(0, "Image position outside of image");
1609 struct magic_entry {
1610 unsigned char *magic;
1613 unsigned char *mask;
1617 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
1618 if (length < magic->magic_size)
1622 unsigned char *bufp = buffer,
1623 *maskp = magic->mask,
1624 *magicp = magic->magic;
1626 for (i = 0; i < magic->magic_size; ++i) {
1627 int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
1630 if ((*bufp++ & mask) != (*magicp++ & mask))
1637 return !memcmp(magic->magic, buffer, magic->magic_size);
1642 =item i_test_format_probe(io_glue *data, int length)
1644 Check the beginning of the supplied file for a 'magic number'
1649 #define FORMAT_ENTRY(magic, type) \
1650 { (unsigned char *)(magic ""), sizeof(magic)-1, type }
1651 #define FORMAT_ENTRY2(magic, type, mask) \
1652 { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
1655 i_test_format_probe(io_glue *data, int length) {
1656 static const struct magic_entry formats[] = {
1657 FORMAT_ENTRY("\xFF\xD8", "jpeg"),
1658 FORMAT_ENTRY("GIF87a", "gif"),
1659 FORMAT_ENTRY("GIF89a", "gif"),
1660 FORMAT_ENTRY("MM\0*", "tiff"),
1661 FORMAT_ENTRY("II*\0", "tiff"),
1662 FORMAT_ENTRY("BM", "bmp"),
1663 FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
1664 FORMAT_ENTRY("P1", "pnm"),
1665 FORMAT_ENTRY("P2", "pnm"),
1666 FORMAT_ENTRY("P3", "pnm"),
1667 FORMAT_ENTRY("P4", "pnm"),
1668 FORMAT_ENTRY("P5", "pnm"),
1669 FORMAT_ENTRY("P6", "pnm"),
1670 FORMAT_ENTRY("/* XPM", "xpm"),
1671 FORMAT_ENTRY("\x8aMNG", "mng"),
1672 FORMAT_ENTRY("\x8aJNG", "jng"),
1673 /* SGI RGB - with various possible parameters to avoid false positives
1675 values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
1677 FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
1678 FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
1679 FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
1680 FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
1682 FORMAT_ENTRY2("FORM ILBM", "ilbm", "xxxx xxxx"),
1684 /* different versions of PCX format
1685 http://www.fileformat.info/format/pcx/
1687 FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
1688 FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
1689 FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
1690 FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
1691 FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
1693 /* FITS - http://fits.gsfc.nasa.gov/ */
1694 FORMAT_ENTRY("SIMPLE =", "fits"),
1696 /* PSD - Photoshop */
1697 FORMAT_ENTRY("8BPS\x00\x01", "psd"),
1699 /* EPS - Encapsulated Postscript */
1700 /* only reading 18 chars, so we don't include the F in EPSF */
1701 FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
1704 FORMAT_ENTRY("\x52\xCC", "utah"),
1706 /* GZIP compressed, only matching deflate for now */
1707 FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
1709 /* bzip2 compressed */
1710 FORMAT_ENTRY("BZh", "bzip2"),
1713 http://code.google.com/speed/webp/docs/riff_container.html */
1714 FORMAT_ENTRY2("RIFF WEBP", "webp", "xxxx xxxx"),
1717 This might match a little loosely */
1718 FORMAT_ENTRY("\x00\x00\x00\x0CjP \x0D\x0A\x87\x0A", "jp2"),
1720 /* FLIF - Free Lossless Image Format - https://flif.info/spec.html */
1721 FORMAT_ENTRY("FLIF", "flif")
1723 static const struct magic_entry more_formats[] = {
1724 /* these were originally both listed as ico, but cur files can
1725 include hotspot information */
1726 FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
1727 FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
1728 FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07",
1729 "xwd", " xxxx"), /* X Windows Dump */
1733 unsigned char head[18];
1736 rc = i_io_peekn(data, head, 18);
1737 if (rc == -1) return NULL;
1741 fprintf(stderr, "%d bytes -", (int)rc);
1742 for (i = 0; i < rc; ++i)
1743 fprintf(stderr, " %02x", head[i]);
1744 fprintf(stderr, "\n");
1748 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
1749 struct magic_entry const *entry = formats + i;
1751 if (test_magic(head, rc, entry))
1756 tga_header_verify(head))
1759 for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) {
1760 struct magic_entry const *entry = more_formats + i;
1762 if (test_magic(head, rc, entry))
1770 =item i_img_is_monochrome(img, &zero_is_white)
1772 =category Image Information
1774 Tests an image to check it meets our monochrome tests.
1776 The idea is that a file writer can use this to test where it should
1777 write the image in whatever bi-level format it uses, eg. C<pbm> for
1780 For performance of encoders we require monochrome images:
1790 have a palette of two colors, containing only C<(0,0,0)> and
1791 C<(255,255,255)> in either order.
1795 C<zero_is_white> is set to non-zero if the first palette entry is white.
1801 i_img_is_monochrome(i_img *im, int *zero_is_white) {
1802 if (im->type == i_palette_type
1803 && i_colorcount(im) == 2) {
1805 if (!i_getcolors(im, 0, colors, 2))
1807 if (im->channels == 3) {
1808 if (colors[0].rgb.r == 255 &&
1809 colors[0].rgb.g == 255 &&
1810 colors[0].rgb.b == 255 &&
1811 colors[1].rgb.r == 0 &&
1812 colors[1].rgb.g == 0 &&
1813 colors[1].rgb.b == 0) {
1817 else if (colors[0].rgb.r == 0 &&
1818 colors[0].rgb.g == 0 &&
1819 colors[0].rgb.b == 0 &&
1820 colors[1].rgb.r == 255 &&
1821 colors[1].rgb.g == 255 &&
1822 colors[1].rgb.b == 255) {
1827 else if (im->channels == 1) {
1828 if (colors[0].channel[0] == 255 &&
1829 colors[1].channel[0] == 0) {
1833 else if (colors[0].channel[0] == 0 &&
1834 colors[1].channel[0] == 255) {
1846 =item i_get_file_background(im, &bg)
1850 Retrieve the file write background color tag from the image.
1852 If not present, C<bg> is set to black.
1854 Returns 1 if the C<i_background> tag was found and valid.
1860 i_get_file_background(i_img *im, i_color *bg) {
1861 int result = i_tags_get_color(&im->tags, "i_background", 0, bg);
1864 bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
1866 /* always full alpha */
1867 bg->channel[3] = 255;
1873 =item i_get_file_backgroundf(im, &bg)
1877 Retrieve the file write background color tag from the image as a
1878 floating point color.
1880 Implemented in terms of i_get_file_background().
1882 If not present, C<bg> is set to black.
1884 Returns 1 if the C<i_background> tag was found and valid.
1890 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
1892 int result = i_get_file_background(im, &bg);
1893 fbg->rgba.r = Sample8ToF(bg.rgba.r);
1894 fbg->rgba.g = Sample8ToF(bg.rgba.g);
1895 fbg->rgba.b = Sample8ToF(bg.rgba.b);
1906 Arnar M. Hrafnkelsson <addi@umich.edu>
1908 Tony Cook <tonyc@cpan.org>