]> git.imager.perl.org - imager.git/blob - image.c
test coverage and fix pass for compose()
[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 static int i_ppix_d(i_img *im, int x, int y, const i_color *val);
43 static int i_gpix_d(i_img *im, int x, int y, i_color *val);
44 static int i_glin_d(i_img *im, int l, int r, int y, i_color *vals);
45 static int i_plin_d(i_img *im, int l, int r, int y, const i_color *vals);
46 static int i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val);
47 static int i_gpixf_d(i_img *im, int x, int y, i_fcolor *val);
48 static int i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals);
49 static int i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals);
50 static int i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, const int *chans, int chan_count);
51 static int i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, const int *chans, int chan_count);
52
53 /*
54 =item i_img_alloc()
55 =category Image Implementation
56
57 Allocates a new i_img structure.
58
59 When implementing a new image type perform the following steps in your
60 image object creation function:
61
62 =over
63
64 =item 1.
65
66 allocate the image with i_img_alloc().
67
68 =item 2.
69
70 initialize any function pointers or other data as needed, you can
71 overwrite the whole block if you need to.
72
73 =item 3.
74
75 initialize Imager's internal data by calling i_img_init() on the image
76 object.
77
78 =back
79
80 =cut
81 */
82
83 i_img *
84 i_img_alloc(void) {
85   return mymalloc(sizeof(i_img));
86 }
87
88 /*
89 =item i_img_init(C<img>)
90 =category Image Implementation
91
92 Imager internal initialization of images.
93
94 Currently this does very little, in the future it may be used to
95 support threads, or color profiles.
96
97 =cut
98 */
99
100 void
101 i_img_init(i_img *img) {
102   img->im_data = NULL;
103 }
104
105 /* 
106 =item ICL_new_internal(r, g, b, a)
107
108 Return a new color object with values passed to it.
109
110    r - red   component (range: 0 - 255)
111    g - green component (range: 0 - 255)
112    b - blue  component (range: 0 - 255)
113    a - alpha component (range: 0 - 255)
114
115 =cut
116 */
117
118 i_color *
119 ICL_new_internal(unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
120   i_color *cl = NULL;
121
122   mm_log((1,"ICL_new_internal(r %d,g %d,b %d,a %d)\n", r, g, b, a));
123
124   if ( (cl=mymalloc(sizeof(i_color))) == NULL) i_fatal(2,"malloc() error\n");
125   cl->rgba.r = r;
126   cl->rgba.g = g;
127   cl->rgba.b = b;
128   cl->rgba.a = a;
129   mm_log((1,"(%p) <- ICL_new_internal\n",cl));
130   return cl;
131 }
132
133
134 /*
135 =item ICL_set_internal(cl, r, g, b, a)
136
137  Overwrite a color with new values.
138
139    cl - pointer to color object
140    r - red   component (range: 0 - 255)
141    g - green component (range: 0 - 255)
142    b - blue  component (range: 0 - 255)
143    a - alpha component (range: 0 - 255)
144
145 =cut
146 */
147
148 i_color *
149 ICL_set_internal(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
150   mm_log((1,"ICL_set_internal(cl* %p,r %d,g %d,b %d,a %d)\n",cl,r,g,b,a));
151   if (cl == NULL)
152     if ( (cl=mymalloc(sizeof(i_color))) == NULL)
153       i_fatal(2,"malloc() error\n");
154   cl->rgba.r=r;
155   cl->rgba.g=g;
156   cl->rgba.b=b;
157   cl->rgba.a=a;
158   mm_log((1,"(%p) <- ICL_set_internal\n",cl));
159   return cl;
160 }
161
162
163 /* 
164 =item ICL_add(dst, src, ch)
165
166 Add src to dst inplace - dst is modified.
167
168    dst - pointer to destination color object
169    src - pointer to color object that is added
170    ch - number of channels
171
172 =cut
173 */
174
175 void
176 ICL_add(i_color *dst,i_color *src,int ch) {
177   int tmp,i;
178   for(i=0;i<ch;i++) {
179     tmp=dst->channel[i]+src->channel[i];
180     dst->channel[i]= tmp>255 ? 255:tmp;
181   }
182 }
183
184 /* 
185 =item ICL_info(cl)
186
187 Dump color information to log - strictly for debugging.
188
189    cl - pointer to color object
190
191 =cut
192 */
193
194 void
195 ICL_info(i_color const *cl) {
196   mm_log((1,"i_color_info(cl* %p)\n",cl));
197   mm_log((1,"i_color_info: (%d,%d,%d,%d)\n",cl->rgba.r,cl->rgba.g,cl->rgba.b,cl->rgba.a));
198 }
199
200 /* 
201 =item ICL_DESTROY
202
203 Destroy ancillary data for Color object.
204
205    cl - pointer to color object
206
207 =cut
208 */
209
210 void
211 ICL_DESTROY(i_color *cl) {
212   mm_log((1,"ICL_DESTROY(cl* %p)\n",cl));
213   myfree(cl);
214 }
215
216 /*
217 =item i_fcolor_new(double r, double g, double b, double a)
218
219 =cut
220 */
221 i_fcolor *i_fcolor_new(double r, double g, double b, double a) {
222   i_fcolor *cl = NULL;
223
224   mm_log((1,"i_fcolor_new(r %g,g %g,b %g,a %g)\n", r, g, b, a));
225
226   if ( (cl=mymalloc(sizeof(i_fcolor))) == NULL) i_fatal(2,"malloc() error\n");
227   cl->rgba.r = r;
228   cl->rgba.g = g;
229   cl->rgba.b = b;
230   cl->rgba.a = a;
231   mm_log((1,"(%p) <- i_fcolor_new\n",cl));
232
233   return cl;
234 }
235
236 /*
237 =item i_fcolor_destroy(i_fcolor *cl) 
238
239 =cut
240 */
241 void i_fcolor_destroy(i_fcolor *cl) {
242   myfree(cl);
243 }
244
245 /*
246 =item IIM_base_8bit_direct (static)
247
248 A static i_img object used to initialize direct 8-bit per sample images.
249
250 =cut
251 */
252 static i_img IIM_base_8bit_direct =
253 {
254   0, /* channels set */
255   0, 0, 0, /* xsize, ysize, bytes */
256   ~0U, /* ch_mask */
257   i_8_bits, /* bits */
258   i_direct_type, /* type */
259   0, /* virtual */
260   NULL, /* idata */
261   { 0, 0, NULL }, /* tags */
262   NULL, /* ext_data */
263
264   i_ppix_d, /* i_f_ppix */
265   i_ppixf_d, /* i_f_ppixf */
266   i_plin_d, /* i_f_plin */
267   i_plinf_d, /* i_f_plinf */
268   i_gpix_d, /* i_f_gpix */
269   i_gpixf_d, /* i_f_gpixf */
270   i_glin_d, /* i_f_glin */
271   i_glinf_d, /* i_f_glinf */
272   i_gsamp_d, /* i_f_gsamp */
273   i_gsampf_d, /* i_f_gsampf */
274
275   NULL, /* i_f_gpal */
276   NULL, /* i_f_ppal */
277   NULL, /* i_f_addcolors */
278   NULL, /* i_f_getcolors */
279   NULL, /* i_f_colorcount */
280   NULL, /* i_f_maxcolors */
281   NULL, /* i_f_findcolor */
282   NULL, /* i_f_setcolors */
283
284   NULL, /* i_f_destroy */
285
286   i_gsamp_bits_fb,
287   NULL, /* i_f_psamp_bits */
288 };
289
290 /*static void set_8bit_direct(i_img *im) {
291   im->i_f_ppix = i_ppix_d;
292   im->i_f_ppixf = i_ppixf_d;
293   im->i_f_plin = i_plin_d;
294   im->i_f_plinf = i_plinf_d;
295   im->i_f_gpix = i_gpix_d;
296   im->i_f_gpixf = i_gpixf_d;
297   im->i_f_glin = i_glin_d;
298   im->i_f_glinf = i_glinf_d;
299   im->i_f_gpal = NULL;
300   im->i_f_ppal = NULL;
301   im->i_f_addcolor = NULL;
302   im->i_f_getcolor = NULL;
303   im->i_f_colorcount = NULL;
304   im->i_f_findcolor = NULL;
305   }*/
306
307 /*
308 =item IIM_new(x, y, ch)
309
310 =item i_img_8_new(x, y, ch)
311
312 =category Image creation/destruction
313
314 =synopsis i_img *img = i_img_8_new(width, height, channels);
315
316 Creates a new image object I<x> pixels wide, and I<y> pixels high with
317 I<ch> channels.
318
319 =cut
320 */
321
322
323 i_img *
324 IIM_new(int x,int y,int ch) {
325   i_img *im;
326   mm_log((1,"IIM_new(x %d,y %d,ch %d)\n",x,y,ch));
327
328   im=i_img_empty_ch(NULL,x,y,ch);
329   
330   mm_log((1,"(%p) <- IIM_new\n",im));
331   return im;
332 }
333
334
335 void
336 IIM_DESTROY(i_img *im) {
337   mm_log((1,"IIM_DESTROY(im* %p)\n",im));
338   i_img_destroy(im);
339   /*   myfree(cl); */
340 }
341
342 /* 
343 =item i_img_new()
344
345 Create new image reference - notice that this isn't an object yet and
346 this should be fixed asap.
347
348 =cut
349 */
350
351
352 i_img *
353 i_img_new() {
354   i_img *im;
355   
356   mm_log((1,"i_img_struct()\n"));
357
358   im = i_img_alloc();
359   
360   *im = IIM_base_8bit_direct;
361   im->xsize=0;
362   im->ysize=0;
363   im->channels=3;
364   im->ch_mask=MAXINT;
365   im->bytes=0;
366   im->idata=NULL;
367
368   i_img_init(im);
369   
370   mm_log((1,"(%p) <- i_img_struct\n",im));
371   return im;
372 }
373
374 /* 
375 =item i_img_empty(im, x, y)
376
377 Re-new image reference (assumes 3 channels)
378
379    im - Image pointer
380    x - xsize of destination image
381    y - ysize of destination image
382
383 **FIXME** what happens if a live image is passed in here?
384
385 Should this just call i_img_empty_ch()?
386
387 =cut
388 */
389
390 i_img *
391 i_img_empty(i_img *im,int x,int y) {
392   mm_log((1,"i_img_empty(*im %p, x %d, y %d)\n",im, x, y));
393   return i_img_empty_ch(im, x, y, 3);
394 }
395
396 /* 
397 =item i_img_empty_ch(im, x, y, ch)
398
399 Re-new image reference 
400
401    im - Image pointer
402    x  - xsize of destination image
403    y  - ysize of destination image
404    ch - number of channels
405
406 =cut
407 */
408
409 i_img *
410 i_img_empty_ch(i_img *im,int x,int y,int ch) {
411   int bytes;
412
413   mm_log((1,"i_img_empty_ch(*im %p, x %d, y %d, ch %d)\n", im, x, y, ch));
414
415   if (x < 1 || y < 1) {
416     i_push_error(0, "Image sizes must be positive");
417     return NULL;
418   }
419   if (ch < 1 || ch > MAXCHANNELS) {
420     i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
421     return NULL;
422   }
423   /* check this multiplication doesn't overflow */
424   bytes = x*y*ch;
425   if (bytes / y / ch != x) {
426     i_push_errorf(0, "integer overflow calculating image allocation");
427     return NULL;
428   }
429
430   if (im == NULL)
431     im = i_img_alloc();
432
433   memcpy(im, &IIM_base_8bit_direct, sizeof(i_img));
434   i_tags_new(&im->tags);
435   im->xsize    = x;
436   im->ysize    = y;
437   im->channels = ch;
438   im->ch_mask  = MAXINT;
439   im->bytes=bytes;
440   if ( (im->idata=mymalloc(im->bytes)) == NULL) 
441     i_fatal(2,"malloc() error\n"); 
442   memset(im->idata,0,(size_t)im->bytes);
443   
444   im->ext_data = NULL;
445
446   i_img_init(im);
447   
448   mm_log((1,"(%p) <- i_img_empty_ch\n",im));
449   return im;
450 }
451
452 /* 
453 =item i_img_exorcise(im)
454
455 Free image data.
456
457    im - Image pointer
458
459 =cut
460 */
461
462 void
463 i_img_exorcise(i_img *im) {
464   mm_log((1,"i_img_exorcise(im* 0x%x)\n",im));
465   i_tags_destroy(&im->tags);
466   if (im->i_f_destroy)
467     (im->i_f_destroy)(im);
468   if (im->idata != NULL) { myfree(im->idata); }
469   im->idata    = NULL;
470   im->xsize    = 0;
471   im->ysize    = 0;
472   im->channels = 0;
473
474   im->i_f_ppix=i_ppix_d;
475   im->i_f_gpix=i_gpix_d;
476   im->i_f_plin=i_plin_d;
477   im->i_f_glin=i_glin_d;
478   im->ext_data=NULL;
479 }
480
481 /* 
482 =item i_img_destroy(C<img>)
483 =order 90
484 =category Image creation/destruction
485 =synopsis i_img_destroy(img)
486
487 Destroy an image object
488
489 =cut
490 */
491
492 void
493 i_img_destroy(i_img *im) {
494   mm_log((1,"i_img_destroy(im %p)\n",im));
495   i_img_exorcise(im);
496   if (im) { myfree(im); }
497 }
498
499 /* 
500 =item i_img_info(im, info)
501
502 =category Image
503
504 Return image information
505
506    im - Image pointer
507    info - pointer to array to return data
508
509 info is an array of 4 integers with the following values:
510
511  info[0] - width
512  info[1] - height
513  info[2] - channels
514  info[3] - channel mask
515
516 =cut
517 */
518
519
520 void
521 i_img_info(i_img *im,int *info) {
522   mm_log((1,"i_img_info(im 0x%x)\n",im));
523   if (im != NULL) {
524     mm_log((1,"i_img_info: xsize=%d ysize=%d channels=%d mask=%ud\n",im->xsize,im->ysize,im->channels,im->ch_mask));
525     mm_log((1,"i_img_info: idata=0x%d\n",im->idata));
526     info[0] = im->xsize;
527     info[1] = im->ysize;
528     info[2] = im->channels;
529     info[3] = im->ch_mask;
530   } else {
531     info[0] = 0;
532     info[1] = 0;
533     info[2] = 0;
534     info[3] = 0;
535   }
536 }
537
538 /*
539 =item i_img_setmask(C<im>, C<ch_mask>)
540 =category Image Information
541 =synopsis // only channel 0 writeable 
542 =synopsis i_img_setmask(img, 0x01);
543
544 Set the image channel mask for C<im> to C<ch_mask>.
545
546 The image channel mask gives some control over which channels can be
547 written to in the image.
548
549 =cut
550 */
551 void
552 i_img_setmask(i_img *im,int ch_mask) { im->ch_mask=ch_mask; }
553
554
555 /*
556 =item i_img_getmask(C<im>)
557 =category Image Information
558 =synopsis int mask = i_img_getmask(img);
559
560 Get the image channel mask for C<im>.
561
562 =cut
563 */
564 int
565 i_img_getmask(i_img *im) { return im->ch_mask; }
566
567 /*
568 =item i_img_getchannels(C<im>)
569 =category Image Information
570 =synopsis int channels = i_img_getchannels(img);
571
572 Get the number of channels in C<im>.
573
574 =cut
575 */
576 int
577 i_img_getchannels(i_img *im) { return im->channels; }
578
579 /*
580 =item i_img_get_width(C<im>)
581 =category Image Information
582 =synopsis i_img_dim width = i_img_get_width(im);
583
584 Returns the width in pixels of the image.
585
586 =cut
587 */
588 i_img_dim
589 i_img_get_width(i_img *im) {
590   return im->xsize;
591 }
592
593 /*
594 =item i_img_get_height(C<im>)
595 =category Image Information
596 =synopsis i_img_dim height = i_img_get_height(im);
597
598 Returns the height in pixels of the image.
599
600 =cut
601 */
602 i_img_dim
603 i_img_get_height(i_img *im) {
604   return im->ysize;
605 }
606
607 /*
608 =item i_copyto_trans(C<im>, C<src>, C<x1>, C<y1>, C<x2>, C<y2>, C<tx>, C<ty>, C<trans>)
609
610 =category Image
611
612 (C<x1>,C<y1>) (C<x2>,C<y2>) specifies the region to copy (in the
613 source coordinates) (C<tx>,C<ty>) specifies the upper left corner for
614 the target image.  pass NULL in C<trans> for non transparent i_colors.
615
616 =cut
617 */
618
619 void
620 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) {
621   i_color pv;
622   int x,y,t,ttx,tty,tt,ch;
623
624   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",
625           im, src, x1, y1, x2, y2, tx, ty, trans));
626   
627   if (x2<x1) { t=x1; x1=x2; x2=t; }
628   if (y2<y1) { t=y1; y1=y2; y2=t; }
629
630   ttx=tx;
631   for(x=x1;x<x2;x++)
632     {
633       tty=ty;
634       for(y=y1;y<y2;y++)
635         {
636           i_gpix(src,x,y,&pv);
637           if ( trans != NULL)
638           {
639             tt=0;
640             for(ch=0;ch<im->channels;ch++) if (trans->channel[ch]!=pv.channel[ch]) tt++;
641             if (tt) i_ppix(im,ttx,tty,&pv);
642           } else i_ppix(im,ttx,tty,&pv);
643           tty++;
644         }
645       ttx++;
646     }
647 }
648
649 /*
650 =item i_copy(source)
651
652 =category Image
653
654 Creates a new image that is a copy of the image C<source>.
655
656 Tags are not copied, only the image data.
657
658 Returns: i_img *
659
660 =cut
661 */
662
663 i_img *
664 i_copy(i_img *src) {
665   int y, y1, x1;
666   i_img *im = i_sametype(src, src->xsize, src->ysize);
667
668   mm_log((1,"i_copy(src %p)\n", src));
669
670   if (!im)
671     return NULL;
672
673   x1 = src->xsize;
674   y1 = src->ysize;
675   if (src->type == i_direct_type) {
676     if (src->bits == i_8_bits) {
677       i_color *pv;
678       pv = mymalloc(sizeof(i_color) * x1);
679       
680       for (y = 0; y < y1; ++y) {
681         i_glin(src, 0, x1, y, pv);
682         i_plin(im, 0, x1, y, pv);
683       }
684       myfree(pv);
685     }
686     else {
687       i_fcolor *pv;
688
689       pv = mymalloc(sizeof(i_fcolor) * x1);
690       for (y = 0; y < y1; ++y) {
691         i_glinf(src, 0, x1, y, pv);
692         i_plinf(im, 0, x1, y, pv);
693       }
694       myfree(pv);
695     }
696   }
697   else {
698     i_palidx *vals;
699
700     vals = mymalloc(sizeof(i_palidx) * x1);
701     for (y = 0; y < y1; ++y) {
702       i_gpal(src, 0, x1, y, vals);
703       i_ppal(im, 0, x1, y, vals);
704     }
705     myfree(vals);
706   }
707
708   return im;
709 }
710
711
712
713
714
715
716 static
717 float
718 Lanczos(float x) {
719   float PIx, PIx2;
720   
721   PIx = PI * x;
722   PIx2 = PIx / 2.0;
723   
724   if ((x >= 2.0) || (x <= -2.0)) return (0.0);
725   else if (x == 0.0) return (1.0);
726   else return(sin(PIx) / PIx * sin(PIx2) / PIx2);
727 }
728
729
730 /*
731 =item i_scaleaxis(im, value, axis)
732
733 Returns a new image object which is I<im> scaled by I<value> along
734 wither the x-axis (I<axis> == 0) or the y-axis (I<axis> == 1).
735
736 =cut
737 */
738
739 i_img*
740 i_scaleaxis(i_img *im, float Value, int Axis) {
741   int hsize, vsize, i, j, k, l, lMax, iEnd, jEnd;
742   int LanczosWidthFactor;
743   float *l0, *l1, OldLocation;
744   int T; 
745   float t;
746   float F, PictureValue[MAXCHANNELS];
747   short psave;
748   i_color val,val1,val2;
749   i_img *new_img;
750   int has_alpha = i_img_has_alpha(im);
751   int color_chans = i_img_color_channels(im);
752
753   i_clear_error();
754   mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
755
756   if (Axis == XAXIS) {
757     hsize = (int)(0.5 + im->xsize * Value);
758     if (hsize < 1) {
759       hsize = 1;
760       Value = 1.0 / im->xsize;
761     }
762     vsize = im->ysize;
763     
764     jEnd = hsize;
765     iEnd = vsize;
766   } else {
767     hsize = im->xsize;
768     vsize = (int)(0.5 + im->ysize * Value);
769
770     if (vsize < 1) {
771       vsize = 1;
772       Value = 1.0 / im->ysize;
773     }
774
775     jEnd = vsize;
776     iEnd = hsize;
777   }
778   
779   new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
780   if (!new_img) {
781     i_push_error(0, "cannot create output image");
782     return NULL;
783   }
784   
785   /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
786   LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value); 
787   lMax = LanczosWidthFactor << 1;
788   
789   l0 = mymalloc(lMax * sizeof(float));
790   l1 = mymalloc(lMax * sizeof(float));
791   
792   for (j=0; j<jEnd; j++) {
793     OldLocation = ((float) j) / Value;
794     T = (int) (OldLocation);
795     F = OldLocation - (float) T;
796     
797     for (l = 0; l<lMax; l++) {
798       l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
799       l1[l]        = Lanczos(((float) (l+1)      - F) / (float) LanczosWidthFactor);
800     }
801     
802     /* Make sure filter is normalized */
803     t = 0.0;
804     for(l=0; l<lMax; l++) {
805       t+=l0[l];
806       t+=l1[l];
807     }
808     t /= (float)LanczosWidthFactor;
809     
810     for(l=0; l<lMax; l++) {
811       l0[l] /= t;
812       l1[l] /= t;
813     }
814
815     if (Axis == XAXIS) {
816       
817       for (i=0; i<iEnd; i++) {
818         for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
819         for (l=0; l<lMax; l++) {
820           int mx = T-lMax+l+1;
821           int Mx = T+l+1;
822           mx = (mx < 0) ? 0 : mx;
823           Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
824           
825           i_gpix(im, Mx, i, &val1);
826           i_gpix(im, mx, i, &val2);
827
828           if (has_alpha) {
829             i_sample_t alpha1 = val1.channel[color_chans];
830             i_sample_t alpha2 = val2.channel[color_chans];
831             for (k=0; k < color_chans; k++) {
832               PictureValue[k] += l1[l]        * val1.channel[k] * alpha1 / 255;
833               PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
834             }
835             PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
836             PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
837           }
838           else {
839             for (k=0; k<im->channels; k++) {
840               PictureValue[k] += l1[l]        * val1.channel[k];
841               PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
842             }
843           }
844         }
845
846         if (has_alpha) {
847           float fa = PictureValue[color_chans] / LanczosWidthFactor;
848           int alpha = minmax(0, 255, fa+0.5);
849           if (alpha) {
850             for (k = 0; k < color_chans; ++k) {
851               psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
852               val.channel[k]=minmax(0,255,psave);
853             }
854             val.channel[color_chans] = alpha;
855           }
856           else {
857             /* zero alpha, so the pixel has no color */
858             for (k = 0; k < im->channels; ++k)
859               val.channel[k] = 0;
860           }
861         }
862         else {
863           for(k=0;k<im->channels;k++) {
864             psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
865             val.channel[k]=minmax(0,255,psave);
866           }
867         }
868         i_ppix(new_img, j, i, &val);
869       }
870       
871     } else {
872       
873       for (i=0; i<iEnd; i++) {
874         for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
875         for (l=0; l < lMax; l++) {
876           int mx = T-lMax+l+1;
877           int Mx = T+l+1;
878           mx = (mx < 0) ? 0 : mx;
879           Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
880
881           i_gpix(im, i, Mx, &val1);
882           i_gpix(im, i, mx, &val2);
883           if (has_alpha) {
884             i_sample_t alpha1 = val1.channel[color_chans];
885             i_sample_t alpha2 = val2.channel[color_chans];
886             for (k=0; k < color_chans; k++) {
887               PictureValue[k] += l1[l]        * val1.channel[k] * alpha1 / 255;
888               PictureValue[k] += l0[lMax-l-1] * val2.channel[k] * alpha2 / 255;
889             }
890             PictureValue[color_chans] += l1[l] * val1.channel[color_chans];
891             PictureValue[color_chans] += l0[lMax-l-1] * val2.channel[color_chans];
892           }
893           else {
894             for (k=0; k<im->channels; k++) {
895               PictureValue[k] += l1[l]        * val1.channel[k];
896               PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
897             }
898           }
899         }
900         if (has_alpha) {
901           float fa = PictureValue[color_chans] / LanczosWidthFactor;
902           int alpha = minmax(0, 255, fa+0.5);
903           if (alpha) {
904             for (k = 0; k < color_chans; ++k) {
905               psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor * 255 / fa));
906               val.channel[k]=minmax(0,255,psave);
907             }
908             val.channel[color_chans] = alpha;
909           }
910           else {
911             for (k = 0; k < im->channels; ++k)
912               val.channel[k] = 0;
913           }
914         }
915         else {
916           for(k=0;k<im->channels;k++) {
917             psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
918             val.channel[k]=minmax(0,255,psave);
919           }
920         }
921         i_ppix(new_img, i, j, &val);
922       }
923       
924     }
925   }
926   myfree(l0);
927   myfree(l1);
928
929   mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
930
931   return new_img;
932 }
933
934
935 /* 
936 =item i_scale_nn(im, scx, scy)
937
938 Scale by using nearest neighbor 
939 Both axes scaled at the same time since 
940 nothing is gained by doing it in two steps 
941
942 =cut
943 */
944
945
946 i_img*
947 i_scale_nn(i_img *im, float scx, float scy) {
948
949   int nxsize,nysize,nx,ny;
950   i_img *new_img;
951   i_color val;
952
953   mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
954
955   nxsize = (int) ((float) im->xsize * scx);
956   if (nxsize < 1) {
957     nxsize = 1;
958     scx = 1.0 / im->xsize;
959   }
960   nysize = (int) ((float) im->ysize * scy);
961   if (nysize < 1) {
962     nysize = 1;
963     scy = 1.0 / im->ysize;
964   }
965   im_assert(scx != 0 && scy != 0);
966     
967   new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
968   
969   for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
970     i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
971     i_ppix(new_img,nx,ny,&val);
972   }
973
974   mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
975
976   return new_img;
977 }
978
979 /*
980 =item i_sametype(C<im>, C<xsize>, C<ysize>)
981
982 =category Image creation/destruction
983 =synopsis i_img *img = i_sametype(src, width, height);
984
985 Returns an image of the same type (sample size, channels, paletted/direct).
986
987 For paletted images the palette is copied from the source.
988
989 =cut
990 */
991
992 i_img *i_sametype(i_img *src, int xsize, int ysize) {
993   if (src->type == i_direct_type) {
994     if (src->bits == 8) {
995       return i_img_empty_ch(NULL, xsize, ysize, src->channels);
996     }
997     else if (src->bits == i_16_bits) {
998       return i_img_16_new(xsize, ysize, src->channels);
999     }
1000     else if (src->bits == i_double_bits) {
1001       return i_img_double_new(xsize, ysize, src->channels);
1002     }
1003     else {
1004       i_push_error(0, "Unknown image bits");
1005       return NULL;
1006     }
1007   }
1008   else {
1009     i_color col;
1010     int i;
1011
1012     i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
1013     for (i = 0; i < i_colorcount(src); ++i) {
1014       i_getcolors(src, i, &col, 1);
1015       i_addcolors(targ, &col, 1);
1016     }
1017
1018     return targ;
1019   }
1020 }
1021
1022 /*
1023 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
1024
1025 =category Image creation/destruction
1026 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
1027
1028 Returns an image of the same type (sample size).
1029
1030 For paletted images the equivalent direct type is returned.
1031
1032 =cut
1033 */
1034
1035 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
1036   if (src->bits == 8) {
1037     return i_img_empty_ch(NULL, xsize, ysize, channels);
1038   }
1039   else if (src->bits == i_16_bits) {
1040     return i_img_16_new(xsize, ysize, channels);
1041   }
1042   else if (src->bits == i_double_bits) {
1043     return i_img_double_new(xsize, ysize, channels);
1044   }
1045   else {
1046     i_push_error(0, "Unknown image bits");
1047     return NULL;
1048   }
1049 }
1050
1051 /*
1052 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
1053
1054 Spatially transforms I<im> returning a new image.
1055
1056 opx for a length of opxl and opy for a length of opy are arrays of
1057 operators that modify the x and y positions to retreive the pixel data from.
1058
1059 parm and parmlen define extra parameters that the operators may use.
1060
1061 Note that this function is largely superseded by the more flexible
1062 L<transform.c/i_transform2>.
1063
1064 Returns the new image.
1065
1066 The operators for this function are defined in L<stackmach.c>.
1067
1068 =cut
1069 */
1070 i_img*
1071 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1072   double rx,ry;
1073   int nxsize,nysize,nx,ny;
1074   i_img *new_img;
1075   i_color val;
1076   
1077   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));
1078
1079   nxsize = im->xsize;
1080   nysize = im->ysize ;
1081   
1082   new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1083   /*   fprintf(stderr,"parm[2]=%f\n",parm[2]);   */
1084   for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1085     /*     parm[parmlen-2]=(double)nx;
1086            parm[parmlen-1]=(double)ny; */
1087
1088     parm[0]=(double)nx;
1089     parm[1]=(double)ny;
1090
1091     /*     fprintf(stderr,"(%d,%d) ->",nx,ny);  */
1092     rx=i_op_run(opx,opxl,parm,parmlen);
1093     ry=i_op_run(opy,opyl,parm,parmlen);
1094     /*    fprintf(stderr,"(%f,%f)\n",rx,ry); */
1095     i_gpix(im,rx,ry,&val);
1096     i_ppix(new_img,nx,ny,&val);
1097   }
1098
1099   mm_log((1,"(0x%x) <- i_transform\n",new_img));
1100   return new_img;
1101 }
1102
1103 /*
1104 =item i_img_diff(im1, im2)
1105
1106 Calculates the sum of the squares of the differences between
1107 correspoding channels in two images.
1108
1109 If the images are not the same size then only the common area is 
1110 compared, hence even if images are different sizes this function 
1111 can return zero.
1112
1113 =cut
1114 */
1115
1116 float
1117 i_img_diff(i_img *im1,i_img *im2) {
1118   int x,y,ch,xb,yb,chb;
1119   float tdiff;
1120   i_color val1,val2;
1121
1122   mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1123
1124   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1125   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1126   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1127
1128   mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1129
1130   tdiff=0;
1131   for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1132     i_gpix(im1,x,y,&val1);
1133     i_gpix(im2,x,y,&val2);
1134
1135     for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1136   }
1137   mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1138   return tdiff;
1139 }
1140
1141 /*
1142 =item i_img_diffd(im1, im2)
1143
1144 Calculates the sum of the squares of the differences between
1145 correspoding channels in two images.
1146
1147 If the images are not the same size then only the common area is 
1148 compared, hence even if images are different sizes this function 
1149 can return zero.
1150
1151 This is like i_img_diff() but looks at floating point samples instead.
1152
1153 =cut
1154 */
1155
1156 double
1157 i_img_diffd(i_img *im1,i_img *im2) {
1158   int x,y,ch,xb,yb,chb;
1159   double tdiff;
1160   i_fcolor val1,val2;
1161
1162   mm_log((1,"i_img_diffd(im1 0x%x,im2 0x%x)\n",im1,im2));
1163
1164   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1165   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1166   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1167
1168   mm_log((1,"i_img_diffd: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1169
1170   tdiff=0;
1171   for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1172     i_gpixf(im1,x,y,&val1);
1173     i_gpixf(im2,x,y,&val2);
1174
1175     for(ch=0;ch<chb;ch++) {
1176       double sdiff = val1.channel[ch]-val2.channel[ch];
1177       tdiff += sdiff * sdiff;
1178     }
1179   }
1180   mm_log((1,"i_img_diffd <- (%.2f)\n",tdiff));
1181
1182   return tdiff;
1183 }
1184
1185 int
1186 i_img_samef(i_img *im1,i_img *im2, double epsilon, char const *what) {
1187   int x,y,ch,xb,yb,chb;
1188   i_fcolor val1,val2;
1189
1190   if (what == NULL)
1191     what = "(null)";
1192
1193   mm_log((1,"i_img_samef(im1 0x%x,im2 0x%x, epsilon %g, what '%s')\n", im1, im2, epsilon, what));
1194
1195   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1196   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1197   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1198
1199   mm_log((1,"i_img_samef: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1200
1201   for(y = 0; y < yb; y++) {
1202     for(x = 0; x < xb; x++) {
1203       i_gpixf(im1, x, y, &val1);
1204       i_gpixf(im2, x, y, &val2);
1205       
1206       for(ch = 0; ch < chb; ch++) {
1207         double sdiff = val1.channel[ch] - val2.channel[ch];
1208         if (fabs(sdiff) > epsilon) {
1209           mm_log((1,"i_img_samef <- different %g @(%d,%d)\n", sdiff, x, y));
1210           return 0;
1211         }
1212       }
1213     }
1214   }
1215   mm_log((1,"i_img_samef <- same\n"));
1216
1217   return 1;
1218 }
1219
1220 /* just a tiny demo of haar wavelets */
1221
1222 i_img*
1223 i_haar(i_img *im) {
1224   int mx,my;
1225   int fx,fy;
1226   int x,y;
1227   int ch,c;
1228   i_img *new_img,*new_img2;
1229   i_color val1,val2,dval1,dval2;
1230   
1231   mx=im->xsize;
1232   my=im->ysize;
1233   fx=(mx+1)/2;
1234   fy=(my+1)/2;
1235
1236
1237   /* horizontal pass */
1238   
1239   new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1240   new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1241
1242   c=0; 
1243   for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1244     i_gpix(im,x*2,y,&val1);
1245     i_gpix(im,x*2+1,y,&val2);
1246     for(ch=0;ch<im->channels;ch++) {
1247       dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1248       dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1249     }
1250     i_ppix(new_img,x,y,&dval1);
1251     i_ppix(new_img,x+fx,y,&dval2);
1252   }
1253
1254   for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1255     i_gpix(new_img,x,y*2,&val1);
1256     i_gpix(new_img,x,y*2+1,&val2);
1257     for(ch=0;ch<im->channels;ch++) {
1258       dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1259       dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1260     }
1261     i_ppix(new_img2,x,y,&dval1);
1262     i_ppix(new_img2,x,y+fy,&dval2);
1263   }
1264
1265   i_img_destroy(new_img);
1266   return new_img2;
1267 }
1268
1269 /* 
1270 =item i_count_colors(im, maxc)
1271
1272 returns number of colors or -1 
1273 to indicate that it was more than max colors
1274
1275 =cut
1276 */
1277 /* This function has been changed and is now faster. It's using
1278  * i_gsamp instead of i_gpix */
1279 int
1280 i_count_colors(i_img *im,int maxc) {
1281   struct octt *ct;
1282   int x,y;
1283   int colorcnt;
1284   int channels[3];
1285   int *samp_chans;
1286   i_sample_t * samp;
1287   int xsize = im->xsize; 
1288   int ysize = im->ysize;
1289   int samp_cnt = 3 * xsize;
1290
1291   if (im->channels >= 3) {
1292     samp_chans = NULL;
1293   }
1294   else {
1295     channels[0] = channels[1] = channels[2] = 0;
1296     samp_chans = channels;
1297   }
1298
1299   ct = octt_new();
1300
1301   samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1302
1303   colorcnt = 0;
1304   for(y = 0; y < ysize; ) {
1305       i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1306       for(x = 0; x < samp_cnt; ) {
1307           colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1308           x += 3;
1309           if (colorcnt > maxc) { 
1310               octt_delete(ct); 
1311               return -1; 
1312           }
1313       }
1314   }
1315   myfree(samp);
1316   octt_delete(ct);
1317   return colorcnt;
1318 }
1319
1320 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm 
1321  * (adapted from the Numerical Recipes)
1322  */
1323 /* Needed by get_anonymous_color_histo */
1324 static void
1325 hpsort(unsigned int n, unsigned *ra) {
1326     unsigned int i,
1327                  ir,
1328                  j,
1329                  l, 
1330                  rra;
1331
1332     if (n < 2) return;
1333     l = n >> 1;
1334     ir = n - 1;
1335     for(;;) {
1336         if (l > 0) {
1337             rra = ra[--l];
1338         }
1339         else {
1340             rra = ra[ir];
1341             ra[ir] = ra[0];
1342             if (--ir == 0) {
1343                 ra[0] = rra;
1344                 break;
1345             }
1346         }
1347         i = l;
1348         j = 2 * l + 1;
1349         while (j <= ir) {
1350             if (j < ir && ra[j] < ra[j+1]) j++;
1351             if (rra < ra[j]) {
1352                 ra[i] = ra[j];
1353                 i = j;
1354                 j++; j <<= 1; j--;
1355             }
1356             else break;
1357         }
1358         ra[i] = rra;
1359     }
1360 }
1361
1362 /* This function constructs an ordered list which represents how much the
1363  * different colors are used. So for instance (100, 100, 500) means that one
1364  * color is used for 500 pixels, another for 100 pixels and another for 100
1365  * pixels. It's tuned for performance. You might not like the way I've hardcoded
1366  * the maxc ;-) and you might want to change the name... */
1367 /* Uses octt_histo */
1368 int
1369 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1370   struct octt *ct;
1371   int x,y;
1372   int colorcnt;
1373   unsigned int *col_usage_it;
1374   i_sample_t * samp;
1375   int channels[3];
1376   int *samp_chans;
1377   
1378   int xsize = im->xsize; 
1379   int ysize = im->ysize;
1380   int samp_cnt = 3 * xsize;
1381   ct = octt_new();
1382   
1383   samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1384   
1385   if (im->channels >= 3) {
1386     samp_chans = NULL;
1387   }
1388   else {
1389     channels[0] = channels[1] = channels[2] = 0;
1390     samp_chans = channels;
1391   }
1392
1393   colorcnt = 0;
1394   for(y = 0; y < ysize; ) {
1395     i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1396     for(x = 0; x < samp_cnt; ) {
1397       colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1398       x += 3;
1399       if (colorcnt > maxc) { 
1400         octt_delete(ct); 
1401         return -1; 
1402       }
1403     }
1404   }
1405   myfree(samp);
1406   /* Now that we know the number of colours... */
1407   col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1408   octt_histo(ct, &col_usage_it);
1409   hpsort(colorcnt, *col_usage);
1410   octt_delete(ct);
1411   return colorcnt;
1412 }
1413
1414 /*
1415 =back
1416
1417 =head2 8-bit per sample image internal functions
1418
1419 These are the functions installed in an 8-bit per sample image.
1420
1421 =over
1422
1423 =item i_ppix_d(im, x, y, col)
1424
1425 Internal function.
1426
1427 This is the function kept in the i_f_ppix member of an i_img object.
1428 It does a normal store of a pixel into the image with range checking.
1429
1430 Returns 0 if the pixel could be set, -1 otherwise.
1431
1432 =cut
1433 */
1434 static
1435 int
1436 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1437   int ch;
1438   
1439   if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1440     for(ch=0;ch<im->channels;ch++)
1441       if (im->ch_mask&(1<<ch)) 
1442         im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1443     return 0;
1444   }
1445   return -1; /* error was clipped */
1446 }
1447
1448 /*
1449 =item i_gpix_d(im, x, y, &col)
1450
1451 Internal function.
1452
1453 This is the function kept in the i_f_gpix member of an i_img object.
1454 It does normal retrieval of a pixel from the image with range checking.
1455
1456 Returns 0 if the pixel could be set, -1 otherwise.
1457
1458 =cut
1459 */
1460 static
1461 int 
1462 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1463   int ch;
1464   if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1465     for(ch=0;ch<im->channels;ch++) 
1466       val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1467     return 0;
1468   }
1469   for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1470   return -1; /* error was cliped */
1471 }
1472
1473 /*
1474 =item i_glin_d(im, l, r, y, vals)
1475
1476 Reads a line of data from the image, storing the pixels at vals.
1477
1478 The line runs from (l,y) inclusive to (r,y) non-inclusive
1479
1480 vals should point at space for (r-l) pixels.
1481
1482 l should never be less than zero (to avoid confusion about where to
1483 put the pixels in vals).
1484
1485 Returns the number of pixels copied (eg. if r, l or y is out of range)
1486
1487 =cut
1488 */
1489 static
1490 int
1491 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1492   int ch, count, i;
1493   unsigned char *data;
1494   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1495     if (r > im->xsize)
1496       r = im->xsize;
1497     data = im->idata + (l+y*im->xsize) * im->channels;
1498     count = r - l;
1499     for (i = 0; i < count; ++i) {
1500       for (ch = 0; ch < im->channels; ++ch)
1501         vals[i].channel[ch] = *data++;
1502     }
1503     return count;
1504   }
1505   else {
1506     return 0;
1507   }
1508 }
1509
1510 /*
1511 =item i_plin_d(im, l, r, y, vals)
1512
1513 Writes a line of data into the image, using the pixels at vals.
1514
1515 The line runs from (l,y) inclusive to (r,y) non-inclusive
1516
1517 vals should point at (r-l) pixels.
1518
1519 l should never be less than zero (to avoid confusion about where to
1520 get the pixels in vals).
1521
1522 Returns the number of pixels copied (eg. if r, l or y is out of range)
1523
1524 =cut
1525 */
1526 static
1527 int
1528 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1529   int ch, count, i;
1530   unsigned char *data;
1531   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1532     if (r > im->xsize)
1533       r = im->xsize;
1534     data = im->idata + (l+y*im->xsize) * im->channels;
1535     count = r - l;
1536     for (i = 0; i < count; ++i) {
1537       for (ch = 0; ch < im->channels; ++ch) {
1538         if (im->ch_mask & (1 << ch)) 
1539           *data = vals[i].channel[ch];
1540         ++data;
1541       }
1542     }
1543     return count;
1544   }
1545   else {
1546     return 0;
1547   }
1548 }
1549
1550 /*
1551 =item i_ppixf_d(im, x, y, val)
1552
1553 =cut
1554 */
1555 static
1556 int
1557 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1558   int ch;
1559   
1560   if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1561     for(ch=0;ch<im->channels;ch++)
1562       if (im->ch_mask&(1<<ch)) {
1563         im->idata[(x+y*im->xsize)*im->channels+ch] = 
1564           SampleFTo8(val->channel[ch]);
1565       }
1566     return 0;
1567   }
1568   return -1; /* error was clipped */
1569 }
1570
1571 /*
1572 =item i_gpixf_d(im, x, y, val)
1573
1574 =cut
1575 */
1576 static
1577 int
1578 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1579   int ch;
1580   if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1581     for(ch=0;ch<im->channels;ch++) {
1582       val->channel[ch] = 
1583         Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1584     }
1585     return 0;
1586   }
1587   return -1; /* error was cliped */
1588 }
1589
1590 /*
1591 =item i_glinf_d(im, l, r, y, vals)
1592
1593 Reads a line of data from the image, storing the pixels at vals.
1594
1595 The line runs from (l,y) inclusive to (r,y) non-inclusive
1596
1597 vals should point at space for (r-l) pixels.
1598
1599 l should never be less than zero (to avoid confusion about where to
1600 put the pixels in vals).
1601
1602 Returns the number of pixels copied (eg. if r, l or y is out of range)
1603
1604 =cut
1605 */
1606 static
1607 int
1608 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1609   int ch, count, i;
1610   unsigned char *data;
1611   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1612     if (r > im->xsize)
1613       r = im->xsize;
1614     data = im->idata + (l+y*im->xsize) * im->channels;
1615     count = r - l;
1616     for (i = 0; i < count; ++i) {
1617       for (ch = 0; ch < im->channels; ++ch)
1618         vals[i].channel[ch] = Sample8ToF(*data++);
1619     }
1620     return count;
1621   }
1622   else {
1623     return 0;
1624   }
1625 }
1626
1627 /*
1628 =item i_plinf_d(im, l, r, y, vals)
1629
1630 Writes a line of data into the image, using the pixels at vals.
1631
1632 The line runs from (l,y) inclusive to (r,y) non-inclusive
1633
1634 vals should point at (r-l) pixels.
1635
1636 l should never be less than zero (to avoid confusion about where to
1637 get the pixels in vals).
1638
1639 Returns the number of pixels copied (eg. if r, l or y is out of range)
1640
1641 =cut
1642 */
1643 static
1644 int
1645 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1646   int ch, count, i;
1647   unsigned char *data;
1648   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1649     if (r > im->xsize)
1650       r = im->xsize;
1651     data = im->idata + (l+y*im->xsize) * im->channels;
1652     count = r - l;
1653     for (i = 0; i < count; ++i) {
1654       for (ch = 0; ch < im->channels; ++ch) {
1655         if (im->ch_mask & (1 << ch)) 
1656           *data = SampleFTo8(vals[i].channel[ch]);
1657         ++data;
1658       }
1659     }
1660     return count;
1661   }
1662   else {
1663     return 0;
1664   }
1665 }
1666
1667 /*
1668 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1669
1670 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1671 for the channels specified by chans, an array of int with chan_count
1672 elements.
1673
1674 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1675
1676 =cut
1677 */
1678 static
1679 int
1680 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, 
1681               const int *chans, int chan_count) {
1682   int ch, count, i, w;
1683   unsigned char *data;
1684
1685   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1686     if (r > im->xsize)
1687       r = im->xsize;
1688     data = im->idata + (l+y*im->xsize) * im->channels;
1689     w = r - l;
1690     count = 0;
1691
1692     if (chans) {
1693       /* make sure we have good channel numbers */
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]);
1697           return 0;
1698         }
1699       }
1700       for (i = 0; i < w; ++i) {
1701         for (ch = 0; ch < chan_count; ++ch) {
1702           *samps++ = data[chans[ch]];
1703           ++count;
1704         }
1705         data += im->channels;
1706       }
1707     }
1708     else {
1709       if (chan_count <= 0 || chan_count > im->channels) {
1710         i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", 
1711                       chan_count);
1712         return 0;
1713       }
1714       for (i = 0; i < w; ++i) {
1715         for (ch = 0; ch < chan_count; ++ch) {
1716           *samps++ = data[ch];
1717           ++count;
1718         }
1719         data += im->channels;
1720       }
1721     }
1722
1723     return count;
1724   }
1725   else {
1726     return 0;
1727   }
1728 }
1729
1730 /*
1731 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1732
1733 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1734 for the channels specified by chan_mask, where bit 0 is the first
1735 channel.
1736
1737 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1738
1739 =cut
1740 */
1741 static
1742 int
1743 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, 
1744            const int *chans, int chan_count) {
1745   int ch, count, i, w;
1746   unsigned char *data;
1747   for (ch = 0; ch < chan_count; ++ch) {
1748     if (chans[ch] < 0 || chans[ch] >= im->channels) {
1749       i_push_errorf(0, "No channel %d in this image", chans[ch]);
1750     }
1751   }
1752   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1753     if (r > im->xsize)
1754       r = im->xsize;
1755     data = im->idata + (l+y*im->xsize) * im->channels;
1756     w = r - l;
1757     count = 0;
1758
1759     if (chans) {
1760       /* make sure we have good channel numbers */
1761       for (ch = 0; ch < chan_count; ++ch) {
1762         if (chans[ch] < 0 || chans[ch] >= im->channels) {
1763           i_push_errorf(0, "No channel %d in this image", chans[ch]);
1764           return 0;
1765         }
1766       }
1767       for (i = 0; i < w; ++i) {
1768         for (ch = 0; ch < chan_count; ++ch) {
1769           *samps++ = Sample8ToF(data[chans[ch]]);
1770           ++count;
1771         }
1772         data += im->channels;
1773       }
1774     }
1775     else {
1776       if (chan_count <= 0 || chan_count > im->channels) {
1777         i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", 
1778                       chan_count);
1779         return 0;
1780       }
1781       for (i = 0; i < w; ++i) {
1782         for (ch = 0; ch < chan_count; ++ch) {
1783           *samps++ = Sample8ToF(data[ch]);
1784           ++count;
1785         }
1786         data += im->channels;
1787       }
1788     }
1789     return count;
1790   }
1791   else {
1792     return 0;
1793   }
1794 }
1795
1796 /*
1797 =back
1798
1799 =head2 Image method wrappers
1800
1801 These functions provide i_fsample_t functions in terms of their
1802 i_sample_t versions.
1803
1804 =over
1805
1806 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1807
1808 =cut
1809 */
1810
1811 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1812   i_color temp;
1813   int ch;
1814
1815   for (ch = 0; ch < im->channels; ++ch)
1816     temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1817   
1818   return i_ppix(im, x, y, &temp);
1819 }
1820
1821 /*
1822 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1823
1824 =cut
1825 */
1826 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1827   i_color temp;
1828   int ch;
1829
1830   if (i_gpix(im, x, y, &temp)) {
1831     for (ch = 0; ch < im->channels; ++ch)
1832       pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1833     return 0;
1834   }
1835   else 
1836     return -1;
1837 }
1838
1839 /*
1840 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1841
1842 =cut
1843 */
1844 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1845   i_color *work;
1846
1847   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1848     if (r > im->xsize)
1849       r = im->xsize;
1850     if (r > l) {
1851       int ret;
1852       int i, ch;
1853       work = mymalloc(sizeof(i_color) * (r-l));
1854       for (i = 0; i < r-l; ++i) {
1855         for (ch = 0; ch < im->channels; ++ch) 
1856           work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1857       }
1858       ret = i_plin(im, l, r, y, work);
1859       myfree(work);
1860
1861       return ret;
1862     }
1863     else {
1864       return 0;
1865     }
1866   }
1867   else {
1868     return 0;
1869   }
1870 }
1871
1872 /*
1873 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1874
1875 =cut
1876 */
1877 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1878   i_color *work;
1879
1880   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1881     if (r > im->xsize)
1882       r = im->xsize;
1883     if (r > l) {
1884       int ret;
1885       int i, ch;
1886       work = mymalloc(sizeof(i_color) * (r-l));
1887       ret = i_plin(im, l, r, y, work);
1888       for (i = 0; i < r-l; ++i) {
1889         for (ch = 0; ch < im->channels; ++ch) 
1890           pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1891       }
1892       myfree(work);
1893
1894       return ret;
1895     }
1896     else {
1897       return 0;
1898     }
1899   }
1900   else {
1901     return 0;
1902   }
1903 }
1904
1905 /*
1906 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1907
1908 =cut
1909 */
1910 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, 
1911                 int const *chans, int chan_count) {
1912   i_sample_t *work;
1913
1914   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1915     if (r > im->xsize)
1916       r = im->xsize;
1917     if (r > l) {
1918       int ret;
1919       int i;
1920       work = mymalloc(sizeof(i_sample_t) * (r-l));
1921       ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1922       for (i = 0; i < ret; ++i) {
1923           samp[i] = Sample8ToF(work[i]);
1924       }
1925       myfree(work);
1926
1927       return ret;
1928     }
1929     else {
1930       return 0;
1931     }
1932   }
1933   else {
1934     return 0;
1935   }
1936 }
1937
1938 /*
1939 =back
1940
1941 =head2 Palette wrapper functions
1942
1943 Used for virtual images, these forward palette calls to a wrapped image, 
1944 assuming the wrapped image is the first pointer in the structure that 
1945 im->ext_data points at.
1946
1947 =over
1948
1949 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1950
1951 =cut
1952 */
1953 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1954   return i_addcolors(*(i_img **)im->ext_data, colors, count);
1955 }
1956
1957 /*
1958 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1959
1960 =cut
1961 */
1962 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1963   return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1964 }
1965
1966 /*
1967 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1968
1969 =cut
1970 */
1971 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1972   return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1973 }
1974
1975 /*
1976 =item i_colorcount_forward(i_img *im)
1977
1978 =cut
1979 */
1980 int i_colorcount_forward(i_img *im) {
1981   return i_colorcount(*(i_img **)im->ext_data);
1982 }
1983
1984 /*
1985 =item i_maxcolors_forward(i_img *im)
1986
1987 =cut
1988 */
1989 int i_maxcolors_forward(i_img *im) {
1990   return i_maxcolors(*(i_img **)im->ext_data);
1991 }
1992
1993 /*
1994 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1995
1996 =cut
1997 */
1998 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1999   return i_findcolor(*(i_img **)im->ext_data, color, entry);
2000 }
2001
2002 /*
2003 =back
2004
2005 =head2 Fallback handler
2006
2007 =over
2008
2009 =item i_gsamp_bits_fb
2010
2011 =cut
2012 */
2013
2014 int 
2015 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps, 
2016                 const int *chans, int chan_count, int bits) {
2017   if (bits < 1 || bits > 32) {
2018     i_push_error(0, "Invalid bits, must be 1..32");
2019     return -1;
2020   }
2021
2022   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
2023     double scale;
2024     int ch, count, i, w;
2025     
2026     if (bits == 32)
2027       scale = 4294967295.0;
2028     else
2029       scale = (double)(1 << bits) - 1;
2030
2031     if (r > im->xsize)
2032       r = im->xsize;
2033     w = r - l;
2034     count = 0;
2035
2036     if (chans) {
2037       /* make sure we have good channel numbers */
2038       for (ch = 0; ch < chan_count; ++ch) {
2039         if (chans[ch] < 0 || chans[ch] >= im->channels) {
2040           i_push_errorf(0, "No channel %d in this image", chans[ch]);
2041           return -1;
2042         }
2043       }
2044       for (i = 0; i < w; ++i) {
2045         i_fcolor c;
2046         i_gpixf(im, l+i, y, &c);
2047         for (ch = 0; ch < chan_count; ++ch) {
2048           *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2049           ++count;
2050         }
2051       }
2052     }
2053     else {
2054       if (chan_count <= 0 || chan_count > im->channels) {
2055         i_push_error(0, "Invalid channel count");
2056         return -1;
2057       }
2058       for (i = 0; i < w; ++i) {
2059         i_fcolor c;
2060         i_gpixf(im, l+i, y, &c);
2061         for (ch = 0; ch < chan_count; ++ch) {
2062           *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
2063           ++count;
2064         }
2065       }
2066     }
2067
2068     return count;
2069   }
2070   else {
2071     i_push_error(0, "Image position outside of image");
2072     return -1;
2073   }
2074 }
2075
2076 /*
2077 =back
2078
2079 =head2 Stream reading and writing wrapper functions
2080
2081 =over
2082
2083 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
2084
2085 Performs general read buffering for file readers that permit reading
2086 to be done through a callback.
2087
2088 The final callback gets two parameters, a I<need> value, and a I<want>
2089 value, where I<need> is the amount of data that the file library needs
2090 to read, and I<want> is the amount of space available in the buffer
2091 maintained by these functions.
2092
2093 This means if you need to read from a stream that you don't know the
2094 length of, you can return I<need> bytes, taking the performance hit of
2095 possibly expensive callbacks (eg. back to perl code), or if you are
2096 reading from a stream where it doesn't matter if some data is lost, or
2097 if the total length of the stream is known, you can return I<want>
2098 bytes.
2099
2100 =cut 
2101 */
2102
2103 int
2104 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2105   int total;
2106
2107   if (length < gci->length - gci->cpos) {
2108     /* simplest case */
2109     memcpy(buf, gci->buffer+gci->cpos, length);
2110     gci->cpos += length;
2111     return length;
2112   }
2113   
2114   total = 0;
2115   memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2116   total  += gci->length - gci->cpos;
2117   length -= gci->length - gci->cpos;
2118   buf    += gci->length - gci->cpos;
2119   if (length < (int)sizeof(gci->buffer)) {
2120     int did_read;
2121     int copy_size;
2122     while (length
2123            && (did_read = (gci->cb)(gci->userdata, gci->buffer, length, 
2124                                     sizeof(gci->buffer))) > 0) {
2125       gci->cpos = 0;
2126       gci->length = did_read;
2127
2128       copy_size = i_min(length, gci->length);
2129       memcpy(buf, gci->buffer, copy_size);
2130       gci->cpos += copy_size;
2131       buf += copy_size;
2132       total += copy_size;
2133       length -= copy_size;
2134     }
2135   }
2136   else {
2137     /* just read the rest - too big for our buffer*/
2138     int did_read;
2139     while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2140       length -= did_read;
2141       total += did_read;
2142       buf += did_read;
2143     }
2144   }
2145   return total;
2146 }
2147
2148 /*
2149 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2150
2151 For use by callback file readers to initialize the reader buffer.
2152
2153 Allocates, initializes and returns the reader buffer.
2154
2155 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2156
2157 =cut
2158 */
2159 i_gen_read_data *
2160 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2161   i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2162   self->cb = cb;
2163   self->userdata = userdata;
2164   self->length = 0;
2165   self->cpos = 0;
2166
2167   return self;
2168 }
2169
2170 /*
2171 =item i_free_gen_read_data(i_gen_read_data *)
2172
2173 Cleans up.
2174
2175 =cut
2176 */
2177 void i_free_gen_read_data(i_gen_read_data *self) {
2178   myfree(self);
2179 }
2180
2181 /*
2182 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2183
2184 Performs write buffering for a callback based file writer.
2185
2186 Failures are considered fatal, if a write fails then data will be
2187 dropped.
2188
2189 =cut
2190 */
2191 int 
2192 i_gen_writer(
2193 i_gen_write_data *self, 
2194 char const *data, 
2195 int size)
2196 {
2197   if (self->filledto && self->filledto+size > self->maxlength) {
2198     if (self->cb(self->userdata, self->buffer, self->filledto)) {
2199       self->filledto = 0;
2200     }
2201     else {
2202       self->filledto = 0;
2203       return 0;
2204     }
2205   }
2206   if (self->filledto+size <= self->maxlength) {
2207     /* just save it */
2208     memcpy(self->buffer+self->filledto, data, size);
2209     self->filledto += size;
2210     return 1;
2211   }
2212   /* doesn't fit - hand it off */
2213   return self->cb(self->userdata, data, size);
2214 }
2215
2216 /*
2217 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2218
2219 Allocates and initializes the data structure used by i_gen_writer.
2220
2221 This should be released with L<image.c/i_free_gen_write_data>
2222
2223 =cut
2224 */
2225 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb, 
2226                                        char *userdata, int max_length)
2227 {
2228   i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2229   self->cb = cb;
2230   self->userdata = userdata;
2231   self->maxlength = i_min(max_length, sizeof(self->buffer));
2232   if (self->maxlength < 0)
2233     self->maxlength = sizeof(self->buffer);
2234   self->filledto = 0;
2235
2236   return self;
2237 }
2238
2239 /*
2240 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2241
2242 Cleans up the write buffer.
2243
2244 Will flush any left-over data if I<flush> is non-zero.
2245
2246 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2247
2248 Return zero only if flush is non-zero and info->cb() returns zero.
2249 ie. if it fails.
2250
2251 =cut
2252 */
2253
2254 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2255 {
2256   int result = !flush || 
2257     info->filledto == 0 ||
2258     info->cb(info->userdata, info->buffer, info->filledto);
2259   myfree(info);
2260
2261   return result;
2262 }
2263
2264 struct magic_entry {
2265   unsigned char *magic;
2266   size_t magic_size;
2267   char *name;
2268   unsigned char *mask;  
2269 };
2270
2271 static int
2272 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2273   if (length < magic->magic_size)
2274     return 0;
2275   if (magic->mask) {
2276     int i;
2277     unsigned char *bufp = buffer, 
2278       *maskp = magic->mask, 
2279       *magicp = magic->magic;
2280
2281     for (i = 0; i < magic->magic_size; ++i) {
2282       int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2283       ++maskp;
2284
2285       if ((*bufp++ & mask) != (*magicp++ & mask)) 
2286         return 0;
2287     }
2288
2289     return 1;
2290   }
2291   else {
2292     return !memcmp(magic->magic, buffer, magic->magic_size);
2293   }
2294 }
2295
2296 /*
2297 =item i_test_format_probe(io_glue *data, int length)
2298
2299 Check the beginning of the supplied file for a 'magic number'
2300
2301 =cut
2302 */
2303
2304 #define FORMAT_ENTRY(magic, type) \
2305   { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2306 #define FORMAT_ENTRY2(magic, type, mask) \
2307   { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2308
2309 const char *
2310 i_test_format_probe(io_glue *data, int length) {
2311   static const struct magic_entry formats[] = {
2312     FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2313     FORMAT_ENTRY("GIF87a", "gif"),
2314     FORMAT_ENTRY("GIF89a", "gif"),
2315     FORMAT_ENTRY("MM\0*", "tiff"),
2316     FORMAT_ENTRY("II*\0", "tiff"),
2317     FORMAT_ENTRY("BM", "bmp"),
2318     FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2319     FORMAT_ENTRY("P1", "pnm"),
2320     FORMAT_ENTRY("P2", "pnm"),
2321     FORMAT_ENTRY("P3", "pnm"),
2322     FORMAT_ENTRY("P4", "pnm"),
2323     FORMAT_ENTRY("P5", "pnm"),
2324     FORMAT_ENTRY("P6", "pnm"),
2325     FORMAT_ENTRY("/* XPM", "xpm"),
2326     FORMAT_ENTRY("\x8aMNG", "mng"),
2327     FORMAT_ENTRY("\x8aJNG", "jng"),
2328     /* SGI RGB - with various possible parameters to avoid false positives
2329        on similar files 
2330        values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2331     */
2332     FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2333     FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2334     FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2335     FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2336     
2337     FORMAT_ENTRY2("FORM    ILBM", "ilbm", "xxxx    xxxx"),
2338
2339     /* different versions of PCX format 
2340        http://www.fileformat.info/format/pcx/
2341     */
2342     FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2343     FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2344     FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2345     FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2346     FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2347
2348     /* FITS - http://fits.gsfc.nasa.gov/ */
2349     FORMAT_ENTRY("SIMPLE  =", "fits"),
2350
2351     /* PSD - Photoshop */
2352     FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2353     
2354     /* EPS - Encapsulated Postscript */
2355     /* only reading 18 chars, so we don't include the F in EPSF */
2356     FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2357
2358     /* Utah RLE */
2359     FORMAT_ENTRY("\x52\xCC", "utah"),
2360
2361     /* GZIP compressed, only matching deflate for now */
2362     FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2363
2364     /* bzip2 compressed */
2365     FORMAT_ENTRY("BZh", "bzip2"),
2366
2367     /* WEBP
2368        http://code.google.com/speed/webp/docs/riff_container.html */
2369     FORMAT_ENTRY2("RIFF    WEBP", "webp", "xxxx    xxxx"),
2370
2371     /* JPEG 2000 
2372        This might match a little loosely */
2373     FORMAT_ENTRY("\x00\x00\x00\x0CjP  \x0D\x0A\x87\x0A", "jp2"),
2374   };
2375   static const struct magic_entry more_formats[] = {
2376     /* these were originally both listed as ico, but cur files can
2377        include hotspot information */
2378     FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2379     FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2380     FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07", 
2381                   "xwd", "    xxxx"), /* X Windows Dump */
2382   };
2383
2384   unsigned int i;
2385   unsigned char head[18];
2386   ssize_t rc;
2387
2388   io_glue_commit_types(data);
2389   rc = data->readcb(data, head, 18);
2390   if (rc == -1) return NULL;
2391   data->seekcb(data, -rc, SEEK_CUR);
2392
2393   for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) { 
2394     struct magic_entry const *entry = formats + i;
2395
2396     if (test_magic(head, rc, entry)) 
2397       return entry->name;
2398   }
2399
2400   if ((rc == 18) &&
2401       tga_header_verify(head))
2402     return "tga";
2403
2404   for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) { 
2405     struct magic_entry const *entry = more_formats + i;
2406
2407     if (test_magic(head, rc, entry)) 
2408       return entry->name;
2409   }
2410
2411   return NULL;
2412 }
2413
2414 /*
2415 =item i_img_is_monochrome(img, &zero_is_white)
2416
2417 =category Image Information
2418
2419 Tests an image to check it meets our monochrome tests.
2420
2421 The idea is that a file writer can use this to test where it should
2422 write the image in whatever bi-level format it uses, eg. C<pbm> for
2423 C<pnm>.
2424
2425 For performance of encoders we require monochrome images:
2426
2427 =over
2428
2429 =item *
2430
2431 be paletted
2432
2433 =item *
2434
2435 have a palette of two colors, containing only C<(0,0,0)> and
2436 C<(255,255,255)> in either order.
2437
2438 =back
2439
2440 C<zero_is_white> is set to non-zero if the first palette entry is white.
2441
2442 =cut
2443 */
2444
2445 int
2446 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2447   if (im->type == i_palette_type
2448       && i_colorcount(im) == 2) {
2449     i_color colors[2];
2450     i_getcolors(im, 0, colors, 2);
2451     if (im->channels == 3) {
2452       if (colors[0].rgb.r == 255 && 
2453           colors[0].rgb.g == 255 &&
2454           colors[0].rgb.b == 255 &&
2455           colors[1].rgb.r == 0 &&
2456           colors[1].rgb.g == 0 &&
2457           colors[1].rgb.b == 0) {
2458         *zero_is_white = 1;
2459         return 1;
2460       }
2461       else if (colors[0].rgb.r == 0 && 
2462                colors[0].rgb.g == 0 &&
2463                colors[0].rgb.b == 0 &&
2464                colors[1].rgb.r == 255 &&
2465                colors[1].rgb.g == 255 &&
2466                colors[1].rgb.b == 255) {
2467         *zero_is_white = 0;
2468         return 1;
2469       }
2470     }
2471     else if (im->channels == 1) {
2472       if (colors[0].channel[0] == 255 &&
2473           colors[1].channel[0] == 0) {
2474         *zero_is_white = 1;
2475         return 1;
2476       }
2477       else if (colors[0].channel[0] == 0 &&
2478                colors[1].channel[0] == 255) {
2479         *zero_is_white = 0;
2480         return 1;         
2481       }
2482     }
2483   }
2484
2485   *zero_is_white = 0;
2486   return 0;
2487 }
2488
2489 /*
2490 =item i_get_file_background(im, &bg)
2491
2492 =category Files
2493
2494 Retrieve the file write background color tag from the image.
2495
2496 If not present, returns black.
2497
2498 =cut
2499 */
2500
2501 void
2502 i_get_file_background(i_img *im, i_color *bg) {
2503   if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
2504     /* black default */
2505     bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
2506   }
2507   /* always full alpha */
2508   bg->channel[3] = 255;
2509 }
2510
2511 /*
2512 =item i_get_file_backgroundf(im, &bg)
2513
2514 =category Files
2515
2516 Retrieve the file write background color tag from the image as a
2517 floating point color.
2518
2519 Implemented in terms of i_get_file_background().
2520
2521 If not present, returns black.
2522
2523 =cut
2524 */
2525
2526 void
2527 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
2528   i_color bg;
2529
2530   i_get_file_background(im, &bg);
2531   fbg->rgba.r = Sample8ToF(bg.rgba.r);
2532   fbg->rgba.g = Sample8ToF(bg.rgba.g);
2533   fbg->rgba.b = Sample8ToF(bg.rgba.b);
2534   fbg->rgba.a = 1.0;
2535 }
2536
2537 /*
2538 =back
2539
2540 =head1 AUTHOR
2541
2542 Arnar M. Hrafnkelsson <addi@umich.edu>
2543
2544 Tony Cook <tony@develop-help.com>
2545
2546 =head1 SEE ALSO
2547
2548 L<Imager>, L<gif.c>
2549
2550 =cut
2551 */