8 image.c - implements most of the basic functions of Imager and much of the rest
14 c = i_color_new(red, green, blue, alpha);
22 image.c implements the basic functions to create and destroy image and
23 color objects for Imager.
25 =head1 FUNCTION REFERENCE
27 Some of these functions are internal.
38 #define minmax(a,b,i) ( ((a>=i)?a: ( (b<=i)?b:i )) )
40 /* Hack around an obscure linker bug on solaris - probably due to builtin gcc thingies */
41 static void fake(void) { ceil(1); }
43 static int i_ppix_d(i_img *im, int x, int y, i_color *val);
44 static int i_gpix_d(i_img *im, int x, int y, i_color *val);
45 static int i_glin_d(i_img *im, int l, int r, int y, i_color *vals);
46 static int i_plin_d(i_img *im, int l, int r, int y, i_color *vals);
47 static int i_ppixf_d(i_img *im, int x, int y, i_fcolor *val);
48 static int i_gpixf_d(i_img *im, int x, int y, i_fcolor *val);
49 static int i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
50 static int i_plinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
51 static int i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, const int *chans, int chan_count);
52 static int i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, const int *chans, int chan_count);
53 /*static int i_psamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count);
54 static int i_psampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count);*/
57 =item ICL_new_internal(r, g, b, a)
59 Return a new color object with values passed to it.
61 r - red component (range: 0 - 255)
62 g - green component (range: 0 - 255)
63 b - blue component (range: 0 - 255)
64 a - alpha component (range: 0 - 255)
70 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
73 mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
75 if ( (cl=mymalloc(sizeof(i_color))) == NULL) m_fatal(2,"malloc() error\n");
80 mm_log((1,"(%p) <- ICL_new_internal\n",cl));
86 =item ICL_set_internal(cl, r, g, b, a)
88 Overwrite a color with new values.
90 cl - pointer to color object
91 r - red component (range: 0 - 255)
92 g - green component (range: 0 - 255)
93 b - blue component (range: 0 - 255)
94 a - alpha component (range: 0 - 255)
100 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
101 mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
103 if ( (cl=mymalloc(sizeof(i_color))) == NULL)
104 m_fatal(2,"malloc() error\n");
109 mm_log((1,"(%p) <- ICL_set_internal\n",cl));
115 =item ICL_add(dst, src, ch)
117 Add src to dst inplace - dst is modified.
119 dst - pointer to destination color object
120 src - pointer to color object that is added
121 ch - number of channels
127 ICL_add(i_color *dst,i_color *src,int ch) {
130 tmp=dst->channel[i]+src->channel[i];
131 dst->channel[i]= tmp>255 ? 255:tmp;
138 Dump color information to log - strictly for debugging.
140 cl - pointer to color object
146 ICL_info(i_color *cl) {
147 mm_log((1,"i_color_info(cl* %p)\n",cl));
148 mm_log((1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
154 Destroy ancillary data for Color object.
156 cl - pointer to color object
162 ICL_DESTROY(i_color *cl) {
163 mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
168 =item i_fcolor_new(double r, double g, double b, double a)
172 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
175 mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
177 if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) m_fatal(2,"malloc() error\n");
182 mm_log((1,"(%p) <- i_fcolor_new\n",cl));
188 =item i_fcolor_destroy(i_fcolor *cl)
192 void i_fcolor_destroy(i_fcolor *cl) {
197 =item IIM_base_8bit_direct (static)
199 A static i_img object used to initialize direct 8-bit per sample images.
203 static i_img IIM_base_8bit_direct =
205 0, /* channels set */
206 0, 0, 0, /* xsize, ysize, bytes */
209 i_direct_type, /* type */
212 { 0, 0, NULL }, /* tags */
215 i_ppix_d, /* i_f_ppix */
216 i_ppixf_d, /* i_f_ppixf */
217 i_plin_d, /* i_f_plin */
218 i_plinf_d, /* i_f_plinf */
219 i_gpix_d, /* i_f_gpix */
220 i_gpixf_d, /* i_f_gpixf */
221 i_glin_d, /* i_f_glin */
222 i_glinf_d, /* i_f_glinf */
223 i_gsamp_d, /* i_f_gsamp */
224 i_gsampf_d, /* i_f_gsampf */
228 NULL, /* i_f_addcolors */
229 NULL, /* i_f_getcolors */
230 NULL, /* i_f_colorcount */
231 NULL, /* i_f_maxcolors */
232 NULL, /* i_f_findcolor */
233 NULL, /* i_f_setcolors */
235 NULL, /* i_f_destroy */
238 /*static void set_8bit_direct(i_img *im) {
239 im->i_f_ppix = i_ppix_d;
240 im->i_f_ppixf = i_ppixf_d;
241 im->i_f_plin = i_plin_d;
242 im->i_f_plinf = i_plinf_d;
243 im->i_f_gpix = i_gpix_d;
244 im->i_f_gpixf = i_gpixf_d;
245 im->i_f_glin = i_glin_d;
246 im->i_f_glinf = i_glinf_d;
249 im->i_f_addcolor = NULL;
250 im->i_f_getcolor = NULL;
251 im->i_f_colorcount = NULL;
252 im->i_f_findcolor = NULL;
256 =item IIM_new(x, y, ch)
258 Creates a new image object I<x> pixels wide, and I<y> pixels high with I<ch> channels.
265 IIM_new(int x,int y,int ch) {
267 mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
269 im=i_img_empty_ch(NULL,x,y,ch);
271 mm_log((1,"(%p) <- IIM_new\n",im));
277 IIM_DESTROY(i_img *im) {
278 mm_log((1,"IIM_DESTROY(im* %p)\n",im));
288 Create new image reference - notice that this isn't an object yet and
289 this should be fixed asap.
299 mm_log((1,"i_img_struct()\n"));
300 if ( (im=mymalloc(sizeof(i_img))) == NULL)
301 m_fatal(2,"malloc() error\n");
303 *im = IIM_base_8bit_direct;
311 mm_log((1,"(%p) <- i_img_struct\n",im));
316 =item i_img_empty(im, x, y)
318 Re-new image reference (assumes 3 channels)
321 x - xsize of destination image
322 y - ysize of destination image
324 **FIXME** what happens if a live image is passed in here?
326 Should this just call i_img_empty_ch()?
332 i_img_empty(i_img *im,int x,int y) {
333 mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
334 return i_img_empty_ch(im, x, y, 3);
338 =item i_img_empty_ch(im, x, y, ch)
340 Re-new image reference
343 x - xsize of destination image
344 y - ysize of destination image
345 ch - number of channels
351 i_img_empty_ch(i_img *im,int x,int y,int ch) {
352 mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
354 if ( (im=mymalloc(sizeof(i_img))) == NULL)
355 m_fatal(2,"malloc() error\n");
357 memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
358 i_tags_new(&im->tags);
362 im->ch_mask = MAXINT;
363 im->bytes=x*y*im->channels;
364 if ( (im->idata=mymalloc(im->bytes)) == NULL) m_fatal(2,"malloc() error\n");
365 memset(im->idata,0,(size_t)im->bytes);
369 mm_log((1,"(%p) <- i_img_empty_ch\n",im));
374 =item i_img_exorcise(im)
384 i_img_exorcise(i_img *im) {
385 mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
386 i_tags_destroy(&im->tags);
388 (im->i_f_destroy)(im);
389 if (im->idata != NULL) { myfree(im->idata); }
395 im->i_f_ppix=i_ppix_d;
396 im->i_f_gpix=i_gpix_d;
397 im->i_f_plin=i_plin_d;
398 im->i_f_glin=i_glin_d;
403 =item i_img_destroy(im)
405 Destroy image and free data via exorcise.
413 i_img_destroy(i_img *im) {
414 mm_log((1,"i_img_destroy(im %p)\n",im));
416 if (im) { myfree(im); }
420 =item i_img_info(im, info)
422 Return image information
425 info - pointer to array to return data
427 info is an array of 4 integers with the following values:
432 info[3] - channel mask
439 i_img_info(i_img *im,int *info) {
440 mm_log((1,"i_img_info(im 0x%x)\n",im));
442 mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
443 mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
446 info[2] = im->channels;
447 info[3] = im->ch_mask;
457 =item i_img_setmask(im, ch_mask)
459 Set the image channel mask for I<im> to I<ch_mask>.
464 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
468 =item i_img_getmask(im)
470 Get the image channel mask for I<im>.
475 i_img_getmask(i_img *im) { return im->ch_mask; }
478 =item i_img_getchannels(im)
480 Get the number of channels in I<im>.
485 i_img_getchannels(i_img *im) { return im->channels; }
490 =item i_copyto_trans(im, src, x1, y1, x2, y2, tx, ty, trans)
492 (x1,y1) (x2,y2) specifies the region to copy (in the source coordinates)
493 (tx,ty) specifies the upper left corner for the target image.
494 pass NULL in trans for non transparent i_colors.
500 i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans) {
502 int x,y,t,ttx,tty,tt,ch;
504 mm_log((1,"i_copyto_trans(im* %p,src 0x%x, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d, trans* 0x%x)\n",
505 im, src, x1, y1, x2, y2, tx, ty, trans));
507 if (x2<x1) { t=x1; x1=x2; x2=t; }
508 if (y2<y1) { t=y1; y1=y2; y2=t; }
520 for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
521 if (tt) i_ppix(im,ttx,tty,&pv);
522 } else i_ppix(im,ttx,tty,&pv);
530 =item i_copyto(dest, src, x1, y1, x2, y2, tx, ty)
532 Copies image data from the area (x1,y1)-[x2,y2] in the source image to
533 a rectangle the same size with it's top-left corner at (tx,ty) in the
536 If x1 > x2 or y1 > y2 then the corresponding co-ordinates are swapped.
542 i_copyto(i_img *im, i_img *src, int x1, int y1, int x2, int y2, int tx, int ty) {
543 int x, y, t, ttx, tty;
545 if (x2<x1) { t=x1; x1=x2; x2=t; }
546 if (y2<y1) { t=y1; y1=y2; y2=t; }
548 mm_log((1,"i_copyto(im* %p, src %p, x1 %d, y1 %d, x2 %d, y2 %d, tx %d, ty %d)\n",
549 im, src, x1, y1, x2, y2, tx, ty));
551 if (im->bits == i_8_bits) {
554 for(y=y1; y<y2; y++) {
556 for(x=x1; x<x2; x++) {
557 i_gpix(src, x, y, &pv);
558 i_ppix(im, ttx, tty, &pv);
567 for(y=y1; y<y2; y++) {
569 for(x=x1; x<x2; x++) {
570 i_gpixf(src, x, y, &pv);
571 i_ppixf(im, ttx, tty, &pv);
580 =item i_copy(im, src)
582 Copies the contents of the image I<src> over the image I<im>.
588 i_copy(i_img *im, i_img *src) {
591 mm_log((1,"i_copy(im* %p,src %p)\n", im, src));
595 if (src->type == i_direct_type) {
596 if (src->bits == i_8_bits) {
598 i_img_empty_ch(im, x1, y1, src->channels);
599 pv = mymalloc(sizeof(i_color) * x1);
601 for (y = 0; y < y1; ++y) {
602 i_glin(src, 0, x1, y, pv);
603 i_plin(im, 0, x1, y, pv);
609 if (src->bits == i_16_bits)
610 i_img_16_new_low(im, x1, y1, src->channels);
611 else if (src->bits == i_double_bits)
612 i_img_double_new_low(im, x1, y1, src->channels);
614 fprintf(stderr, "i_copy(): Unknown image bit size %d\n", src->bits);
615 return; /* I dunno */
618 pv = mymalloc(sizeof(i_fcolor) * x1);
619 for (y = 0; y < y1; ++y) {
620 i_glinf(src, 0, x1, y, pv);
621 i_plinf(im, 0, x1, y, pv);
633 i_img_pal_new_low(im, x1, y1, src->channels, i_maxcolors(src));
634 /* copy across the palette */
635 count = i_colorcount(src);
636 for (index = 0; index < count; ++index) {
637 i_getcolors(src, index, &temp, 1);
638 i_addcolors(im, &temp, 1);
641 vals = mymalloc(sizeof(i_palidx) * x1);
642 for (y = 0; y < y1; ++y) {
643 i_gpal(src, 0, x1, y, vals);
644 i_ppal(im, 0, x1, y, vals);
652 =item i_rubthru(im, src, tx, ty)
654 Takes the image I<src> and applies it at an original (I<tx>,I<ty>) in I<im>.
656 The alpha channel of each pixel in I<src> is used to control how much
657 the existing colour in I<im> is replaced, if it is 255 then the colour
658 is completely replaced, if it is 0 then the original colour is left
665 i_rubthru(i_img *im,i_img *src,int tx,int ty) {
672 mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d)\n", im, src, tx, ty));
675 if (im->channels == 3 && src->channels == 4) {
677 chans[0] = 0; chans[1] = 1; chans[2] = 2;
680 else if (im->channels == 3 && src->channels == 2) {
682 chans[0] = chans[1] = chans[2] = 0;
685 else if (im->channels == 1 && src->channels == 2) {
691 i_push_error(0, "rubthru can only work where (dest, src) channels are (3,4), (3,2) or (1,2)");
696 /* if you change this code, please make sure the else branch is
697 changed in a similar fashion - TC */
699 i_color pv, orig, dest;
701 for(x=0; x<src->xsize; x++) {
703 for(y=0;y<src->ysize;y++) {
704 /* fprintf(stderr,"reading (%d,%d) writing (%d,%d).\n",x,y,ttx,tty); */
705 i_gpix(src, x, y, &pv);
706 i_gpix(im, ttx, tty, &orig);
707 alpha = pv.channel[alphachan];
708 for (ch = 0; ch < chancount; ++ch) {
709 dest.channel[ch] = (alpha * pv.channel[chans[ch]]
710 + (255 - alpha) * orig.channel[ch])/255;
712 i_ppix(im, ttx, tty, &dest);
720 i_fcolor pv, orig, dest;
723 for(x=0; x<src->xsize; x++) {
725 for(y=0;y<src->ysize;y++) {
726 /* fprintf(stderr,"reading (%d,%d) writing (%d,%d).\n",x,y,ttx,tty); */
727 i_gpixf(src, x, y, &pv);
728 i_gpixf(im, ttx, tty, &orig);
729 alpha = pv.channel[alphachan];
730 for (ch = 0; ch < chancount; ++ch) {
731 dest.channel[ch] = alpha * pv.channel[chans[ch]]
732 + (1 - alpha) * orig.channel[ch];
734 i_ppixf(im, ttx, tty, &dest);
746 =item i_flipxy(im, axis)
748 Flips the image inplace around the axis specified.
749 Returns 0 if parameters are invalid.
752 axis - 0 = x, 1 = y, 2 = both
758 i_flipxy(i_img *im, int direction) {
759 int x, x2, y, y2, xm, ym;
763 mm_log((1, "i_flipxy(im %p, direction %d)\n", im, direction ));
768 case XAXIS: /* Horizontal flip */
771 for(y=0; y<ym; y++) {
773 for(x=0; x<xm; x++) {
775 i_gpix(im, x, y, &val1);
776 i_gpix(im, x2, y, &val2);
777 i_ppix(im, x, y, &val2);
778 i_ppix(im, x2, y, &val1);
783 case YAXIS: /* Vertical flip */
787 for(y=0; y<ym; y++) {
788 for(x=0; x<xm; x++) {
790 i_gpix(im, x, y, &val1);
791 i_gpix(im, x, y2, &val2);
792 i_ppix(im, x, y, &val2);
793 i_ppix(im, x, y2, &val1);
798 case XYAXIS: /* Horizontal and Vertical flip */
802 for(y=0; y<ym; y++) {
804 for(x=0; x<xm; x++) {
806 i_gpix(im, x, y, &val1);
807 i_gpix(im, x2, y2, &val2);
808 i_ppix(im, x, y, &val2);
809 i_ppix(im, x2, y2, &val1);
811 i_gpix(im, x2, y, &val1);
812 i_gpix(im, x, y2, &val2);
813 i_ppix(im, x2, y, &val2);
814 i_ppix(im, x, y2, &val1);
819 if (xm*2 != xs) { /* odd number of column */
820 mm_log((1, "i_flipxy: odd number of columns\n"));
823 for(y=0; y<ym; y++) {
825 i_gpix(im, x, y, &val1);
826 i_gpix(im, x, y2, &val2);
827 i_ppix(im, x, y, &val2);
828 i_ppix(im, x, y2, &val1);
832 if (ym*2 != ys) { /* odd number of rows */
833 mm_log((1, "i_flipxy: odd number of rows\n"));
836 for(x=0; x<xm; x++) {
838 i_gpix(im, x, y, &val1);
839 i_gpix(im, x2, y, &val2);
840 i_ppix(im, x, y, &val2);
841 i_ppix(im, x2, y, &val1);
847 mm_log((1, "i_flipxy: direction is invalid\n" ));
865 if ((x >= 2.0) || (x <= -2.0)) return (0.0);
866 else if (x == 0.0) return (1.0);
867 else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
879 i_scaleaxis_3ch_8bit(i_img *im, int size, int Axis) {
887 unsigned long *pixels;
891 mm_log((1,"i_scaleaxis_3ch_8bit(im %p, size %d,Axis %d)\n",im, size, Axis));
899 pixels = mymalloc(sizeof(*pixels) * im->xsize);
906 pixels = mymalloc(sizeof(*pixels) * im->ysize);
909 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
914 for (i=0; i<iEnd; i++) {
917 for(j=0; j<im->xsize; j++) {
918 i_gpix(im, j, i, &val);
919 pixels[j] = (val.rgba.r<<24) | (val.rgba.g<<16) | (val.rgba.b<<8) | (val.rgba.a<<0);
922 /* printf("jEnd = %d, end = %d\n", jEnd, end); */
923 while ((end+1)/2>=size) {
927 for(j=0; j<lend; j++) {
928 unsigned long a = pixels[2*j];
929 unsigned long b = pixels[2*j+1];
930 pixels[j] = (((a ^ b) & 0xfefefefeUL) >> 1) + (a & b);
933 pixels[j] = pixels[2*j];
938 printf("end = %d size = %d\n", end, size);
940 /* Replace this with Bresenham later */
941 for(j=0; j<size; j++) {
943 /* if ((i*size)/end <) */
944 unsigned long t = pixels[j];
945 val.rgba.r = (t >> 24) & 0xff;
946 val.rgba.g = (t >> 16) & 0xff;
947 val.rgba.b = (t >> 8) & 0xff;
948 val.rgba.a = t & 0xff;
949 i_ppix(new_img, j, i, &val);
964 =item i_scaleaxis(im, value, axis)
966 Returns a new image object which is I<im> scaled by I<value> along
967 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
973 i_scaleaxis(i_img *im, float Value, int Axis) {
974 int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
975 int LanczosWidthFactor;
976 float *l0, *l1, OldLocation;
979 float F, PictureValue[MAXCHANNELS];
981 i_color val,val1,val2;
984 mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
988 return i_scaleaxis_3ch_8bit(im, (int)(0.5+im->xsize*Value), Axis);
990 hsize = (int)(0.5 + im->xsize * Value);
997 vsize = (int)(0.5 + im->ysize * Value);
1003 new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
1005 /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
1006 LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value);
1007 lMax = LanczosWidthFactor << 1;
1009 l0 = mymalloc(lMax * sizeof(float));
1010 l1 = mymalloc(lMax * sizeof(float));
1012 for (j=0; j<jEnd; j++) {
1013 OldLocation = ((float) j) / Value;
1014 T = (int) (OldLocation);
1015 F = OldLocation - (float) T;
1017 for (l = 0; l<lMax; l++) {
1018 l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
1019 l1[l] = Lanczos(((float) (l+1) - F) / (float) LanczosWidthFactor);
1022 /* Make sure filter is normalized */
1024 for(l=0; l<lMax; l++) {
1028 t /= (float)LanczosWidthFactor;
1030 for(l=0; l<lMax; l++) {
1035 if (Axis == XAXIS) {
1037 for (i=0; i<iEnd; i++) {
1038 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
1039 for (l=0; l<lMax; l++) {
1040 int mx = T-lMax+l+1;
1042 mx = (mx < 0) ? 0 : mx;
1043 Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
1045 i_gpix(im, Mx, i, &val1);
1046 i_gpix(im, mx, i, &val2);
1048 for (k=0; k<im->channels; k++) {
1049 PictureValue[k] += l1[l] * val1.channel[k];
1050 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
1053 for(k=0;k<im->channels;k++) {
1054 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
1055 val.channel[k]=minmax(0,255,psave);
1057 i_ppix(new_img, j, i, &val);
1062 for (i=0; i<iEnd; i++) {
1063 for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
1064 for (l=0; l < lMax; l++) {
1065 int mx = T-lMax+l+1;
1067 mx = (mx < 0) ? 0 : mx;
1068 Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
1070 i_gpix(im, i, Mx, &val1);
1071 i_gpix(im, i, mx, &val2);
1072 for (k=0; k<im->channels; k++) {
1073 PictureValue[k] += l1[l] * val1.channel[k];
1074 PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
1077 for (k=0; k<im->channels; k++) {
1078 psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
1079 val.channel[k] = minmax(0, 255, psave);
1081 i_ppix(new_img, i, j, &val);
1089 mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
1096 =item i_scale_nn(im, scx, scy)
1098 Scale by using nearest neighbor
1099 Both axes scaled at the same time since
1100 nothing is gained by doing it in two steps
1107 i_scale_nn(i_img *im, float scx, float scy) {
1109 int nxsize,nysize,nx,ny;
1113 mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
1115 nxsize = (int) ((float) im->xsize * scx);
1116 nysize = (int) ((float) im->ysize * scy);
1118 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1120 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1121 i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
1122 i_ppix(new_img,nx,ny,&val);
1125 mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
1131 =item i_sametype(i_img *im, int xsize, int ysize)
1133 Returns an image of the same type (sample size, channels, paletted/direct).
1135 For paletted images the palette is copied from the source.
1140 i_img *i_sametype(i_img *src, int xsize, int ysize) {
1141 if (src->type == i_direct_type) {
1142 if (src->bits == 8) {
1143 return i_img_empty_ch(NULL, xsize, ysize, src->channels);
1145 else if (src->bits == i_16_bits) {
1146 return i_img_16_new(xsize, ysize, src->channels);
1148 else if (src->bits == i_double_bits) {
1149 return i_img_double_new(xsize, ysize, src->channels);
1152 i_push_error(0, "Unknown image bits");
1160 i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1161 for (i = 0; i < i_colorcount(src); ++i) {
1162 i_getcolors(src, i, &col, 1);
1163 i_addcolors(targ, &col, 1);
1171 =item i_sametype_chans(i_img *im, int xsize, int ysize, int channels)
1173 Returns an image of the same type (sample size).
1175 For paletted images the equivalent direct type is returned.
1180 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1181 if (src->bits == 8) {
1182 return i_img_empty_ch(NULL, xsize, ysize, channels);
1184 else if (src->bits == i_16_bits) {
1185 return i_img_16_new(xsize, ysize, channels);
1187 else if (src->bits == i_double_bits) {
1188 return i_img_double_new(xsize, ysize, channels);
1191 i_push_error(0, "Unknown image bits");
1197 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1199 Spatially transforms I<im> returning a new image.
1201 opx for a length of opxl and opy for a length of opy are arrays of
1202 operators that modify the x and y positions to retreive the pixel data from.
1204 parm and parmlen define extra parameters that the operators may use.
1206 Note that this function is largely superseded by the more flexible
1207 L<transform.c/i_transform2>.
1209 Returns the new image.
1211 The operators for this function are defined in L<stackmach.c>.
1216 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1218 int nxsize,nysize,nx,ny;
1222 mm_log((1,"i_transform(im 0x%x, opx 0x%x, opxl %d, opy 0x%x, opyl %d, parm 0x%x, parmlen %d)\n",im,opx,opxl,opy,opyl,parm,parmlen));
1225 nysize = im->ysize ;
1227 new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1228 /* fprintf(stderr,"parm[2]=%f\n",parm[2]); */
1229 for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1230 /* parm[parmlen-2]=(double)nx;
1231 parm[parmlen-1]=(double)ny; */
1236 /* fprintf(stderr,"(%d,%d) ->",nx,ny); */
1237 rx=i_op_run(opx,opxl,parm,parmlen);
1238 ry=i_op_run(opy,opyl,parm,parmlen);
1239 /* fprintf(stderr,"(%f,%f)\n",rx,ry); */
1240 i_gpix(im,rx,ry,&val);
1241 i_ppix(new_img,nx,ny,&val);
1244 mm_log((1,"(0x%x) <- i_transform\n",new_img));
1249 =item i_img_diff(im1, im2)
1251 Calculates the sum of the squares of the differences between
1252 correspoding channels in two images.
1254 If the images are not the same size then only the common area is
1255 compared, hence even if images are different sizes this function
1261 i_img_diff(i_img *im1,i_img *im2) {
1262 int x,y,ch,xb,yb,chb;
1266 mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1268 xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1269 yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1270 chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1272 mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1275 for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1276 i_gpix(im1,x,y,&val1);
1277 i_gpix(im2,x,y,&val2);
1279 for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1281 mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1285 /* just a tiny demo of haar wavelets */
1293 i_img *new_img,*new_img2;
1294 i_color val1,val2,dval1,dval2;
1302 /* horizontal pass */
1304 new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1305 new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1308 for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1309 i_gpix(im,x*2,y,&val1);
1310 i_gpix(im,x*2+1,y,&val2);
1311 for(ch=0;ch<im->channels;ch++) {
1312 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1313 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1315 i_ppix(new_img,x,y,&dval1);
1316 i_ppix(new_img,x+fx,y,&dval2);
1319 for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1320 i_gpix(new_img,x,y*2,&val1);
1321 i_gpix(new_img,x,y*2+1,&val2);
1322 for(ch=0;ch<im->channels;ch++) {
1323 dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1324 dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1326 i_ppix(new_img2,x,y,&dval1);
1327 i_ppix(new_img2,x,y+fy,&dval2);
1330 i_img_destroy(new_img);
1335 =item i_count_colors(im, maxc)
1337 returns number of colors or -1
1338 to indicate that it was more than max colors
1343 i_count_colors(i_img *im,int maxc) {
1350 mm_log((1,"i_count_colors(im 0x%08X,maxc %d)\n"));
1357 for(y=0;y<ysize;y++) for(x=0;x<xsize;x++) {
1358 i_gpix(im,x,y,&val);
1359 colorcnt+=octt_add(ct,val.rgb.r,val.rgb.g,val.rgb.b);
1360 if (colorcnt > maxc) { octt_delete(ct); return -1; }
1369 =head2 8-bit per sample image internal functions
1371 These are the functions installed in an 8-bit per sample image.
1375 =item i_ppix_d(im, x, y, col)
1379 This is the function kept in the i_f_ppix member of an i_img object.
1380 It does a normal store of a pixel into the image with range checking.
1382 Returns 0 if the pixel could be set, -1 otherwise.
1388 i_ppix_d(i_img *im, int x, int y, i_color *val) {
1391 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1392 for(ch=0;ch<im->channels;ch++)
1393 if (im->ch_mask&(1<<ch))
1394 im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1397 return -1; /* error was clipped */
1401 =item i_gpix_d(im, x, y, &col)
1405 This is the function kept in the i_f_gpix member of an i_img object.
1406 It does normal retrieval of a pixel from the image with range checking.
1408 Returns 0 if the pixel could be set, -1 otherwise.
1414 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1416 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1417 for(ch=0;ch<im->channels;ch++)
1418 val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1421 for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1422 return -1; /* error was cliped */
1426 =item i_glin_d(im, l, r, y, vals)
1428 Reads a line of data from the image, storing the pixels at vals.
1430 The line runs from (l,y) inclusive to (r,y) non-inclusive
1432 vals should point at space for (r-l) pixels.
1434 l should never be less than zero (to avoid confusion about where to
1435 put the pixels in vals).
1437 Returns the number of pixels copied (eg. if r, l or y is out of range)
1443 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1445 unsigned char *data;
1446 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1449 data = im->idata + (l+y*im->xsize) * im->channels;
1451 for (i = 0; i < count; ++i) {
1452 for (ch = 0; ch < im->channels; ++ch)
1453 vals[i].channel[ch] = *data++;
1463 =item i_plin_d(im, l, r, y, vals)
1465 Writes a line of data into the image, using the pixels at vals.
1467 The line runs from (l,y) inclusive to (r,y) non-inclusive
1469 vals should point at (r-l) pixels.
1471 l should never be less than zero (to avoid confusion about where to
1472 get the pixels in vals).
1474 Returns the number of pixels copied (eg. if r, l or y is out of range)
1480 i_plin_d(i_img *im, int l, int r, int y, i_color *vals) {
1482 unsigned char *data;
1483 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1486 data = im->idata + (l+y*im->xsize) * im->channels;
1488 for (i = 0; i < count; ++i) {
1489 for (ch = 0; ch < im->channels; ++ch) {
1490 if (im->ch_mask & (1 << ch))
1491 *data = vals[i].channel[ch];
1503 =item i_ppixf_d(im, x, y, val)
1509 i_ppixf_d(i_img *im, int x, int y, i_fcolor *val) {
1512 if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1513 for(ch=0;ch<im->channels;ch++)
1514 if (im->ch_mask&(1<<ch)) {
1515 im->idata[(x+y*im->xsize)*im->channels+ch] =
1516 SampleFTo8(val->channel[ch]);
1520 return -1; /* error was clipped */
1524 =item i_gpixf_d(im, x, y, val)
1530 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1532 if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1533 for(ch=0;ch<im->channels;ch++) {
1535 Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1539 return -1; /* error was cliped */
1543 =item i_glinf_d(im, l, r, y, vals)
1545 Reads a line of data from the image, storing the pixels at vals.
1547 The line runs from (l,y) inclusive to (r,y) non-inclusive
1549 vals should point at space for (r-l) pixels.
1551 l should never be less than zero (to avoid confusion about where to
1552 put the pixels in vals).
1554 Returns the number of pixels copied (eg. if r, l or y is out of range)
1560 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1562 unsigned char *data;
1563 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1566 data = im->idata + (l+y*im->xsize) * im->channels;
1568 for (i = 0; i < count; ++i) {
1569 for (ch = 0; ch < im->channels; ++ch)
1570 vals[i].channel[ch] = Sample8ToF(*data++);
1580 =item i_plinf_d(im, l, r, y, vals)
1582 Writes a line of data into the image, using the pixels at vals.
1584 The line runs from (l,y) inclusive to (r,y) non-inclusive
1586 vals should point at (r-l) pixels.
1588 l should never be less than zero (to avoid confusion about where to
1589 get the pixels in vals).
1591 Returns the number of pixels copied (eg. if r, l or y is out of range)
1597 i_plinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1599 unsigned char *data;
1600 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1603 data = im->idata + (l+y*im->xsize) * im->channels;
1605 for (i = 0; i < count; ++i) {
1606 for (ch = 0; ch < im->channels; ++ch) {
1607 if (im->ch_mask & (1 << ch))
1608 *data = SampleFTo8(vals[i].channel[ch]);
1620 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1622 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1623 for the channels specified by chans, an array of int with chan_count
1626 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1632 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps,
1633 const int *chans, int chan_count) {
1634 int ch, count, i, w;
1635 unsigned char *data;
1637 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1640 data = im->idata + (l+y*im->xsize) * im->channels;
1645 /* make sure we have good channel numbers */
1646 for (ch = 0; ch < chan_count; ++ch) {
1647 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1648 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1652 for (i = 0; i < w; ++i) {
1653 for (ch = 0; ch < chan_count; ++ch) {
1654 *samps++ = data[chans[ch]];
1657 data += im->channels;
1661 for (i = 0; i < w; ++i) {
1662 for (ch = 0; ch < chan_count; ++ch) {
1663 *samps++ = data[ch];
1666 data += im->channels;
1678 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1680 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1681 for the channels specified by chan_mask, where bit 0 is the first
1684 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1690 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps,
1691 const int *chans, int chan_count) {
1692 int ch, count, i, w;
1693 unsigned char *data;
1694 for (ch = 0; ch < chan_count; ++ch) {
1695 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1696 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1699 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1702 data = im->idata + (l+y*im->xsize) * im->channels;
1707 /* make sure we have good channel numbers */
1708 for (ch = 0; ch < chan_count; ++ch) {
1709 if (chans[ch] < 0 || chans[ch] >= im->channels) {
1710 i_push_errorf(0, "No channel %d in this image", chans[ch]);
1714 for (i = 0; i < w; ++i) {
1715 for (ch = 0; ch < chan_count; ++ch) {
1716 *samps++ = Sample8ToF(data[chans[ch]]);
1719 data += im->channels;
1723 for (i = 0; i < w; ++i) {
1724 for (ch = 0; ch < chan_count; ++ch) {
1725 *samps++ = Sample8ToF(data[ch]);
1728 data += im->channels;
1741 =head2 Image method wrappers
1743 These functions provide i_fsample_t functions in terms of their
1744 i_sample_t versions.
1748 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1753 int i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1757 for (ch = 0; ch < im->channels; ++ch)
1758 temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1760 return i_ppix(im, x, y, &temp);
1764 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1768 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1772 if (i_gpix(im, x, y, &temp)) {
1773 for (ch = 0; ch < im->channels; ++ch)
1774 pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1782 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1786 int i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1789 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1795 work = mymalloc(sizeof(i_color) * (r-l));
1796 for (i = 0; i < r-l; ++i) {
1797 for (ch = 0; ch < im->channels; ++ch)
1798 work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1800 ret = i_plin(im, l, r, y, work);
1815 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1819 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1822 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1828 work = mymalloc(sizeof(i_color) * (r-l));
1829 ret = i_plin(im, l, r, y, work);
1830 for (i = 0; i < r-l; ++i) {
1831 for (ch = 0; ch < im->channels; ++ch)
1832 pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1848 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1852 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp,
1853 int const *chans, int chan_count) {
1856 if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1862 work = mymalloc(sizeof(i_sample_t) * (r-l));
1863 ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1864 for (i = 0; i < ret; ++i) {
1865 samp[i] = Sample8ToF(work[i]);
1883 =head2 Palette wrapper functions
1885 Used for virtual images, these forward palette calls to a wrapped image,
1886 assuming the wrapped image is the first pointer in the structure that
1887 im->ext_data points at.
1891 =item i_addcolors_forward(i_img *im, i_color *colors, int count)
1895 int i_addcolors_forward(i_img *im, i_color *colors, int count) {
1896 return i_addcolors(*(i_img **)im->ext_data, colors, count);
1900 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1904 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1905 return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1909 =item i_setcolors_forward(i_img *im, int i, i_color *color, int count)
1913 int i_setcolors_forward(i_img *im, int i, i_color *color, int count) {
1914 return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1918 =item i_colorcount_forward(i_img *im)
1922 int i_colorcount_forward(i_img *im) {
1923 return i_colorcount(*(i_img **)im->ext_data);
1927 =item i_maxcolors_forward(i_img *im)
1931 int i_maxcolors_forward(i_img *im) {
1932 return i_maxcolors(*(i_img **)im->ext_data);
1936 =item i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry)
1940 int i_findcolor_forward(i_img *im, i_color *color, i_palidx *entry) {
1941 return i_findcolor(*(i_img **)im->ext_data, color, entry);
1947 =head2 Stream reading and writing wrapper functions
1951 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1953 Performs general read buffering for file readers that permit reading
1954 to be done through a callback.
1956 The final callback gets two parameters, a I<need> value, and a I<want>
1957 value, where I<need> is the amount of data that the file library needs
1958 to read, and I<want> is the amount of space available in the buffer
1959 maintained by these functions.
1961 This means if you need to read from a stream that you don't know the
1962 length of, you can return I<need> bytes, taking the performance hit of
1963 possibly expensive callbacks (eg. back to perl code), or if you are
1964 reading from a stream where it doesn't matter if some data is lost, or
1965 if the total length of the stream is known, you can return I<want>
1972 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1975 if (length < gci->length - gci->cpos) {
1977 memcpy(buf, gci->buffer+gci->cpos, length);
1978 gci->cpos += length;
1983 memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1984 total += gci->length - gci->cpos;
1985 length -= gci->length - gci->cpos;
1986 buf += gci->length - gci->cpos;
1987 if (length < (int)sizeof(gci->buffer)) {
1991 && (did_read = (gci->cb)(gci->userdata, gci->buffer, length,
1992 sizeof(gci->buffer))) > 0) {
1994 gci->length = did_read;
1996 copy_size = i_min(length, gci->length);
1997 memcpy(buf, gci->buffer, copy_size);
1998 gci->cpos += copy_size;
2001 length -= copy_size;
2005 /* just read the rest - too big for our buffer*/
2007 while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2017 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2019 For use by callback file readers to initialize the reader buffer.
2021 Allocates, initializes and returns the reader buffer.
2023 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2028 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2029 i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2031 self->userdata = userdata;
2039 =item i_free_gen_read_data(i_gen_read_data *)
2045 void i_free_gen_read_data(i_gen_read_data *self) {
2050 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2052 Performs write buffering for a callback based file writer.
2054 Failures are considered fatal, if a write fails then data will be
2061 i_gen_write_data *self,
2065 if (self->filledto && self->filledto+size > self->maxlength) {
2066 if (self->cb(self->userdata, self->buffer, self->filledto)) {
2074 if (self->filledto+size <= self->maxlength) {
2076 memcpy(self->buffer+self->filledto, data, size);
2077 self->filledto += size;
2080 /* doesn't fit - hand it off */
2081 return self->cb(self->userdata, data, size);
2085 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2087 Allocates and initializes the data structure used by i_gen_writer.
2089 This should be released with L<image.c/i_free_gen_write_data>
2093 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb,
2094 char *userdata, int max_length)
2096 i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2098 self->userdata = userdata;
2099 self->maxlength = i_min(max_length, sizeof(self->buffer));
2100 if (self->maxlength < 0)
2101 self->maxlength = sizeof(self->buffer);
2108 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2110 Cleans up the write buffer.
2112 Will flush any left-over data if I<flush> is non-zero.
2114 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2116 Return zero only if flush is non-zero and info->cb() returns zero.
2122 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2124 int result = !flush ||
2125 info->filledto == 0 ||
2126 info->cb(info->userdata, info->buffer, info->filledto);
2135 =item i_test_format_probe(io_glue *data, int length)
2137 Cleans up the write buffer.
2139 Will flush any left-over data if I<flush> is non-zero.
2141 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2143 Return zero only if flush is non-zero and info->cb() returns zero.
2151 i_test_format_probe(io_glue *data, int length) {
2157 {"\xFF\xD8", "jpeg"},
2163 {"\x89PNG\x0d\x0a\x1a\x0a", "png"},
2176 io_glue_commit_types(data);
2177 rc = data->readcb(data, head, 18);
2178 if (rc == -1) return NULL;
2179 data->seekcb(data, -rc, SEEK_CUR);
2181 for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) {
2183 ssize_t len = strlen(formats[i].magic);
2184 if (rc<len) continue;
2185 c = !strncmp(formats[i].magic, head, len);
2187 match = formats[i].name;
2193 if (match && !strcmp(match, "jpeg")) {
2194 unsigned int x0, x1;
2195 rc = data->readcb(data, head, 18);
2196 if (rc == -1) return NULL;
2197 x0 = (unsigned char)head[0];
2198 x1 = (unsigned char)head[1];
2199 data->seekcb(data, -rc, SEEK_CUR);
2200 printf("Jpeg reread: %x %x\n", x0, x1);
2206 tga_header_verify(head)) return "tga";
2218 Arnar M. Hrafnkelsson <addi@umich.edu>
2220 Tony Cook <tony@develop-help.com>