split 8-bit image implementation out of the megafile image.c
[imager.git] / image.c
1 #include "imager.h"
2 #include "imageri.h"
3
4 /*
5 =head1 NAME
6
7 image.c - implements most of the basic functions of Imager and much of the rest
8
9 =head1 SYNOPSIS
10
11   i_img *i;
12   i_color *c;
13   c = i_color_new(red, green, blue, alpha);
14   ICL_DESTROY(c);
15   i = i_img_new();
16   i_img_destroy(i);
17   // and much more
18
19 =head1 DESCRIPTION
20
21 image.c implements the basic functions to create and destroy image and
22 color objects for Imager.
23
24 =head1 FUNCTION REFERENCE
25
26 Some of these functions are internal.
27
28 =over
29
30 =cut
31 */
32
33 #define XAXIS 0
34 #define YAXIS 1
35 #define XYAXIS 2
36
37 #define minmax(a,b,i) ( ((a>=i)?a: ( (b<=i)?b:i   )) )
38
39 /* Hack around an obscure linker bug on solaris - probably due to builtin gcc thingies */
40 static void fake(void) { ceil(1); }
41
42 /*
43 =item i_img_alloc()
44 =category Image Implementation
45
46 Allocates a new i_img structure.
47
48 When implementing a new image type perform the following steps in your
49 image object creation function:
50
51 =over
52
53 =item 1.
54
55 allocate the image with i_img_alloc().
56
57 =item 2.
58
59 initialize any function pointers or other data as needed, you can
60 overwrite the whole block if you need to.
61
62 =item 3.
63
64 initialize Imager's internal data by calling i_img_init() on the image
65 object.
66
67 =back
68
69 =cut
70 */
71
72 i_img *
73 i_img_alloc(void) {
74   return mymalloc(sizeof(i_img));
75 }
76
77 /*
78 =item i_img_init(C<img>)
79 =category Image Implementation
80
81 Imager internal initialization of images.
82
83 Currently this does very little, in the future it may be used to
84 support threads, or color profiles.
85
86 =cut
87 */
88
89 void
90 i_img_init(i_img *img) {
91   img->im_data = NULL;
92 }
93
94 /* 
95 =item ICL_new_internal(r, g, b, a)
96
97 Return a new color object with values passed to it.
98
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)
103
104 =cut
105 */
106
107 i_color *
108 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
109   i_color *cl = NULL;
110
111   mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
112
113   if ( (cl=mymalloc(sizeof(i_color))) == NULL) i_fatal(2,"malloc() error\n");
114   cl->rgba.r = r;
115   cl->rgba.g = g;
116   cl->rgba.b = b;
117   cl->rgba.a = a;
118   mm_log((1,"(%p) <- ICL_new_internal\n",cl));
119   return cl;
120 }
121
122
123 /*
124 =item ICL_set_internal(cl, r, g, b, a)
125
126  Overwrite a color with new values.
127
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)
133
134 =cut
135 */
136
137 i_color *
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));
140   if (cl == NULL)
141     if ( (cl=mymalloc(sizeof(i_color))) == NULL)
142       i_fatal(2,"malloc() error\n");
143   cl->rgba.r=r;
144   cl->rgba.g=g;
145   cl->rgba.b=b;
146   cl->rgba.a=a;
147   mm_log((1,"(%p) <- ICL_set_internal\n",cl));
148   return cl;
149 }
150
151
152 /* 
153 =item ICL_add(dst, src, ch)
154
155 Add src to dst inplace - dst is modified.
156
157    dst - pointer to destination color object
158    src - pointer to color object that is added
159    ch - number of channels
160
161 =cut
162 */
163
164 void
165 ICL_add(i_color *dst,i_color *src,int ch) {
166   int tmp,i;
167   for(i=0;i<ch;i++) {
168     tmp=dst->channel[i]+src->channel[i];
169     dst->channel[i]= tmp>255 ? 255:tmp;
170   }
171 }
172
173 /* 
174 =item ICL_info(cl)
175
176 Dump color information to log - strictly for debugging.
177
178    cl - pointer to color object
179
180 =cut
181 */
182
183 void
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));
187 }
188
189 /* 
190 =item ICL_DESTROY
191
192 Destroy ancillary data for Color object.
193
194    cl - pointer to color object
195
196 =cut
197 */
198
199 void
200 ICL_DESTROY(i_color *cl) {
201   mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
202   myfree(cl);
203 }
204
205 /*
206 =item i_fcolor_new(double r, double g, double b, double a)
207
208 =cut
209 */
210 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
211   i_fcolor *cl = NULL;
212
213   mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
214
215   if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) i_fatal(2,"malloc() error\n");
216   cl->rgba.r = r;
217   cl->rgba.g = g;
218   cl->rgba.b = b;
219   cl->rgba.a = a;
220   mm_log((1,"(%p) <- i_fcolor_new\n",cl));
221
222   return cl;
223 }
224
225 /*
226 =item i_fcolor_destroy(i_fcolor *cl) 
227
228 =cut
229 */
230 void i_fcolor_destroy(i_fcolor *cl) {
231   myfree(cl);
232 }
233
234 /* 
235 =item i_img_exorcise(im)
236
237 Free image data.
238
239    im - Image pointer
240
241 =cut
242 */
243
244 void
245 i_img_exorcise(i_img *im) {
246   mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
247   i_tags_destroy(&im->tags);
248   if (im->i_f_destroy)
249     (im->i_f_destroy)(im);
250   if (im->idata != NULL) { myfree(im->idata); }
251   im->idata    = NULL;
252   im->xsize    = 0;
253   im->ysize    = 0;
254   im->channels = 0;
255
256   im->ext_data=NULL;
257 }
258
259 /* 
260 =item i_img_destroy(C<img>)
261 =order 90
262 =category Image creation/destruction
263 =synopsis i_img_destroy(img)
264
265 Destroy an image object
266
267 =cut
268 */
269
270 void
271 i_img_destroy(i_img *im) {
272   mm_log((1,"i_img_destroy(im %p)\n",im));
273   i_img_exorcise(im);
274   if (im) { myfree(im); }
275 }
276
277 /* 
278 =item i_img_info(im, info)
279
280 =category Image
281
282 Return image information
283
284    im - Image pointer
285    info - pointer to array to return data
286
287 info is an array of 4 integers with the following values:
288
289  info[0] - width
290  info[1] - height
291  info[2] - channels
292  info[3] - channel mask
293
294 =cut
295 */
296
297
298 void
299 i_img_info(i_img *im,int *info) {
300   mm_log((1,"i_img_info(im 0x%x)\n",im));
301   if (im != NULL) {
302     mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
303     mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
304     info[0] = im->xsize;
305     info[1] = im->ysize;
306     info[2] = im->channels;
307     info[3] = im->ch_mask;
308   } else {
309     info[0] = 0;
310     info[1] = 0;
311     info[2] = 0;
312     info[3] = 0;
313   }
314 }
315
316 /*
317 =item i_img_setmask(C<im>, C<ch_mask>)
318 =category Image Information
319 =synopsis // only channel 0 writeable 
320 =synopsis i_img_setmask(img, 0x01);
321
322 Set the image channel mask for C<im> to C<ch_mask>.
323
324 The image channel mask gives some control over which channels can be
325 written to in the image.
326
327 =cut
328 */
329 void
330 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
331
332
333 /*
334 =item i_img_getmask(C<im>)
335 =category Image Information
336 =synopsis int mask = i_img_getmask(img);
337
338 Get the image channel mask for C<im>.
339
340 =cut
341 */
342 int
343 i_img_getmask(i_img *im) { return im->ch_mask; }
344
345 /*
346 =item i_img_getchannels(C<im>)
347 =category Image Information
348 =synopsis int channels = i_img_getchannels(img);
349
350 Get the number of channels in C<im>.
351
352 =cut
353 */
354 int
355 i_img_getchannels(i_img *im) { return im->channels; }
356
357 /*
358 =item i_img_get_width(C<im>)
359 =category Image Information
360 =synopsis i_img_dim width = i_img_get_width(im);
361
362 Returns the width in pixels of the image.
363
364 =cut
365 */
366 i_img_dim
367 i_img_get_width(i_img *im) {
368   return im->xsize;
369 }
370
371 /*
372 =item i_img_get_height(C<im>)
373 =category Image Information
374 =synopsis i_img_dim height = i_img_get_height(im);
375
376 Returns the height in pixels of the image.
377
378 =cut
379 */
380 i_img_dim
381 i_img_get_height(i_img *im) {
382   return im->ysize;
383 }
384
385 /*
386 =item i_copyto_trans(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
387
388 =category Image
389
390 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
391 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
392 the target image.  pass NULL in C<trans> for non transparent i_colors.
393
394 =cut
395 */
396
397 void
398 i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,const i_color *trans) {
399   i_color pv;
400   int x,y,t,ttx,tty,tt,ch;
401
402   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",
403           im, src, x1, y1, x2, y2, tx, ty, trans));
404   
405   if (x2<x1) { t=x1; x1=x2; x2=t; }
406   if (y2<y1) { t=y1; y1=y2; y2=t; }
407
408   ttx=tx;
409   for(x=x1;x<x2;x++)
410     {
411       tty=ty;
412       for(y=y1;y<y2;y++)
413         {
414           i_gpix(src,x,y,&pv);
415           if ( trans != NULL)
416           {
417             tt=0;
418             for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
419             if (tt) i_ppix(im,ttx,tty,&pv);
420           } else i_ppix(im,ttx,tty,&pv);
421           tty++;
422         }
423       ttx++;
424     }
425 }
426
427 /*
428 =item i_copy(source)
429
430 =category Image
431
432 Creates a new image that is a copy of the image C<source>.
433
434 Tags are not copied, only the image data.
435
436 Returns: i_img *
437
438 =cut
439 */
440
441 i_img *
442 i_copy(i_img *src) {
443   int y, y1, x1;
444   i_img *im = i_sametype(src, src->xsize, src->ysize);
445
446   mm_log((1,"i_copy(src %p)\n", src));
447
448   if (!im)
449     return NULL;
450
451   x1 = src->xsize;
452   y1 = src->ysize;
453   if (src->type == i_direct_type) {
454     if (src->bits == i_8_bits) {
455       i_color *pv;
456       pv = mymalloc(sizeof(i_color) * x1);
457       
458       for (y = 0; y < y1; ++y) {
459         i_glin(src, 0, x1, y, pv);
460         i_plin(im, 0, x1, y, pv);
461       }
462       myfree(pv);
463     }
464     else {
465       i_fcolor *pv;
466
467       pv = mymalloc(sizeof(i_fcolor) * x1);
468       for (y = 0; y < y1; ++y) {
469         i_glinf(src, 0, x1, y, pv);
470         i_plinf(im, 0, x1, y, pv);
471       }
472       myfree(pv);
473     }
474   }
475   else {
476     i_palidx *vals;
477
478     vals = mymalloc(sizeof(i_palidx) * x1);
479     for (y = 0; y < y1; ++y) {
480       i_gpal(src, 0, x1, y, vals);
481       i_ppal(im, 0, x1, y, vals);
482     }
483     myfree(vals);
484   }
485
486   return im;
487 }
488
489
490
491
492
493
494 static
495 float
496 Lanczos(float x) {
497   float PIx, PIx2;
498   
499   PIx = PI * x;
500   PIx2 = PIx / 2.0;
501   
502   if ((x >= 2.0) || (x <= -2.0)) return (0.0);
503   else if (x == 0.0) return (1.0);
504   else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
505 }
506
507
508 /*
509 =item i_scaleaxis(im, value, axis)
510
511 Returns a new image object which is I<im> scaled by I<value> along
512 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
513
514 =cut
515 */
516
517 i_img*
518 i_scaleaxis(i_img *im, float Value, int Axis) {
519   int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
520   int LanczosWidthFactor;
521   float *l0, *l1, OldLocation;
522   int T; 
523   float t;
524   float F, PictureValue[MAXCHANNELS];
525   short psave;
526   i_color val,val1,val2;
527   i_img *new_img;
528   int has_alpha = i_img_has_alpha(im);
529   int color_chans = i_img_color_channels(im);
530
531   i_clear_error();
532   mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
533
534   if (Axis == XAXIS) {
535     hsize = (int)(0.5 + im->xsize * Value);
536     if (hsize < 1) {
537       hsize = 1;
538       Value = 1.0 / im->xsize;
539     }
540     vsize = im->ysize;
541     
542     jEnd = hsize;
543     iEnd = vsize;
544   } else {
545     hsize = im->xsize;
546     vsize = (int)(0.5 + im->ysize * Value);
547
548     if (vsize < 1) {
549       vsize = 1;
550       Value = 1.0 / im->ysize;
551     }
552
553     jEnd = vsize;
554     iEnd = hsize;
555   }
556   
557   new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
558   if (!new_img) {
559     i_push_error(0, "cannot create output image");
560     return NULL;
561   }
562   
563   /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
564   LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value); 
565   lMax = LanczosWidthFactor << 1;
566   
567   l0 = mymalloc(lMax * sizeof(float));
568   l1 = mymalloc(lMax * sizeof(float));
569   
570   for (j=0; j<jEnd; j++) {
571     OldLocation = ((float) j) / Value;
572     T = (int) (OldLocation);
573     F = OldLocation - (float) T;
574     
575     for (l = 0; l<lMax; l++) {
576       l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
577       l1[l]        = Lanczos(((float) (l+1)      - F) / (float) LanczosWidthFactor);
578     }
579     
580     /* Make sure filter is normalized */
581     t = 0.0;
582     for(l=0; l<lMax; l++) {
583       t+=l0[l];
584       t+=l1[l];
585     }
586     t /= (float)LanczosWidthFactor;
587     
588     for(l=0; l<lMax; l++) {
589       l0[l] /= t;
590       l1[l] /= t;
591     }
592
593     if (Axis == XAXIS) {
594       
595       for (i=0; i<iEnd; i++) {
596         for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
597         for (l=0; l<lMax; l++) {
598           int mx = T-lMax+l+1;
599           int Mx = T+l+1;
600           mx = (mx < 0) ? 0 : mx;
601           Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
602           
603           i_gpix(im, Mx, i, &val1);
604           i_gpix(im, mx, i, &val2);
605
606           if (has_alpha) {
607             i_sample_t alpha1 = val1.channel[color_chans];
608             i_sample_t alpha2 = val2.channel[color_chans];
609             for (k=0; k < color_chans; k++) {
610               PictureValue[k] += l1[l]        * val1.channel[k] * alpha1 / 255;
611               PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
612             }
613             PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
614             PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
615           }
616           else {
617             for (k=0; k<im->channels; k++) {
618               PictureValue[k] += l1[l]        * val1.channel[k];
619               PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
620             }
621           }
622         }
623
624         if (has_alpha) {
625           float fa = PictureValue[color_chans] / LanczosWidthFactor;
626           int alpha = minmax(0, 255, fa+0.5);
627           if (alpha) {
628             for (k = 0; k < color_chans; ++k) {
629               psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
630               val.channel[k]=minmax(0,255,psave);
631             }
632             val.channel[color_chans] = alpha;
633           }
634           else {
635             /* zero alpha, so the pixel has no color */
636             for (k = 0; k < im->channels; ++k)
637               val.channel[k] = 0;
638           }
639         }
640         else {
641           for(k=0;k<im->channels;k++) {
642             psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
643             val.channel[k]=minmax(0,255,psave);
644           }
645         }
646         i_ppix(new_img, j, i, &val);
647       }
648       
649     } else {
650       
651       for (i=0; i<iEnd; i++) {
652         for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
653         for (l=0; l < lMax; l++) {
654           int mx = T-lMax+l+1;
655           int Mx = T+l+1;
656           mx = (mx < 0) ? 0 : mx;
657           Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
658
659           i_gpix(im, i, Mx, &val1);
660           i_gpix(im, i, mx, &val2);
661           if (has_alpha) {
662             i_sample_t alpha1 = val1.channel[color_chans];
663             i_sample_t alpha2 = val2.channel[color_chans];
664             for (k=0; k < color_chans; k++) {
665               PictureValue[k] += l1[l]        * val1.channel[k] * alpha1 / 255;
666               PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
667             }
668             PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
669             PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
670           }
671           else {
672             for (k=0; k<im->channels; k++) {
673               PictureValue[k] += l1[l]        * val1.channel[k];
674               PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
675             }
676           }
677         }
678         if (has_alpha) {
679           float fa = PictureValue[color_chans] / LanczosWidthFactor;
680           int alpha = minmax(0, 255, fa+0.5);
681           if (alpha) {
682             for (k = 0; k < color_chans; ++k) {
683               psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
684               val.channel[k]=minmax(0,255,psave);
685             }
686             val.channel[color_chans] = alpha;
687           }
688           else {
689             for (k = 0; k < im->channels; ++k)
690               val.channel[k] = 0;
691           }
692         }
693         else {
694           for(k=0;k<im->channels;k++) {
695             psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
696             val.channel[k]=minmax(0,255,psave);
697           }
698         }
699         i_ppix(new_img, i, j, &val);
700       }
701       
702     }
703   }
704   myfree(l0);
705   myfree(l1);
706
707   mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
708
709   return new_img;
710 }
711
712
713 /* 
714 =item i_scale_nn(im, scx, scy)
715
716 Scale by using nearest neighbor 
717 Both axes scaled at the same time since 
718 nothing is gained by doing it in two steps 
719
720 =cut
721 */
722
723
724 i_img*
725 i_scale_nn(i_img *im, float scx, float scy) {
726
727   int nxsize,nysize,nx,ny;
728   i_img *new_img;
729   i_color val;
730
731   mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
732
733   nxsize = (int) ((float) im->xsize * scx);
734   if (nxsize < 1) {
735     nxsize = 1;
736     scx = 1.0 / im->xsize;
737   }
738   nysize = (int) ((float) im->ysize * scy);
739   if (nysize < 1) {
740     nysize = 1;
741     scy = 1.0 / im->ysize;
742   }
743   im_assert(scx != 0 && scy != 0);
744     
745   new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
746   
747   for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
748     i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
749     i_ppix(new_img,nx,ny,&val);
750   }
751
752   mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
753
754   return new_img;
755 }
756
757 /*
758 =item i_sametype(C<im>, C<xsize>, C<ysize>)
759
760 =category Image creation/destruction
761 =synopsis i_img *img = i_sametype(src, width, height);
762
763 Returns an image of the same type (sample size, channels, paletted/direct).
764
765 For paletted images the palette is copied from the source.
766
767 =cut
768 */
769
770 i_img *i_sametype(i_img *src, int xsize, int ysize) {
771   if (src->type == i_direct_type) {
772     if (src->bits == 8) {
773       return i_img_empty_ch(NULL, xsize, ysize, src->channels);
774     }
775     else if (src->bits == i_16_bits) {
776       return i_img_16_new(xsize, ysize, src->channels);
777     }
778     else if (src->bits == i_double_bits) {
779       return i_img_double_new(xsize, ysize, src->channels);
780     }
781     else {
782       i_push_error(0, "Unknown image bits");
783       return NULL;
784     }
785   }
786   else {
787     i_color col;
788     int i;
789
790     i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
791     for (i = 0; i < i_colorcount(src); ++i) {
792       i_getcolors(src, i, &col, 1);
793       i_addcolors(targ, &col, 1);
794     }
795
796     return targ;
797   }
798 }
799
800 /*
801 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
802
803 =category Image creation/destruction
804 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
805
806 Returns an image of the same type (sample size).
807
808 For paletted images the equivalent direct type is returned.
809
810 =cut
811 */
812
813 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
814   if (src->bits == 8) {
815     return i_img_empty_ch(NULL, xsize, ysize, channels);
816   }
817   else if (src->bits == i_16_bits) {
818     return i_img_16_new(xsize, ysize, channels);
819   }
820   else if (src->bits == i_double_bits) {
821     return i_img_double_new(xsize, ysize, channels);
822   }
823   else {
824     i_push_error(0, "Unknown image bits");
825     return NULL;
826   }
827 }
828
829 /*
830 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
831
832 Spatially transforms I<im> returning a new image.
833
834 opx for a length of opxl and opy for a length of opy are arrays of
835 operators that modify the x and y positions to retreive the pixel data from.
836
837 parm and parmlen define extra parameters that the operators may use.
838
839 Note that this function is largely superseded by the more flexible
840 L<transform.c/i_transform2>.
841
842 Returns the new image.
843
844 The operators for this function are defined in L<stackmach.c>.
845
846 =cut
847 */
848 i_img*
849 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
850   double rx,ry;
851   int nxsize,nysize,nx,ny;
852   i_img *new_img;
853   i_color val;
854   
855   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));
856
857   nxsize = im->xsize;
858   nysize = im->ysize ;
859   
860   new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
861   /*   fprintf(stderr,"parm[2]=%f\n",parm[2]);   */
862   for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
863     /*     parm[parmlen-2]=(double)nx;
864            parm[parmlen-1]=(double)ny; */
865
866     parm[0]=(double)nx;
867     parm[1]=(double)ny;
868
869     /*     fprintf(stderr,"(%d,%d) ->",nx,ny);  */
870     rx=i_op_run(opx,opxl,parm,parmlen);
871     ry=i_op_run(opy,opyl,parm,parmlen);
872     /*    fprintf(stderr,"(%f,%f)\n",rx,ry); */
873     i_gpix(im,rx,ry,&val);
874     i_ppix(new_img,nx,ny,&val);
875   }
876
877   mm_log((1,"(0x%x) <- i_transform\n",new_img));
878   return new_img;
879 }
880
881 /*
882 =item i_img_diff(im1, im2)
883
884 Calculates the sum of the squares of the differences between
885 correspoding channels in two images.
886
887 If the images are not the same size then only the common area is 
888 compared, hence even if images are different sizes this function 
889 can return zero.
890
891 =cut
892 */
893
894 float
895 i_img_diff(i_img *im1,i_img *im2) {
896   int x,y,ch,xb,yb,chb;
897   float tdiff;
898   i_color val1,val2;
899
900   mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
901
902   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
903   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
904   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
905
906   mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
907
908   tdiff=0;
909   for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
910     i_gpix(im1,x,y,&val1);
911     i_gpix(im2,x,y,&val2);
912
913     for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
914   }
915   mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
916   return tdiff;
917 }
918
919 /*
920 =item i_img_diffd(im1, im2)
921
922 Calculates the sum of the squares of the differences between
923 correspoding channels in two images.
924
925 If the images are not the same size then only the common area is 
926 compared, hence even if images are different sizes this function 
927 can return zero.
928
929 This is like i_img_diff() but looks at floating point samples instead.
930
931 =cut
932 */
933
934 double
935 i_img_diffd(i_img *im1,i_img *im2) {
936   int x,y,ch,xb,yb,chb;
937   double tdiff;
938   i_fcolor val1,val2;
939
940   mm_log((1,"i_img_diffd(im1 0x%x,im2 0x%x)\n",im1,im2));
941
942   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
943   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
944   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
945
946   mm_log((1,"i_img_diffd: xb=%d xy=%d chb=%d\n",xb,yb,chb));
947
948   tdiff=0;
949   for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
950     i_gpixf(im1,x,y,&val1);
951     i_gpixf(im2,x,y,&val2);
952
953     for(ch=0;ch<chb;ch++) {
954       double sdiff = val1.channel[ch]-val2.channel[ch];
955       tdiff += sdiff * sdiff;
956     }
957   }
958   mm_log((1,"i_img_diffd <- (%.2f)\n",tdiff));
959
960   return tdiff;
961 }
962
963 int
964 i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
965   int x,y,ch,xb,yb,chb;
966   i_fcolor val1,val2;
967
968   if (what == NULL)
969     what = "(null)";
970
971   mm_log((1,"i_img_samef(im1 0x%x,im2 0x%x, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
972
973   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
974   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
975   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
976
977   mm_log((1,"i_img_samef: xb=%d xy=%d chb=%d\n",xb,yb,chb));
978
979   for(y = 0; y < yb; y++) {
980     for(x = 0; x < xb; x++) {
981       i_gpixf(im1, x, y, &val1);
982       i_gpixf(im2, x, y, &val2);
983       
984       for(ch = 0; ch < chb; ch++) {
985         double sdiff = val1.channel[ch] - val2.channel[ch];
986         if (fabs(sdiff) > epsilon) {
987           mm_log((1,"i_img_samef <- different %g @(%d,%d)\n", sdiff, x, y));
988           return 0;
989         }
990       }
991     }
992   }
993   mm_log((1,"i_img_samef <- same\n"));
994
995   return 1;
996 }
997
998 /* just a tiny demo of haar wavelets */
999
1000 i_img*
1001 i_haar(i_img *im) {
1002   int mx,my;
1003   int fx,fy;
1004   int x,y;
1005   int ch,c;
1006   i_img *new_img,*new_img2;
1007   i_color val1,val2,dval1,dval2;
1008   
1009   mx=im->xsize;
1010   my=im->ysize;
1011   fx=(mx+1)/2;
1012   fy=(my+1)/2;
1013
1014
1015   /* horizontal pass */
1016   
1017   new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1018   new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1019
1020   c=0; 
1021   for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1022     i_gpix(im,x*2,y,&val1);
1023     i_gpix(im,x*2+1,y,&val2);
1024     for(ch=0;ch<im->channels;ch++) {
1025       dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1026       dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1027     }
1028     i_ppix(new_img,x,y,&dval1);
1029     i_ppix(new_img,x+fx,y,&dval2);
1030   }
1031
1032   for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1033     i_gpix(new_img,x,y*2,&val1);
1034     i_gpix(new_img,x,y*2+1,&val2);
1035     for(ch=0;ch<im->channels;ch++) {
1036       dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1037       dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1038     }
1039     i_ppix(new_img2,x,y,&dval1);
1040     i_ppix(new_img2,x,y+fy,&dval2);
1041   }
1042
1043   i_img_destroy(new_img);
1044   return new_img2;
1045 }
1046
1047 /* 
1048 =item i_count_colors(im, maxc)
1049
1050 returns number of colors or -1 
1051 to indicate that it was more than max colors
1052
1053 =cut
1054 */
1055 /* This function has been changed and is now faster. It's using
1056  * i_gsamp instead of i_gpix */
1057 int
1058 i_count_colors(i_img *im,int maxc) {
1059   struct octt *ct;
1060   int x,y;
1061   int colorcnt;
1062   int channels[3];
1063   int *samp_chans;
1064   i_sample_t * samp;
1065   int xsize = im->xsize; 
1066   int ysize = im->ysize;
1067   int samp_cnt = 3 * xsize;
1068
1069   if (im->channels >= 3) {
1070     samp_chans = NULL;
1071   }
1072   else {
1073     channels[0] = channels[1] = channels[2] = 0;
1074     samp_chans = channels;
1075   }
1076
1077   ct = octt_new();
1078
1079   samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1080
1081   colorcnt = 0;
1082   for(y = 0; y < ysize; ) {
1083       i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1084       for(x = 0; x < samp_cnt; ) {
1085           colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1086           x += 3;
1087           if (colorcnt > maxc) { 
1088               octt_delete(ct); 
1089               return -1; 
1090           }
1091       }
1092   }
1093   myfree(samp);
1094   octt_delete(ct);
1095   return colorcnt;
1096 }
1097
1098 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm 
1099  * (adapted from the Numerical Recipes)
1100  */
1101 /* Needed by get_anonymous_color_histo */
1102 static void
1103 hpsort(unsigned int n, unsigned *ra) {
1104     unsigned int i,
1105                  ir,
1106                  j,
1107                  l, 
1108                  rra;
1109
1110     if (n < 2) return;
1111     l = n >> 1;
1112     ir = n - 1;
1113     for(;;) {
1114         if (l > 0) {
1115             rra = ra[--l];
1116         }
1117         else {
1118             rra = ra[ir];
1119             ra[ir] = ra[0];
1120             if (--ir == 0) {
1121                 ra[0] = rra;
1122                 break;
1123             }
1124         }
1125         i = l;
1126         j = 2 * l + 1;
1127         while (j <= ir) {
1128             if (j < ir && ra[j] < ra[j+1]) j++;
1129             if (rra < ra[j]) {
1130                 ra[i] = ra[j];
1131                 i = j;
1132                 j++; j <<= 1; j--;
1133             }
1134             else break;
1135         }
1136         ra[i] = rra;
1137     }
1138 }
1139
1140 /* This function constructs an ordered list which represents how much the
1141  * different colors are used. So for instance (100, 100, 500) means that one
1142  * color is used for 500 pixels, another for 100 pixels and another for 100
1143  * pixels. It's tuned for performance. You might not like the way I've hardcoded
1144  * the maxc ;-) and you might want to change the name... */
1145 /* Uses octt_histo */
1146 int
1147 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1148   struct octt *ct;
1149   int x,y;
1150   int colorcnt;
1151   unsigned int *col_usage_it;
1152   i_sample_t * samp;
1153   int channels[3];
1154   int *samp_chans;
1155   
1156   int xsize = im->xsize; 
1157   int ysize = im->ysize;
1158   int samp_cnt = 3 * xsize;
1159   ct = octt_new();
1160   
1161   samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1162   
1163   if (im->channels >= 3) {
1164     samp_chans = NULL;
1165   }
1166   else {
1167     channels[0] = channels[1] = channels[2] = 0;
1168     samp_chans = channels;
1169   }
1170
1171   colorcnt = 0;
1172   for(y = 0; y < ysize; ) {
1173     i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1174     for(x = 0; x < samp_cnt; ) {
1175       colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1176       x += 3;
1177       if (colorcnt > maxc) { 
1178         octt_delete(ct); 
1179         return -1; 
1180       }
1181     }
1182   }
1183   myfree(samp);
1184   /* Now that we know the number of colours... */
1185   col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1186   octt_histo(ct, &col_usage_it);
1187   hpsort(colorcnt, *col_usage);
1188   octt_delete(ct);
1189   return colorcnt;
1190 }
1191
1192 /*
1193 =back
1194
1195 =head2 Image method wrappers
1196
1197 These functions provide i_fsample_t functions in terms of their
1198 i_sample_t versions.
1199
1200 =over
1201
1202 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1203
1204 =cut
1205 */
1206
1207 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1208   i_color temp;
1209   int ch;
1210
1211   for (ch = 0; ch < im->channels; ++ch)
1212     temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1213   
1214   return i_ppix(im, x, y, &temp);
1215 }
1216
1217 /*
1218 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1219
1220 =cut
1221 */
1222 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1223   i_color temp;
1224   int ch;
1225
1226   if (i_gpix(im, x, y, &temp)) {
1227     for (ch = 0; ch < im->channels; ++ch)
1228       pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1229     return 0;
1230   }
1231   else 
1232     return -1;
1233 }
1234
1235 /*
1236 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1237
1238 =cut
1239 */
1240 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1241   i_color *work;
1242
1243   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1244     if (r > im->xsize)
1245       r = im->xsize;
1246     if (r > l) {
1247       int ret;
1248       int i, ch;
1249       work = mymalloc(sizeof(i_color) * (r-l));
1250       for (i = 0; i < r-l; ++i) {
1251         for (ch = 0; ch < im->channels; ++ch) 
1252           work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1253       }
1254       ret = i_plin(im, l, r, y, work);
1255       myfree(work);
1256
1257       return ret;
1258     }
1259     else {
1260       return 0;
1261     }
1262   }
1263   else {
1264     return 0;
1265   }
1266 }
1267
1268 /*
1269 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1270
1271 =cut
1272 */
1273 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1274   i_color *work;
1275
1276   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1277     if (r > im->xsize)
1278       r = im->xsize;
1279     if (r > l) {
1280       int ret;
1281       int i, ch;
1282       work = mymalloc(sizeof(i_color) * (r-l));
1283       ret = i_plin(im, l, r, y, work);
1284       for (i = 0; i < r-l; ++i) {
1285         for (ch = 0; ch < im->channels; ++ch) 
1286           pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1287       }
1288       myfree(work);
1289
1290       return ret;
1291     }
1292     else {
1293       return 0;
1294     }
1295   }
1296   else {
1297     return 0;
1298   }
1299 }
1300
1301 /*
1302 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1303
1304 =cut
1305 */
1306 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, 
1307                 int const *chans, int chan_count) {
1308   i_sample_t *work;
1309
1310   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1311     if (r > im->xsize)
1312       r = im->xsize;
1313     if (r > l) {
1314       int ret;
1315       int i;
1316       work = mymalloc(sizeof(i_sample_t) * (r-l));
1317       ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1318       for (i = 0; i < ret; ++i) {
1319           samp[i] = Sample8ToF(work[i]);
1320       }
1321       myfree(work);
1322
1323       return ret;
1324     }
1325     else {
1326       return 0;
1327     }
1328   }
1329   else {
1330     return 0;
1331   }
1332 }
1333
1334 /*
1335 =back
1336
1337 =head2 Palette wrapper functions
1338
1339 Used for virtual images, these forward palette calls to a wrapped image, 
1340 assuming the wrapped image is the first pointer in the structure that 
1341 im->ext_data points at.
1342
1343 =over
1344
1345 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1346
1347 =cut
1348 */
1349 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1350   return i_addcolors(*(i_img **)im->ext_data, colors, count);
1351 }
1352
1353 /*
1354 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1355
1356 =cut
1357 */
1358 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1359   return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1360 }
1361
1362 /*
1363 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1364
1365 =cut
1366 */
1367 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1368   return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1369 }
1370
1371 /*
1372 =item i_colorcount_forward(i_img *im)
1373
1374 =cut
1375 */
1376 int i_colorcount_forward(i_img *im) {
1377   return i_colorcount(*(i_img **)im->ext_data);
1378 }
1379
1380 /*
1381 =item i_maxcolors_forward(i_img *im)
1382
1383 =cut
1384 */
1385 int i_maxcolors_forward(i_img *im) {
1386   return i_maxcolors(*(i_img **)im->ext_data);
1387 }
1388
1389 /*
1390 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1391
1392 =cut
1393 */
1394 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1395   return i_findcolor(*(i_img **)im->ext_data, color, entry);
1396 }
1397
1398 /*
1399 =back
1400
1401 =head2 Fallback handler
1402
1403 =over
1404
1405 =item i_gsamp_bits_fb
1406
1407 =cut
1408 */
1409
1410 int 
1411 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps, 
1412                 const int *chans, int chan_count, int bits) {
1413   if (bits < 1 || bits > 32) {
1414     i_push_error(0, "Invalid bits, must be 1..32");
1415     return -1;
1416   }
1417
1418   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1419     double scale;
1420     int ch, count, i, w;
1421     
1422     if (bits == 32)
1423       scale = 4294967295.0;
1424     else
1425       scale = (double)(1 << bits) - 1;
1426
1427     if (r > im->xsize)
1428       r = im->xsize;
1429     w = r - l;
1430     count = 0;
1431
1432     if (chans) {
1433       /* make sure we have good channel numbers */
1434       for (ch = 0; ch < chan_count; ++ch) {
1435         if (chans[ch] < 0 || chans[ch] >= im->channels) {
1436           i_push_errorf(0, "No channel %d in this image", chans[ch]);
1437           return -1;
1438         }
1439       }
1440       for (i = 0; i < w; ++i) {
1441         i_fcolor c;
1442         i_gpixf(im, l+i, y, &c);
1443         for (ch = 0; ch < chan_count; ++ch) {
1444           *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1445           ++count;
1446         }
1447       }
1448     }
1449     else {
1450       if (chan_count <= 0 || chan_count > im->channels) {
1451         i_push_error(0, "Invalid channel count");
1452         return -1;
1453       }
1454       for (i = 0; i < w; ++i) {
1455         i_fcolor c;
1456         i_gpixf(im, l+i, y, &c);
1457         for (ch = 0; ch < chan_count; ++ch) {
1458           *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1459           ++count;
1460         }
1461       }
1462     }
1463
1464     return count;
1465   }
1466   else {
1467     i_push_error(0, "Image position outside of image");
1468     return -1;
1469   }
1470 }
1471
1472 /*
1473 =back
1474
1475 =head2 Stream reading and writing wrapper functions
1476
1477 =over
1478
1479 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1480
1481 Performs general read buffering for file readers that permit reading
1482 to be done through a callback.
1483
1484 The final callback gets two parameters, a I<need> value, and a I<want>
1485 value, where I<need> is the amount of data that the file library needs
1486 to read, and I<want> is the amount of space available in the buffer
1487 maintained by these functions.
1488
1489 This means if you need to read from a stream that you don't know the
1490 length of, you can return I<need> bytes, taking the performance hit of
1491 possibly expensive callbacks (eg. back to perl code), or if you are
1492 reading from a stream where it doesn't matter if some data is lost, or
1493 if the total length of the stream is known, you can return I<want>
1494 bytes.
1495
1496 =cut 
1497 */
1498
1499 int
1500 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
1501   int total;
1502
1503   if (length < gci->length - gci->cpos) {
1504     /* simplest case */
1505     memcpy(buf, gci->buffer+gci->cpos, length);
1506     gci->cpos += length;
1507     return length;
1508   }
1509   
1510   total = 0;
1511   memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
1512   total  += gci->length - gci->cpos;
1513   length -= gci->length - gci->cpos;
1514   buf    += gci->length - gci->cpos;
1515   if (length < (int)sizeof(gci->buffer)) {
1516     int did_read;
1517     int copy_size;
1518     while (length
1519            && (did_read = (gci->cb)(gci->userdata, gci->buffer, length, 
1520                                     sizeof(gci->buffer))) > 0) {
1521       gci->cpos = 0;
1522       gci->length = did_read;
1523
1524       copy_size = i_min(length, gci->length);
1525       memcpy(buf, gci->buffer, copy_size);
1526       gci->cpos += copy_size;
1527       buf += copy_size;
1528       total += copy_size;
1529       length -= copy_size;
1530     }
1531   }
1532   else {
1533     /* just read the rest - too big for our buffer*/
1534     int did_read;
1535     while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
1536       length -= did_read;
1537       total += did_read;
1538       buf += did_read;
1539     }
1540   }
1541   return total;
1542 }
1543
1544 /*
1545 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
1546
1547 For use by callback file readers to initialize the reader buffer.
1548
1549 Allocates, initializes and returns the reader buffer.
1550
1551 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
1552
1553 =cut
1554 */
1555 i_gen_read_data *
1556 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
1557   i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
1558   self->cb = cb;
1559   self->userdata = userdata;
1560   self->length = 0;
1561   self->cpos = 0;
1562
1563   return self;
1564 }
1565
1566 /*
1567 =item i_free_gen_read_data(i_gen_read_data *)
1568
1569 Cleans up.
1570
1571 =cut
1572 */
1573 void i_free_gen_read_data(i_gen_read_data *self) {
1574   myfree(self);
1575 }
1576
1577 /*
1578 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
1579
1580 Performs write buffering for a callback based file writer.
1581
1582 Failures are considered fatal, if a write fails then data will be
1583 dropped.
1584
1585 =cut
1586 */
1587 int 
1588 i_gen_writer(
1589 i_gen_write_data *self, 
1590 char const *data, 
1591 int size)
1592 {
1593   if (self->filledto && self->filledto+size > self->maxlength) {
1594     if (self->cb(self->userdata, self->buffer, self->filledto)) {
1595       self->filledto = 0;
1596     }
1597     else {
1598       self->filledto = 0;
1599       return 0;
1600     }
1601   }
1602   if (self->filledto+size <= self->maxlength) {
1603     /* just save it */
1604     memcpy(self->buffer+self->filledto, data, size);
1605     self->filledto += size;
1606     return 1;
1607   }
1608   /* doesn't fit - hand it off */
1609   return self->cb(self->userdata, data, size);
1610 }
1611
1612 /*
1613 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
1614
1615 Allocates and initializes the data structure used by i_gen_writer.
1616
1617 This should be released with L<image.c/i_free_gen_write_data>
1618
1619 =cut
1620 */
1621 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb, 
1622                                        char *userdata, int max_length)
1623 {
1624   i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
1625   self->cb = cb;
1626   self->userdata = userdata;
1627   self->maxlength = i_min(max_length, sizeof(self->buffer));
1628   if (self->maxlength < 0)
1629     self->maxlength = sizeof(self->buffer);
1630   self->filledto = 0;
1631
1632   return self;
1633 }
1634
1635 /*
1636 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
1637
1638 Cleans up the write buffer.
1639
1640 Will flush any left-over data if I<flush> is non-zero.
1641
1642 Returns non-zero if flush is zero or if info->cb() returns non-zero.
1643
1644 Return zero only if flush is non-zero and info->cb() returns zero.
1645 ie. if it fails.
1646
1647 =cut
1648 */
1649
1650 int i_free_gen_write_data(i_gen_write_data *info, int flush)
1651 {
1652   int result = !flush || 
1653     info->filledto == 0 ||
1654     info->cb(info->userdata, info->buffer, info->filledto);
1655   myfree(info);
1656
1657   return result;
1658 }
1659
1660 struct magic_entry {
1661   unsigned char *magic;
1662   size_t magic_size;
1663   char *name;
1664   unsigned char *mask;  
1665 };
1666
1667 static int
1668 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
1669   if (length < magic->magic_size)
1670     return 0;
1671   if (magic->mask) {
1672     int i;
1673     unsigned char *bufp = buffer, 
1674       *maskp = magic->mask, 
1675       *magicp = magic->magic;
1676
1677     for (i = 0; i < magic->magic_size; ++i) {
1678       int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
1679       ++maskp;
1680
1681       if ((*bufp++ & mask) != (*magicp++ & mask)) 
1682         return 0;
1683     }
1684
1685     return 1;
1686   }
1687   else {
1688     return !memcmp(magic->magic, buffer, magic->magic_size);
1689   }
1690 }
1691
1692 /*
1693 =item i_test_format_probe(io_glue *data, int length)
1694
1695 Check the beginning of the supplied file for a 'magic number'
1696
1697 =cut
1698 */
1699
1700 #define FORMAT_ENTRY(magic, type) \
1701   { (unsigned char *)(magic ""), sizeof(magic)-1, type }
1702 #define FORMAT_ENTRY2(magic, type, mask) \
1703   { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
1704
1705 const char *
1706 i_test_format_probe(io_glue *data, int length) {
1707   static const struct magic_entry formats[] = {
1708     FORMAT_ENTRY("\xFF\xD8", "jpeg"),
1709     FORMAT_ENTRY("GIF87a", "gif"),
1710     FORMAT_ENTRY("GIF89a", "gif"),
1711     FORMAT_ENTRY("MM\0*", "tiff"),
1712     FORMAT_ENTRY("II*\0", "tiff"),
1713     FORMAT_ENTRY("BM", "bmp"),
1714     FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
1715     FORMAT_ENTRY("P1", "pnm"),
1716     FORMAT_ENTRY("P2", "pnm"),
1717     FORMAT_ENTRY("P3", "pnm"),
1718     FORMAT_ENTRY("P4", "pnm"),
1719     FORMAT_ENTRY("P5", "pnm"),
1720     FORMAT_ENTRY("P6", "pnm"),
1721     FORMAT_ENTRY("/* XPM", "xpm"),
1722     FORMAT_ENTRY("\x8aMNG", "mng"),
1723     FORMAT_ENTRY("\x8aJNG", "jng"),
1724     /* SGI RGB - with various possible parameters to avoid false positives
1725        on similar files 
1726        values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
1727     */
1728     FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
1729     FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
1730     FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
1731     FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
1732     
1733     FORMAT_ENTRY2("FORM    ILBM", "ilbm", "xxxx    xxxx"),
1734
1735     /* different versions of PCX format 
1736        http://www.fileformat.info/format/pcx/
1737     */
1738     FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
1739     FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
1740     FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
1741     FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
1742     FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
1743
1744     /* FITS - http://fits.gsfc.nasa.gov/ */
1745     FORMAT_ENTRY("SIMPLE  =", "fits"),
1746
1747     /* PSD - Photoshop */
1748     FORMAT_ENTRY("8BPS\x00\x01", "psd"),
1749     
1750     /* EPS - Encapsulated Postscript */
1751     /* only reading 18 chars, so we don't include the F in EPSF */
1752     FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
1753
1754     /* Utah RLE */
1755     FORMAT_ENTRY("\x52\xCC", "utah"),
1756
1757     /* GZIP compressed, only matching deflate for now */
1758     FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
1759
1760     /* bzip2 compressed */
1761     FORMAT_ENTRY("BZh", "bzip2"),
1762
1763     /* WEBP
1764        http://code.google.com/speed/webp/docs/riff_container.html */
1765     FORMAT_ENTRY2("RIFF    WEBP", "webp", "xxxx    xxxx"),
1766
1767     /* JPEG 2000 
1768        This might match a little loosely */
1769     FORMAT_ENTRY("\x00\x00\x00\x0CjP  \x0D\x0A\x87\x0A", "jp2"),
1770   };
1771   static const struct magic_entry more_formats[] = {
1772     /* these were originally both listed as ico, but cur files can
1773        include hotspot information */
1774     FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
1775     FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
1776     FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07", 
1777                   "xwd", "    xxxx"), /* X Windows Dump */
1778   };
1779
1780   unsigned int i;
1781   unsigned char head[18];
1782   ssize_t rc;
1783
1784   io_glue_commit_types(data);
1785   rc = data->readcb(data, head, 18);
1786   if (rc == -1) return NULL;
1787   data->seekcb(data, -rc, SEEK_CUR);
1788
1789   for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) { 
1790     struct magic_entry const *entry = formats + i;
1791
1792     if (test_magic(head, rc, entry)) 
1793       return entry->name;
1794   }
1795
1796   if ((rc == 18) &&
1797       tga_header_verify(head))
1798     return "tga";
1799
1800   for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) { 
1801     struct magic_entry const *entry = more_formats + i;
1802
1803     if (test_magic(head, rc, entry)) 
1804       return entry->name;
1805   }
1806
1807   return NULL;
1808 }
1809
1810 /*
1811 =item i_img_is_monochrome(img, &zero_is_white)
1812
1813 =category Image Information
1814
1815 Tests an image to check it meets our monochrome tests.
1816
1817 The idea is that a file writer can use this to test where it should
1818 write the image in whatever bi-level format it uses, eg. C<pbm> for
1819 C<pnm>.
1820
1821 For performance of encoders we require monochrome images:
1822
1823 =over
1824
1825 =item *
1826
1827 be paletted
1828
1829 =item *
1830
1831 have a palette of two colors, containing only C<(0,0,0)> and
1832 C<(255,255,255)> in either order.
1833
1834 =back
1835
1836 C<zero_is_white> is set to non-zero if the first palette entry is white.
1837
1838 =cut
1839 */
1840
1841 int
1842 i_img_is_monochrome(i_img *im, int *zero_is_white) {
1843   if (im->type == i_palette_type
1844       && i_colorcount(im) == 2) {
1845     i_color colors[2];
1846     i_getcolors(im, 0, colors, 2);
1847     if (im->channels == 3) {
1848       if (colors[0].rgb.r == 255 && 
1849           colors[0].rgb.g == 255 &&
1850           colors[0].rgb.b == 255 &&
1851           colors[1].rgb.r == 0 &&
1852           colors[1].rgb.g == 0 &&
1853           colors[1].rgb.b == 0) {
1854         *zero_is_white = 1;
1855         return 1;
1856       }
1857       else if (colors[0].rgb.r == 0 && 
1858                colors[0].rgb.g == 0 &&
1859                colors[0].rgb.b == 0 &&
1860                colors[1].rgb.r == 255 &&
1861                colors[1].rgb.g == 255 &&
1862                colors[1].rgb.b == 255) {
1863         *zero_is_white = 0;
1864         return 1;
1865       }
1866     }
1867     else if (im->channels == 1) {
1868       if (colors[0].channel[0] == 255 &&
1869           colors[1].channel[0] == 0) {
1870         *zero_is_white = 1;
1871         return 1;
1872       }
1873       else if (colors[0].channel[0] == 0 &&
1874                colors[1].channel[0] == 255) {
1875         *zero_is_white = 0;
1876         return 1;         
1877       }
1878     }
1879   }
1880
1881   *zero_is_white = 0;
1882   return 0;
1883 }
1884
1885 /*
1886 =item i_get_file_background(im, &bg)
1887
1888 =category Files
1889
1890 Retrieve the file write background color tag from the image.
1891
1892 If not present, returns black.
1893
1894 =cut
1895 */
1896
1897 void
1898 i_get_file_background(i_img *im, i_color *bg) {
1899   if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
1900     /* black default */
1901     bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
1902   }
1903   /* always full alpha */
1904   bg->channel[3] = 255;
1905 }
1906
1907 /*
1908 =item i_get_file_backgroundf(im, &bg)
1909
1910 =category Files
1911
1912 Retrieve the file write background color tag from the image as a
1913 floating point color.
1914
1915 Implemented in terms of i_get_file_background().
1916
1917 If not present, returns black.
1918
1919 =cut
1920 */
1921
1922 void
1923 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
1924   i_color bg;
1925
1926   i_get_file_background(im, &bg);
1927   fbg->rgba.r = Sample8ToF(bg.rgba.r);
1928   fbg->rgba.g = Sample8ToF(bg.rgba.g);
1929   fbg->rgba.b = Sample8ToF(bg.rgba.b);
1930   fbg->rgba.a = 1.0;
1931 }
1932
1933 /*
1934 =back
1935
1936 =head1 AUTHOR
1937
1938 Arnar M. Hrafnkelsson <addi@umich.edu>
1939
1940 Tony Cook <tony@develop-help.com>
1941
1942 =head1 SEE ALSO
1943
1944 L<Imager>, L<gif.c>
1945
1946 =cut
1947 */