huge spelling update and spell checking patch
[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
751   i_clear_error();
752   mm_log((1,"i_scaleaxis(im %p,Value %.2f,Axis %d)\n",im,Value,Axis));
753
754
755   if (Axis == XAXIS) {
756     hsize = (int)(0.5 + im->xsize * Value);
757     if (hsize < 1) {
758       hsize = 1;
759       Value = 1.0 / im->xsize;
760     }
761     vsize = im->ysize;
762     
763     jEnd = hsize;
764     iEnd = vsize;
765   } else {
766     hsize = im->xsize;
767     vsize = (int)(0.5 + im->ysize * Value);
768
769     if (vsize < 1) {
770       vsize = 1;
771       Value = 1.0 / im->ysize;
772     }
773
774     jEnd = vsize;
775     iEnd = hsize;
776   }
777   
778   new_img = i_img_empty_ch(NULL, hsize, vsize, im->channels);
779   if (!new_img) {
780     i_push_error(0, "cannot create output image");
781     return NULL;
782   }
783   
784   /* 1.4 is a magic number, setting it to 2 will cause rather blurred images */
785   LanczosWidthFactor = (Value >= 1) ? 1 : (int) (1.4/Value); 
786   lMax = LanczosWidthFactor << 1;
787   
788   l0 = mymalloc(lMax * sizeof(float));
789   l1 = mymalloc(lMax * sizeof(float));
790   
791   for (j=0; j<jEnd; j++) {
792     OldLocation = ((float) j) / Value;
793     T = (int) (OldLocation);
794     F = OldLocation - (float) T;
795     
796     for (l = 0; l<lMax; l++) {
797       l0[lMax-l-1] = Lanczos(((float) (lMax-l-1) + F) / (float) LanczosWidthFactor);
798       l1[l]        = Lanczos(((float) (l+1)      - F) / (float) LanczosWidthFactor);
799     }
800     
801     /* Make sure filter is normalized */
802     t = 0.0;
803     for(l=0; l<lMax; l++) {
804       t+=l0[l];
805       t+=l1[l];
806     }
807     t /= (float)LanczosWidthFactor;
808     
809     for(l=0; l<lMax; l++) {
810       l0[l] /= t;
811       l1[l] /= t;
812     }
813
814     if (Axis == XAXIS) {
815       
816       for (i=0; i<iEnd; i++) {
817         for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
818         for (l=0; l<lMax; l++) {
819           int mx = T-lMax+l+1;
820           int Mx = T+l+1;
821           mx = (mx < 0) ? 0 : mx;
822           Mx = (Mx >= im->xsize) ? im->xsize-1 : Mx;
823           
824           i_gpix(im, Mx, i, &val1);
825           i_gpix(im, mx, i, &val2);
826           
827           for (k=0; k<im->channels; k++) {
828             PictureValue[k] += l1[l]        * val1.channel[k];
829             PictureValue[k] += l0[lMax-l-1] * val2.channel[k];
830           }
831         }
832         for(k=0;k<im->channels;k++) {
833           psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
834           val.channel[k]=minmax(0,255,psave);
835         }
836         i_ppix(new_img, j, i, &val);
837       }
838       
839     } else {
840       
841       for (i=0; i<iEnd; i++) {
842         for (k=0; k<im->channels; k++) PictureValue[k] = 0.0;
843         for (l=0; l < lMax; l++) {
844           int mx = T-lMax+l+1;
845           int Mx = T+l+1;
846           mx = (mx < 0) ? 0 : mx;
847           Mx = (Mx >= im->ysize) ? im->ysize-1 : Mx;
848
849           i_gpix(im, i, Mx, &val1);
850           i_gpix(im, i, mx, &val2);
851           for (k=0; k<im->channels; k++) {
852             PictureValue[k] += l1[l]        * val1.channel[k];
853             PictureValue[k] += l0[lMax-l-1] * val2.channel[k]; 
854           }
855         }
856         for (k=0; k<im->channels; k++) {
857           psave = (short)(0.5+(PictureValue[k] / LanczosWidthFactor));
858           val.channel[k] = minmax(0, 255, psave);
859         }
860         i_ppix(new_img, i, j, &val);
861       }
862       
863     }
864   }
865   myfree(l0);
866   myfree(l1);
867
868   mm_log((1,"(%p) <- i_scaleaxis\n", new_img));
869
870   return new_img;
871 }
872
873
874 /* 
875 =item i_scale_nn(im, scx, scy)
876
877 Scale by using nearest neighbor 
878 Both axes scaled at the same time since 
879 nothing is gained by doing it in two steps 
880
881 =cut
882 */
883
884
885 i_img*
886 i_scale_nn(i_img *im, float scx, float scy) {
887
888   int nxsize,nysize,nx,ny;
889   i_img *new_img;
890   i_color val;
891
892   mm_log((1,"i_scale_nn(im 0x%x,scx %.2f,scy %.2f)\n",im,scx,scy));
893
894   nxsize = (int) ((float) im->xsize * scx);
895   if (nxsize < 1) {
896     nxsize = 1;
897     scx = 1.0 / im->xsize;
898   }
899   nysize = (int) ((float) im->ysize * scy);
900   if (nysize < 1) {
901     nysize = 1;
902     scy = 1.0 / im->ysize;
903   }
904   im_assert(scx != 0 && scy != 0);
905     
906   new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
907   
908   for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
909     i_gpix(im,((float)nx)/scx,((float)ny)/scy,&val);
910     i_ppix(new_img,nx,ny,&val);
911   }
912
913   mm_log((1,"(0x%x) <- i_scale_nn\n",new_img));
914
915   return new_img;
916 }
917
918 /*
919 =item i_sametype(C<im>, C<xsize>, C<ysize>)
920
921 =category Image creation/destruction
922 =synopsis i_img *img = i_sametype(src, width, height);
923
924 Returns an image of the same type (sample size, channels, paletted/direct).
925
926 For paletted images the palette is copied from the source.
927
928 =cut
929 */
930
931 i_img *i_sametype(i_img *src, int xsize, int ysize) {
932   if (src->type == i_direct_type) {
933     if (src->bits == 8) {
934       return i_img_empty_ch(NULL, xsize, ysize, src->channels);
935     }
936     else if (src->bits == i_16_bits) {
937       return i_img_16_new(xsize, ysize, src->channels);
938     }
939     else if (src->bits == i_double_bits) {
940       return i_img_double_new(xsize, ysize, src->channels);
941     }
942     else {
943       i_push_error(0, "Unknown image bits");
944       return NULL;
945     }
946   }
947   else {
948     i_color col;
949     int i;
950
951     i_img *targ = i_img_pal_new(xsize, ysize, src->channels, i_maxcolors(src));
952     for (i = 0; i < i_colorcount(src); ++i) {
953       i_getcolors(src, i, &col, 1);
954       i_addcolors(targ, &col, 1);
955     }
956
957     return targ;
958   }
959 }
960
961 /*
962 =item i_sametype_chans(C<im>, C<xsize>, C<ysize>, C<channels>)
963
964 =category Image creation/destruction
965 =synopsis i_img *img = i_sametype_chans(src, width, height, channels);
966
967 Returns an image of the same type (sample size).
968
969 For paletted images the equivalent direct type is returned.
970
971 =cut
972 */
973
974 i_img *i_sametype_chans(i_img *src, int xsize, int ysize, int channels) {
975   if (src->bits == 8) {
976     return i_img_empty_ch(NULL, xsize, ysize, channels);
977   }
978   else if (src->bits == i_16_bits) {
979     return i_img_16_new(xsize, ysize, channels);
980   }
981   else if (src->bits == i_double_bits) {
982     return i_img_double_new(xsize, ysize, channels);
983   }
984   else {
985     i_push_error(0, "Unknown image bits");
986     return NULL;
987   }
988 }
989
990 /*
991 =item i_transform(im, opx, opxl, opy, opyl, parm, parmlen)
992
993 Spatially transforms I<im> returning a new image.
994
995 opx for a length of opxl and opy for a length of opy are arrays of
996 operators that modify the x and y positions to retreive the pixel data from.
997
998 parm and parmlen define extra parameters that the operators may use.
999
1000 Note that this function is largely superseded by the more flexible
1001 L<transform.c/i_transform2>.
1002
1003 Returns the new image.
1004
1005 The operators for this function are defined in L<stackmach.c>.
1006
1007 =cut
1008 */
1009 i_img*
1010 i_transform(i_img *im, int *opx,int opxl,int *opy,int opyl,double parm[],int parmlen) {
1011   double rx,ry;
1012   int nxsize,nysize,nx,ny;
1013   i_img *new_img;
1014   i_color val;
1015   
1016   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));
1017
1018   nxsize = im->xsize;
1019   nysize = im->ysize ;
1020   
1021   new_img=i_img_empty_ch(NULL,nxsize,nysize,im->channels);
1022   /*   fprintf(stderr,"parm[2]=%f\n",parm[2]);   */
1023   for(ny=0;ny<nysize;ny++) for(nx=0;nx<nxsize;nx++) {
1024     /*     parm[parmlen-2]=(double)nx;
1025            parm[parmlen-1]=(double)ny; */
1026
1027     parm[0]=(double)nx;
1028     parm[1]=(double)ny;
1029
1030     /*     fprintf(stderr,"(%d,%d) ->",nx,ny);  */
1031     rx=i_op_run(opx,opxl,parm,parmlen);
1032     ry=i_op_run(opy,opyl,parm,parmlen);
1033     /*    fprintf(stderr,"(%f,%f)\n",rx,ry); */
1034     i_gpix(im,rx,ry,&val);
1035     i_ppix(new_img,nx,ny,&val);
1036   }
1037
1038   mm_log((1,"(0x%x) <- i_transform\n",new_img));
1039   return new_img;
1040 }
1041
1042 /*
1043 =item i_img_diff(im1, im2)
1044
1045 Calculates the sum of the squares of the differences between
1046 correspoding channels in two images.
1047
1048 If the images are not the same size then only the common area is 
1049 compared, hence even if images are different sizes this function 
1050 can return zero.
1051
1052 =cut
1053 */
1054
1055 float
1056 i_img_diff(i_img *im1,i_img *im2) {
1057   int x,y,ch,xb,yb,chb;
1058   float tdiff;
1059   i_color val1,val2;
1060
1061   mm_log((1,"i_img_diff(im1 0x%x,im2 0x%x)\n",im1,im2));
1062
1063   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1064   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1065   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1066
1067   mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1068
1069   tdiff=0;
1070   for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1071     i_gpix(im1,x,y,&val1);
1072     i_gpix(im2,x,y,&val2);
1073
1074     for(ch=0;ch<chb;ch++) tdiff+=(val1.channel[ch]-val2.channel[ch])*(val1.channel[ch]-val2.channel[ch]);
1075   }
1076   mm_log((1,"i_img_diff <- (%.2f)\n",tdiff));
1077   return tdiff;
1078 }
1079
1080 /*
1081 =item i_img_diffd(im1, im2)
1082
1083 Calculates the sum of the squares of the differences between
1084 correspoding channels in two images.
1085
1086 If the images are not the same size then only the common area is 
1087 compared, hence even if images are different sizes this function 
1088 can return zero.
1089
1090 This is like i_img_diff() but looks at floating point samples instead.
1091
1092 =cut
1093 */
1094
1095 double
1096 i_img_diffd(i_img *im1,i_img *im2) {
1097   int x,y,ch,xb,yb,chb;
1098   double tdiff;
1099   i_fcolor val1,val2;
1100
1101   mm_log((1,"i_img_diffd(im1 0x%x,im2 0x%x)\n",im1,im2));
1102
1103   xb=(im1->xsize<im2->xsize)?im1->xsize:im2->xsize;
1104   yb=(im1->ysize<im2->ysize)?im1->ysize:im2->ysize;
1105   chb=(im1->channels<im2->channels)?im1->channels:im2->channels;
1106
1107   mm_log((1,"i_img_diff: xb=%d xy=%d chb=%d\n",xb,yb,chb));
1108
1109   tdiff=0;
1110   for(y=0;y<yb;y++) for(x=0;x<xb;x++) {
1111     i_gpixf(im1,x,y,&val1);
1112     i_gpixf(im2,x,y,&val2);
1113
1114     for(ch=0;ch<chb;ch++) {
1115       double sdiff = val1.channel[ch]-val2.channel[ch];
1116       tdiff += sdiff * sdiff;
1117     }
1118   }
1119   mm_log((1,"i_img_diffd <- (%.2f)\n",tdiff));
1120
1121   return tdiff;
1122 }
1123
1124 /* just a tiny demo of haar wavelets */
1125
1126 i_img*
1127 i_haar(i_img *im) {
1128   int mx,my;
1129   int fx,fy;
1130   int x,y;
1131   int ch,c;
1132   i_img *new_img,*new_img2;
1133   i_color val1,val2,dval1,dval2;
1134   
1135   mx=im->xsize;
1136   my=im->ysize;
1137   fx=(mx+1)/2;
1138   fy=(my+1)/2;
1139
1140
1141   /* horizontal pass */
1142   
1143   new_img=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1144   new_img2=i_img_empty_ch(NULL,fx*2,fy*2,im->channels);
1145
1146   c=0; 
1147   for(y=0;y<my;y++) for(x=0;x<fx;x++) {
1148     i_gpix(im,x*2,y,&val1);
1149     i_gpix(im,x*2+1,y,&val2);
1150     for(ch=0;ch<im->channels;ch++) {
1151       dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1152       dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1153     }
1154     i_ppix(new_img,x,y,&dval1);
1155     i_ppix(new_img,x+fx,y,&dval2);
1156   }
1157
1158   for(y=0;y<fy;y++) for(x=0;x<mx;x++) {
1159     i_gpix(new_img,x,y*2,&val1);
1160     i_gpix(new_img,x,y*2+1,&val2);
1161     for(ch=0;ch<im->channels;ch++) {
1162       dval1.channel[ch]=(val1.channel[ch]+val2.channel[ch])/2;
1163       dval2.channel[ch]=(255+val1.channel[ch]-val2.channel[ch])/2;
1164     }
1165     i_ppix(new_img2,x,y,&dval1);
1166     i_ppix(new_img2,x,y+fy,&dval2);
1167   }
1168
1169   i_img_destroy(new_img);
1170   return new_img2;
1171 }
1172
1173 /* 
1174 =item i_count_colors(im, maxc)
1175
1176 returns number of colors or -1 
1177 to indicate that it was more than max colors
1178
1179 =cut
1180 */
1181 /* This function has been changed and is now faster. It's using
1182  * i_gsamp instead of i_gpix */
1183 int
1184 i_count_colors(i_img *im,int maxc) {
1185   struct octt *ct;
1186   int x,y;
1187   int colorcnt;
1188   int channels[3];
1189   int *samp_chans;
1190   i_sample_t * samp;
1191   int xsize = im->xsize; 
1192   int ysize = im->ysize;
1193   int samp_cnt = 3 * xsize;
1194
1195   if (im->channels >= 3) {
1196     samp_chans = NULL;
1197   }
1198   else {
1199     channels[0] = channels[1] = channels[2] = 0;
1200     samp_chans = channels;
1201   }
1202
1203   ct = octt_new();
1204
1205   samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1206
1207   colorcnt = 0;
1208   for(y = 0; y < ysize; ) {
1209       i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1210       for(x = 0; x < samp_cnt; ) {
1211           colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1212           x += 3;
1213           if (colorcnt > maxc) { 
1214               octt_delete(ct); 
1215               return -1; 
1216           }
1217       }
1218   }
1219   myfree(samp);
1220   octt_delete(ct);
1221   return colorcnt;
1222 }
1223
1224 /* sorts the array ra[0..n-1] into increasing order using heapsort algorithm 
1225  * (adapted from the Numerical Recipes)
1226  */
1227 /* Needed by get_anonymous_color_histo */
1228 static void
1229 hpsort(unsigned int n, unsigned *ra) {
1230     unsigned int i,
1231                  ir,
1232                  j,
1233                  l, 
1234                  rra;
1235
1236     if (n < 2) return;
1237     l = n >> 1;
1238     ir = n - 1;
1239     for(;;) {
1240         if (l > 0) {
1241             rra = ra[--l];
1242         }
1243         else {
1244             rra = ra[ir];
1245             ra[ir] = ra[0];
1246             if (--ir == 0) {
1247                 ra[0] = rra;
1248                 break;
1249             }
1250         }
1251         i = l;
1252         j = 2 * l + 1;
1253         while (j <= ir) {
1254             if (j < ir && ra[j] < ra[j+1]) j++;
1255             if (rra < ra[j]) {
1256                 ra[i] = ra[j];
1257                 i = j;
1258                 j++; j <<= 1; j--;
1259             }
1260             else break;
1261         }
1262         ra[i] = rra;
1263     }
1264 }
1265
1266 /* This function constructs an ordered list which represents how much the
1267  * different colors are used. So for instance (100, 100, 500) means that one
1268  * color is used for 500 pixels, another for 100 pixels and another for 100
1269  * pixels. It's tuned for performance. You might not like the way I've hardcoded
1270  * the maxc ;-) and you might want to change the name... */
1271 /* Uses octt_histo */
1272 int
1273 i_get_anonymous_color_histo(i_img *im, unsigned int **col_usage, int maxc) {
1274   struct octt *ct;
1275   int x,y;
1276   int colorcnt;
1277   unsigned int *col_usage_it;
1278   i_sample_t * samp;
1279   int channels[3];
1280   int *samp_chans;
1281   
1282   int xsize = im->xsize; 
1283   int ysize = im->ysize;
1284   int samp_cnt = 3 * xsize;
1285   ct = octt_new();
1286   
1287   samp = (i_sample_t *) mymalloc( xsize * 3 * sizeof(i_sample_t));
1288   
1289   if (im->channels >= 3) {
1290     samp_chans = NULL;
1291   }
1292   else {
1293     channels[0] = channels[1] = channels[2] = 0;
1294     samp_chans = channels;
1295   }
1296
1297   colorcnt = 0;
1298   for(y = 0; y < ysize; ) {
1299     i_gsamp(im, 0, xsize, y++, samp, samp_chans, 3);
1300     for(x = 0; x < samp_cnt; ) {
1301       colorcnt += octt_add(ct, samp[x], samp[x+1], samp[x+2]);
1302       x += 3;
1303       if (colorcnt > maxc) { 
1304         octt_delete(ct); 
1305         return -1; 
1306       }
1307     }
1308   }
1309   myfree(samp);
1310   /* Now that we know the number of colours... */
1311   col_usage_it = *col_usage = (unsigned int *) mymalloc(colorcnt * sizeof(unsigned int));
1312   octt_histo(ct, &col_usage_it);
1313   hpsort(colorcnt, *col_usage);
1314   octt_delete(ct);
1315   return colorcnt;
1316 }
1317
1318 /*
1319 =back
1320
1321 =head2 8-bit per sample image internal functions
1322
1323 These are the functions installed in an 8-bit per sample image.
1324
1325 =over
1326
1327 =item i_ppix_d(im, x, y, col)
1328
1329 Internal function.
1330
1331 This is the function kept in the i_f_ppix member of an i_img object.
1332 It does a normal store of a pixel into the image with range checking.
1333
1334 Returns 0 if the pixel could be set, -1 otherwise.
1335
1336 =cut
1337 */
1338 static
1339 int
1340 i_ppix_d(i_img *im, int x, int y, const i_color *val) {
1341   int ch;
1342   
1343   if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1344     for(ch=0;ch<im->channels;ch++)
1345       if (im->ch_mask&(1<<ch)) 
1346         im->idata[(x+y*im->xsize)*im->channels+ch]=val->channel[ch];
1347     return 0;
1348   }
1349   return -1; /* error was clipped */
1350 }
1351
1352 /*
1353 =item i_gpix_d(im, x, y, &col)
1354
1355 Internal function.
1356
1357 This is the function kept in the i_f_gpix member of an i_img object.
1358 It does normal retrieval of a pixel from the image with range checking.
1359
1360 Returns 0 if the pixel could be set, -1 otherwise.
1361
1362 =cut
1363 */
1364 static
1365 int 
1366 i_gpix_d(i_img *im, int x, int y, i_color *val) {
1367   int ch;
1368   if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1369     for(ch=0;ch<im->channels;ch++) 
1370       val->channel[ch]=im->idata[(x+y*im->xsize)*im->channels+ch];
1371     return 0;
1372   }
1373   for(ch=0;ch<im->channels;ch++) val->channel[ch] = 0;
1374   return -1; /* error was cliped */
1375 }
1376
1377 /*
1378 =item i_glin_d(im, l, r, y, vals)
1379
1380 Reads a line of data from the image, storing the pixels at vals.
1381
1382 The line runs from (l,y) inclusive to (r,y) non-inclusive
1383
1384 vals should point at space for (r-l) pixels.
1385
1386 l should never be less than zero (to avoid confusion about where to
1387 put the pixels in vals).
1388
1389 Returns the number of pixels copied (eg. if r, l or y is out of range)
1390
1391 =cut
1392 */
1393 static
1394 int
1395 i_glin_d(i_img *im, int l, int r, int y, i_color *vals) {
1396   int ch, count, i;
1397   unsigned char *data;
1398   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1399     if (r > im->xsize)
1400       r = im->xsize;
1401     data = im->idata + (l+y*im->xsize) * im->channels;
1402     count = r - l;
1403     for (i = 0; i < count; ++i) {
1404       for (ch = 0; ch < im->channels; ++ch)
1405         vals[i].channel[ch] = *data++;
1406     }
1407     return count;
1408   }
1409   else {
1410     return 0;
1411   }
1412 }
1413
1414 /*
1415 =item i_plin_d(im, l, r, y, vals)
1416
1417 Writes a line of data into the image, using the pixels at vals.
1418
1419 The line runs from (l,y) inclusive to (r,y) non-inclusive
1420
1421 vals should point at (r-l) pixels.
1422
1423 l should never be less than zero (to avoid confusion about where to
1424 get the pixels in vals).
1425
1426 Returns the number of pixels copied (eg. if r, l or y is out of range)
1427
1428 =cut
1429 */
1430 static
1431 int
1432 i_plin_d(i_img *im, int l, int r, int y, const i_color *vals) {
1433   int ch, count, i;
1434   unsigned char *data;
1435   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1436     if (r > im->xsize)
1437       r = im->xsize;
1438     data = im->idata + (l+y*im->xsize) * im->channels;
1439     count = r - l;
1440     for (i = 0; i < count; ++i) {
1441       for (ch = 0; ch < im->channels; ++ch) {
1442         if (im->ch_mask & (1 << ch)) 
1443           *data = vals[i].channel[ch];
1444         ++data;
1445       }
1446     }
1447     return count;
1448   }
1449   else {
1450     return 0;
1451   }
1452 }
1453
1454 /*
1455 =item i_ppixf_d(im, x, y, val)
1456
1457 =cut
1458 */
1459 static
1460 int
1461 i_ppixf_d(i_img *im, int x, int y, const i_fcolor *val) {
1462   int ch;
1463   
1464   if ( x>-1 && x<im->xsize && y>-1 && y<im->ysize ) {
1465     for(ch=0;ch<im->channels;ch++)
1466       if (im->ch_mask&(1<<ch)) {
1467         im->idata[(x+y*im->xsize)*im->channels+ch] = 
1468           SampleFTo8(val->channel[ch]);
1469       }
1470     return 0;
1471   }
1472   return -1; /* error was clipped */
1473 }
1474
1475 /*
1476 =item i_gpixf_d(im, x, y, val)
1477
1478 =cut
1479 */
1480 static
1481 int
1482 i_gpixf_d(i_img *im, int x, int y, i_fcolor *val) {
1483   int ch;
1484   if (x>-1 && x<im->xsize && y>-1 && y<im->ysize) {
1485     for(ch=0;ch<im->channels;ch++) {
1486       val->channel[ch] = 
1487         Sample8ToF(im->idata[(x+y*im->xsize)*im->channels+ch]);
1488     }
1489     return 0;
1490   }
1491   return -1; /* error was cliped */
1492 }
1493
1494 /*
1495 =item i_glinf_d(im, l, r, y, vals)
1496
1497 Reads a line of data from the image, storing the pixels at vals.
1498
1499 The line runs from (l,y) inclusive to (r,y) non-inclusive
1500
1501 vals should point at space for (r-l) pixels.
1502
1503 l should never be less than zero (to avoid confusion about where to
1504 put the pixels in vals).
1505
1506 Returns the number of pixels copied (eg. if r, l or y is out of range)
1507
1508 =cut
1509 */
1510 static
1511 int
1512 i_glinf_d(i_img *im, int l, int r, int y, i_fcolor *vals) {
1513   int ch, count, i;
1514   unsigned char *data;
1515   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1516     if (r > im->xsize)
1517       r = im->xsize;
1518     data = im->idata + (l+y*im->xsize) * im->channels;
1519     count = r - l;
1520     for (i = 0; i < count; ++i) {
1521       for (ch = 0; ch < im->channels; ++ch)
1522         vals[i].channel[ch] = Sample8ToF(*data++);
1523     }
1524     return count;
1525   }
1526   else {
1527     return 0;
1528   }
1529 }
1530
1531 /*
1532 =item i_plinf_d(im, l, r, y, vals)
1533
1534 Writes a line of data into the image, using the pixels at vals.
1535
1536 The line runs from (l,y) inclusive to (r,y) non-inclusive
1537
1538 vals should point at (r-l) pixels.
1539
1540 l should never be less than zero (to avoid confusion about where to
1541 get the pixels in vals).
1542
1543 Returns the number of pixels copied (eg. if r, l or y is out of range)
1544
1545 =cut
1546 */
1547 static
1548 int
1549 i_plinf_d(i_img *im, int l, int r, int y, const i_fcolor *vals) {
1550   int ch, count, i;
1551   unsigned char *data;
1552   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1553     if (r > im->xsize)
1554       r = im->xsize;
1555     data = im->idata + (l+y*im->xsize) * im->channels;
1556     count = r - l;
1557     for (i = 0; i < count; ++i) {
1558       for (ch = 0; ch < im->channels; ++ch) {
1559         if (im->ch_mask & (1 << ch)) 
1560           *data = SampleFTo8(vals[i].channel[ch]);
1561         ++data;
1562       }
1563     }
1564     return count;
1565   }
1566   else {
1567     return 0;
1568   }
1569 }
1570
1571 /*
1572 =item i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, int *chans, int chan_count)
1573
1574 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1575 for the channels specified by chans, an array of int with chan_count
1576 elements.
1577
1578 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1579
1580 =cut
1581 */
1582 static
1583 int
1584 i_gsamp_d(i_img *im, int l, int r, int y, i_sample_t *samps, 
1585               const int *chans, int chan_count) {
1586   int ch, count, i, w;
1587   unsigned char *data;
1588
1589   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1590     if (r > im->xsize)
1591       r = im->xsize;
1592     data = im->idata + (l+y*im->xsize) * im->channels;
1593     w = r - l;
1594     count = 0;
1595
1596     if (chans) {
1597       /* make sure we have good channel numbers */
1598       for (ch = 0; ch < chan_count; ++ch) {
1599         if (chans[ch] < 0 || chans[ch] >= im->channels) {
1600           i_push_errorf(0, "No channel %d in this image", chans[ch]);
1601           return 0;
1602         }
1603       }
1604       for (i = 0; i < w; ++i) {
1605         for (ch = 0; ch < chan_count; ++ch) {
1606           *samps++ = data[chans[ch]];
1607           ++count;
1608         }
1609         data += im->channels;
1610       }
1611     }
1612     else {
1613       if (chan_count <= 0 || chan_count > im->channels) {
1614         i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", 
1615                       chan_count);
1616         return 0;
1617       }
1618       for (i = 0; i < w; ++i) {
1619         for (ch = 0; ch < chan_count; ++ch) {
1620           *samps++ = data[ch];
1621           ++count;
1622         }
1623         data += im->channels;
1624       }
1625     }
1626
1627     return count;
1628   }
1629   else {
1630     return 0;
1631   }
1632 }
1633
1634 /*
1635 =item i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, int *chans, int chan_count)
1636
1637 Reads sample values from im for the horizontal line (l, y) to (r-1,y)
1638 for the channels specified by chan_mask, where bit 0 is the first
1639 channel.
1640
1641 Returns the number of samples read (which should be (r-l) * bits_set(chan_mask)
1642
1643 =cut
1644 */
1645 static
1646 int
1647 i_gsampf_d(i_img *im, int l, int r, int y, i_fsample_t *samps, 
1648            const int *chans, int chan_count) {
1649   int ch, count, i, w;
1650   unsigned char *data;
1651   for (ch = 0; ch < chan_count; ++ch) {
1652     if (chans[ch] < 0 || chans[ch] >= im->channels) {
1653       i_push_errorf(0, "No channel %d in this image", chans[ch]);
1654     }
1655   }
1656   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1657     if (r > im->xsize)
1658       r = im->xsize;
1659     data = im->idata + (l+y*im->xsize) * im->channels;
1660     w = r - l;
1661     count = 0;
1662
1663     if (chans) {
1664       /* make sure we have good channel numbers */
1665       for (ch = 0; ch < chan_count; ++ch) {
1666         if (chans[ch] < 0 || chans[ch] >= im->channels) {
1667           i_push_errorf(0, "No channel %d in this image", chans[ch]);
1668           return 0;
1669         }
1670       }
1671       for (i = 0; i < w; ++i) {
1672         for (ch = 0; ch < chan_count; ++ch) {
1673           *samps++ = Sample8ToF(data[chans[ch]]);
1674           ++count;
1675         }
1676         data += im->channels;
1677       }
1678     }
1679     else {
1680       if (chan_count <= 0 || chan_count > im->channels) {
1681         i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", 
1682                       chan_count);
1683         return 0;
1684       }
1685       for (i = 0; i < w; ++i) {
1686         for (ch = 0; ch < chan_count; ++ch) {
1687           *samps++ = Sample8ToF(data[ch]);
1688           ++count;
1689         }
1690         data += im->channels;
1691       }
1692     }
1693     return count;
1694   }
1695   else {
1696     return 0;
1697   }
1698 }
1699
1700 /*
1701 =back
1702
1703 =head2 Image method wrappers
1704
1705 These functions provide i_fsample_t functions in terms of their
1706 i_sample_t versions.
1707
1708 =over
1709
1710 =item i_ppixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1711
1712 =cut
1713 */
1714
1715 int i_ppixf_fp(i_img *im, int x, int y, const i_fcolor *pix) {
1716   i_color temp;
1717   int ch;
1718
1719   for (ch = 0; ch < im->channels; ++ch)
1720     temp.channel[ch] = SampleFTo8(pix->channel[ch]);
1721   
1722   return i_ppix(im, x, y, &temp);
1723 }
1724
1725 /*
1726 =item i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix)
1727
1728 =cut
1729 */
1730 int i_gpixf_fp(i_img *im, int x, int y, i_fcolor *pix) {
1731   i_color temp;
1732   int ch;
1733
1734   if (i_gpix(im, x, y, &temp)) {
1735     for (ch = 0; ch < im->channels; ++ch)
1736       pix->channel[ch] = Sample8ToF(temp.channel[ch]);
1737     return 0;
1738   }
1739   else 
1740     return -1;
1741 }
1742
1743 /*
1744 =item i_plinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1745
1746 =cut
1747 */
1748 int i_plinf_fp(i_img *im, int l, int r, int y, const i_fcolor *pix) {
1749   i_color *work;
1750
1751   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1752     if (r > im->xsize)
1753       r = im->xsize;
1754     if (r > l) {
1755       int ret;
1756       int i, ch;
1757       work = mymalloc(sizeof(i_color) * (r-l));
1758       for (i = 0; i < r-l; ++i) {
1759         for (ch = 0; ch < im->channels; ++ch) 
1760           work[i].channel[ch] = SampleFTo8(pix[i].channel[ch]);
1761       }
1762       ret = i_plin(im, l, r, y, work);
1763       myfree(work);
1764
1765       return ret;
1766     }
1767     else {
1768       return 0;
1769     }
1770   }
1771   else {
1772     return 0;
1773   }
1774 }
1775
1776 /*
1777 =item i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix)
1778
1779 =cut
1780 */
1781 int i_glinf_fp(i_img *im, int l, int r, int y, i_fcolor *pix) {
1782   i_color *work;
1783
1784   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1785     if (r > im->xsize)
1786       r = im->xsize;
1787     if (r > l) {
1788       int ret;
1789       int i, ch;
1790       work = mymalloc(sizeof(i_color) * (r-l));
1791       ret = i_plin(im, l, r, y, work);
1792       for (i = 0; i < r-l; ++i) {
1793         for (ch = 0; ch < im->channels; ++ch) 
1794           pix[i].channel[ch] = Sample8ToF(work[i].channel[ch]);
1795       }
1796       myfree(work);
1797
1798       return ret;
1799     }
1800     else {
1801       return 0;
1802     }
1803   }
1804   else {
1805     return 0;
1806   }
1807 }
1808
1809 /*
1810 =item i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, int *chans, int chan_count)
1811
1812 =cut
1813 */
1814 int i_gsampf_fp(i_img *im, int l, int r, int y, i_fsample_t *samp, 
1815                 int const *chans, int chan_count) {
1816   i_sample_t *work;
1817
1818   if (y >= 0 && y < im->ysize && l < im->xsize && l >= 0) {
1819     if (r > im->xsize)
1820       r = im->xsize;
1821     if (r > l) {
1822       int ret;
1823       int i;
1824       work = mymalloc(sizeof(i_sample_t) * (r-l));
1825       ret = i_gsamp(im, l, r, y, work, chans, chan_count);
1826       for (i = 0; i < ret; ++i) {
1827           samp[i] = Sample8ToF(work[i]);
1828       }
1829       myfree(work);
1830
1831       return ret;
1832     }
1833     else {
1834       return 0;
1835     }
1836   }
1837   else {
1838     return 0;
1839   }
1840 }
1841
1842 /*
1843 =back
1844
1845 =head2 Palette wrapper functions
1846
1847 Used for virtual images, these forward palette calls to a wrapped image, 
1848 assuming the wrapped image is the first pointer in the structure that 
1849 im->ext_data points at.
1850
1851 =over
1852
1853 =item i_addcolors_forward(i_img *im, const i_color *colors, int count)
1854
1855 =cut
1856 */
1857 int i_addcolors_forward(i_img *im, const i_color *colors, int count) {
1858   return i_addcolors(*(i_img **)im->ext_data, colors, count);
1859 }
1860
1861 /*
1862 =item i_getcolors_forward(i_img *im, int i, i_color *color, int count)
1863
1864 =cut
1865 */
1866 int i_getcolors_forward(i_img *im, int i, i_color *color, int count) {
1867   return i_getcolors(*(i_img **)im->ext_data, i, color, count);
1868 }
1869
1870 /*
1871 =item i_setcolors_forward(i_img *im, int i, const i_color *color, int count)
1872
1873 =cut
1874 */
1875 int i_setcolors_forward(i_img *im, int i, const i_color *color, int count) {
1876   return i_setcolors(*(i_img **)im->ext_data, i, color, count);
1877 }
1878
1879 /*
1880 =item i_colorcount_forward(i_img *im)
1881
1882 =cut
1883 */
1884 int i_colorcount_forward(i_img *im) {
1885   return i_colorcount(*(i_img **)im->ext_data);
1886 }
1887
1888 /*
1889 =item i_maxcolors_forward(i_img *im)
1890
1891 =cut
1892 */
1893 int i_maxcolors_forward(i_img *im) {
1894   return i_maxcolors(*(i_img **)im->ext_data);
1895 }
1896
1897 /*
1898 =item i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry)
1899
1900 =cut
1901 */
1902 int i_findcolor_forward(i_img *im, const i_color *color, i_palidx *entry) {
1903   return i_findcolor(*(i_img **)im->ext_data, color, entry);
1904 }
1905
1906 /*
1907 =back
1908
1909 =head2 Fallback handler
1910
1911 =over
1912
1913 =item i_gsamp_bits_fb
1914
1915 =cut
1916 */
1917
1918 int 
1919 i_gsamp_bits_fb(i_img *im, int l, int r, int y, unsigned *samps, 
1920                 const int *chans, int chan_count, int bits) {
1921   if (bits < 1 || bits > 32) {
1922     i_push_error(0, "Invalid bits, must be 1..32");
1923     return -1;
1924   }
1925
1926   if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
1927     double scale;
1928     int ch, count, i, w;
1929     
1930     if (bits == 32)
1931       scale = 4294967295.0;
1932     else
1933       scale = (double)(1 << bits) - 1;
1934
1935     if (r > im->xsize)
1936       r = im->xsize;
1937     w = r - l;
1938     count = 0;
1939
1940     if (chans) {
1941       /* make sure we have good channel numbers */
1942       for (ch = 0; ch < chan_count; ++ch) {
1943         if (chans[ch] < 0 || chans[ch] >= im->channels) {
1944           i_push_errorf(0, "No channel %d in this image", chans[ch]);
1945           return -1;
1946         }
1947       }
1948       for (i = 0; i < w; ++i) {
1949         i_fcolor c;
1950         i_gpixf(im, l+i, y, &c);
1951         for (ch = 0; ch < chan_count; ++ch) {
1952           *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1953           ++count;
1954         }
1955       }
1956     }
1957     else {
1958       if (chan_count <= 0 || chan_count > im->channels) {
1959         i_push_error(0, "Invalid channel count");
1960         return -1;
1961       }
1962       for (i = 0; i < w; ++i) {
1963         i_fcolor c;
1964         i_gpixf(im, l+i, y, &c);
1965         for (ch = 0; ch < chan_count; ++ch) {
1966           *samps++ = (unsigned)(c.channel[ch] * scale + 0.5);
1967           ++count;
1968         }
1969       }
1970     }
1971
1972     return count;
1973   }
1974   else {
1975     i_push_error(0, "Image position outside of image");
1976     return -1;
1977   }
1978 }
1979
1980 /*
1981 =back
1982
1983 =head2 Stream reading and writing wrapper functions
1984
1985 =over
1986
1987 =item i_gen_reader(i_gen_read_data *info, char *buf, int length)
1988
1989 Performs general read buffering for file readers that permit reading
1990 to be done through a callback.
1991
1992 The final callback gets two parameters, a I<need> value, and a I<want>
1993 value, where I<need> is the amount of data that the file library needs
1994 to read, and I<want> is the amount of space available in the buffer
1995 maintained by these functions.
1996
1997 This means if you need to read from a stream that you don't know the
1998 length of, you can return I<need> bytes, taking the performance hit of
1999 possibly expensive callbacks (eg. back to perl code), or if you are
2000 reading from a stream where it doesn't matter if some data is lost, or
2001 if the total length of the stream is known, you can return I<want>
2002 bytes.
2003
2004 =cut 
2005 */
2006
2007 int
2008 i_gen_reader(i_gen_read_data *gci, char *buf, int length) {
2009   int total;
2010
2011   if (length < gci->length - gci->cpos) {
2012     /* simplest case */
2013     memcpy(buf, gci->buffer+gci->cpos, length);
2014     gci->cpos += length;
2015     return length;
2016   }
2017   
2018   total = 0;
2019   memcpy(buf, gci->buffer+gci->cpos, gci->length-gci->cpos);
2020   total  += gci->length - gci->cpos;
2021   length -= gci->length - gci->cpos;
2022   buf    += gci->length - gci->cpos;
2023   if (length < (int)sizeof(gci->buffer)) {
2024     int did_read;
2025     int copy_size;
2026     while (length
2027            && (did_read = (gci->cb)(gci->userdata, gci->buffer, length, 
2028                                     sizeof(gci->buffer))) > 0) {
2029       gci->cpos = 0;
2030       gci->length = did_read;
2031
2032       copy_size = i_min(length, gci->length);
2033       memcpy(buf, gci->buffer, copy_size);
2034       gci->cpos += copy_size;
2035       buf += copy_size;
2036       total += copy_size;
2037       length -= copy_size;
2038     }
2039   }
2040   else {
2041     /* just read the rest - too big for our buffer*/
2042     int did_read;
2043     while ((did_read = (gci->cb)(gci->userdata, buf, length, length)) > 0) {
2044       length -= did_read;
2045       total += did_read;
2046       buf += did_read;
2047     }
2048   }
2049   return total;
2050 }
2051
2052 /*
2053 =item i_gen_read_data_new(i_read_callback_t cb, char *userdata)
2054
2055 For use by callback file readers to initialize the reader buffer.
2056
2057 Allocates, initializes and returns the reader buffer.
2058
2059 See also L<image.c/free_gen_read_data> and L<image.c/i_gen_reader>.
2060
2061 =cut
2062 */
2063 i_gen_read_data *
2064 i_gen_read_data_new(i_read_callback_t cb, char *userdata) {
2065   i_gen_read_data *self = mymalloc(sizeof(i_gen_read_data));
2066   self->cb = cb;
2067   self->userdata = userdata;
2068   self->length = 0;
2069   self->cpos = 0;
2070
2071   return self;
2072 }
2073
2074 /*
2075 =item i_free_gen_read_data(i_gen_read_data *)
2076
2077 Cleans up.
2078
2079 =cut
2080 */
2081 void i_free_gen_read_data(i_gen_read_data *self) {
2082   myfree(self);
2083 }
2084
2085 /*
2086 =item i_gen_writer(i_gen_write_data *info, char const *data, int size)
2087
2088 Performs write buffering for a callback based file writer.
2089
2090 Failures are considered fatal, if a write fails then data will be
2091 dropped.
2092
2093 =cut
2094 */
2095 int 
2096 i_gen_writer(
2097 i_gen_write_data *self, 
2098 char const *data, 
2099 int size)
2100 {
2101   if (self->filledto && self->filledto+size > self->maxlength) {
2102     if (self->cb(self->userdata, self->buffer, self->filledto)) {
2103       self->filledto = 0;
2104     }
2105     else {
2106       self->filledto = 0;
2107       return 0;
2108     }
2109   }
2110   if (self->filledto+size <= self->maxlength) {
2111     /* just save it */
2112     memcpy(self->buffer+self->filledto, data, size);
2113     self->filledto += size;
2114     return 1;
2115   }
2116   /* doesn't fit - hand it off */
2117   return self->cb(self->userdata, data, size);
2118 }
2119
2120 /*
2121 =item i_gen_write_data_new(i_write_callback_t cb, char *userdata, int max_length)
2122
2123 Allocates and initializes the data structure used by i_gen_writer.
2124
2125 This should be released with L<image.c/i_free_gen_write_data>
2126
2127 =cut
2128 */
2129 i_gen_write_data *i_gen_write_data_new(i_write_callback_t cb, 
2130                                        char *userdata, int max_length)
2131 {
2132   i_gen_write_data *self = mymalloc(sizeof(i_gen_write_data));
2133   self->cb = cb;
2134   self->userdata = userdata;
2135   self->maxlength = i_min(max_length, sizeof(self->buffer));
2136   if (self->maxlength < 0)
2137     self->maxlength = sizeof(self->buffer);
2138   self->filledto = 0;
2139
2140   return self;
2141 }
2142
2143 /*
2144 =item i_free_gen_write_data(i_gen_write_data *info, int flush)
2145
2146 Cleans up the write buffer.
2147
2148 Will flush any left-over data if I<flush> is non-zero.
2149
2150 Returns non-zero if flush is zero or if info->cb() returns non-zero.
2151
2152 Return zero only if flush is non-zero and info->cb() returns zero.
2153 ie. if it fails.
2154
2155 =cut
2156 */
2157
2158 int i_free_gen_write_data(i_gen_write_data *info, int flush)
2159 {
2160   int result = !flush || 
2161     info->filledto == 0 ||
2162     info->cb(info->userdata, info->buffer, info->filledto);
2163   myfree(info);
2164
2165   return result;
2166 }
2167
2168 struct magic_entry {
2169   unsigned char *magic;
2170   size_t magic_size;
2171   char *name;
2172   unsigned char *mask;  
2173 };
2174
2175 static int
2176 test_magic(unsigned char *buffer, size_t length, struct magic_entry const *magic) {
2177   if (length < magic->magic_size)
2178     return 0;
2179   if (magic->mask) {
2180     int i;
2181     unsigned char *bufp = buffer, 
2182       *maskp = magic->mask, 
2183       *magicp = magic->magic;
2184
2185     for (i = 0; i < magic->magic_size; ++i) {
2186       int mask = *maskp == 'x' ? 0xFF : *maskp == ' ' ? 0 : *maskp;
2187       ++maskp;
2188
2189       if ((*bufp++ & mask) != (*magicp++ & mask)) 
2190         return 0;
2191     }
2192
2193     return 1;
2194   }
2195   else {
2196     return !memcmp(magic->magic, buffer, magic->magic_size);
2197   }
2198 }
2199
2200 /*
2201 =item i_test_format_probe(io_glue *data, int length)
2202
2203 Check the beginning of the supplied file for a 'magic number'
2204
2205 =cut
2206 */
2207
2208 #define FORMAT_ENTRY(magic, type) \
2209   { (unsigned char *)(magic ""), sizeof(magic)-1, type }
2210 #define FORMAT_ENTRY2(magic, type, mask) \
2211   { (unsigned char *)(magic ""), sizeof(magic)-1, type, (unsigned char *)(mask) }
2212
2213 const char *
2214 i_test_format_probe(io_glue *data, int length) {
2215   static const struct magic_entry formats[] = {
2216     FORMAT_ENTRY("\xFF\xD8", "jpeg"),
2217     FORMAT_ENTRY("GIF87a", "gif"),
2218     FORMAT_ENTRY("GIF89a", "gif"),
2219     FORMAT_ENTRY("MM\0*", "tiff"),
2220     FORMAT_ENTRY("II*\0", "tiff"),
2221     FORMAT_ENTRY("BM", "bmp"),
2222     FORMAT_ENTRY("\x89PNG\x0d\x0a\x1a\x0a", "png"),
2223     FORMAT_ENTRY("P1", "pnm"),
2224     FORMAT_ENTRY("P2", "pnm"),
2225     FORMAT_ENTRY("P3", "pnm"),
2226     FORMAT_ENTRY("P4", "pnm"),
2227     FORMAT_ENTRY("P5", "pnm"),
2228     FORMAT_ENTRY("P6", "pnm"),
2229     FORMAT_ENTRY("/* XPM", "xpm"),
2230     FORMAT_ENTRY("\x8aMNG", "mng"),
2231     FORMAT_ENTRY("\x8aJNG", "jng"),
2232     /* SGI RGB - with various possible parameters to avoid false positives
2233        on similar files 
2234        values are: 2 byte magic, rle flags (0 or 1), bytes/sample (1 or 2)
2235     */
2236     FORMAT_ENTRY("\x01\xDA\x00\x01", "sgi"),
2237     FORMAT_ENTRY("\x01\xDA\x00\x02", "sgi"),
2238     FORMAT_ENTRY("\x01\xDA\x01\x01", "sgi"),
2239     FORMAT_ENTRY("\x01\xDA\x01\x02", "sgi"),
2240     
2241     FORMAT_ENTRY2("FORM    ILBM", "ilbm", "xxxx    xxxx"),
2242
2243     /* different versions of PCX format 
2244        http://www.fileformat.info/format/pcx/
2245     */
2246     FORMAT_ENTRY("\x0A\x00\x01", "pcx"),
2247     FORMAT_ENTRY("\x0A\x02\x01", "pcx"),
2248     FORMAT_ENTRY("\x0A\x03\x01", "pcx"),
2249     FORMAT_ENTRY("\x0A\x04\x01", "pcx"),
2250     FORMAT_ENTRY("\x0A\x05\x01", "pcx"),
2251
2252     /* FITS - http://fits.gsfc.nasa.gov/ */
2253     FORMAT_ENTRY("SIMPLE  =", "fits"),
2254
2255     /* PSD - Photoshop */
2256     FORMAT_ENTRY("8BPS\x00\x01", "psd"),
2257     
2258     /* EPS - Encapsulated Postscript */
2259     /* only reading 18 chars, so we don't include the F in EPSF */
2260     FORMAT_ENTRY("%!PS-Adobe-2.0 EPS", "eps"),
2261
2262     /* Utah RLE */
2263     FORMAT_ENTRY("\x52\xCC", "utah"),
2264
2265     /* GZIP compressed, only matching deflate for now */
2266     FORMAT_ENTRY("\x1F\x8B\x08", "gzip"),
2267
2268     /* bzip2 compressed */
2269     FORMAT_ENTRY("BZh", "bzip2"),
2270   };
2271   static const struct magic_entry more_formats[] = {
2272     /* these were originally both listed as ico, but cur files can
2273        include hotspot information */
2274     FORMAT_ENTRY("\x00\x00\x01\x00", "ico"), /* Windows icon */
2275     FORMAT_ENTRY("\x00\x00\x02\x00", "cur"), /* Windows cursor */
2276     FORMAT_ENTRY2("\x00\x00\x00\x00\x00\x00\x00\x07", 
2277                   "xwd", "    xxxx"), /* X Windows Dump */
2278   };
2279
2280   unsigned int i;
2281   unsigned char head[18];
2282   ssize_t rc;
2283
2284   io_glue_commit_types(data);
2285   rc = data->readcb(data, head, 18);
2286   if (rc == -1) return NULL;
2287   data->seekcb(data, -rc, SEEK_CUR);
2288
2289   for(i=0; i<sizeof(formats)/sizeof(formats[0]); i++) { 
2290     struct magic_entry const *entry = formats + i;
2291
2292     if (test_magic(head, rc, entry)) 
2293       return entry->name;
2294   }
2295
2296   if ((rc == 18) &&
2297       tga_header_verify(head))
2298     return "tga";
2299
2300   for(i=0; i<sizeof(more_formats)/sizeof(more_formats[0]); i++) { 
2301     struct magic_entry const *entry = more_formats + i;
2302
2303     if (test_magic(head, rc, entry)) 
2304       return entry->name;
2305   }
2306
2307   return NULL;
2308 }
2309
2310 /*
2311 =item i_img_is_monochrome(img, &zero_is_white)
2312
2313 Tests an image to check it meets our monochrome tests.
2314
2315 The idea is that a file writer can use this to test where it should
2316 write the image in whatever bi-level format it uses, eg. pbm for pnm.
2317
2318 For performance of encoders we require monochrome images:
2319
2320 =over
2321
2322 =item *
2323
2324 be paletted
2325
2326 =item *
2327
2328 have a palette of two colors, containing only (0,0,0) and
2329 (255,255,255) in either order.
2330
2331 =back
2332
2333 zero_is_white is set to non-zero iff the first palette entry is white.
2334
2335 =cut
2336 */
2337
2338 int
2339 i_img_is_monochrome(i_img *im, int *zero_is_white) {
2340   if (im->type == i_palette_type
2341       && i_colorcount(im) == 2) {
2342     i_color colors[2];
2343     i_getcolors(im, 0, colors, 2);
2344     if (im->channels == 3) {
2345       if (colors[0].rgb.r == 255 && 
2346           colors[0].rgb.g == 255 &&
2347           colors[0].rgb.b == 255 &&
2348           colors[1].rgb.r == 0 &&
2349           colors[1].rgb.g == 0 &&
2350           colors[1].rgb.b == 0) {
2351         *zero_is_white = 1;
2352         return 1;
2353       }
2354       else if (colors[0].rgb.r == 0 && 
2355                colors[0].rgb.g == 0 &&
2356                colors[0].rgb.b == 0 &&
2357                colors[1].rgb.r == 255 &&
2358                colors[1].rgb.g == 255 &&
2359                colors[1].rgb.b == 255) {
2360         *zero_is_white = 0;
2361         return 1;
2362       }
2363     }
2364     else if (im->channels == 1) {
2365       if (colors[0].channel[0] == 255 &&
2366           colors[1].channel[0] == 0) {
2367         *zero_is_white = 1;
2368         return 1;
2369       }
2370       else if (colors[0].channel[0] == 0 &&
2371                colors[1].channel[0] == 255) {
2372         *zero_is_white = 0;
2373         return 1;         
2374       }
2375     }
2376   }
2377
2378   *zero_is_white = 0;
2379   return 0;
2380 }
2381
2382 /*
2383 =item i_get_file_background(im, &bg)
2384
2385 Retrieve the file write background color tag from the image.
2386
2387 If not present, returns black.
2388
2389 =cut
2390 */
2391
2392 void
2393 i_get_file_background(i_img *im, i_color *bg) {
2394   if (!i_tags_get_color(&im->tags, "i_background", 0, bg)) {
2395     /* black default */
2396     bg->channel[0] = bg->channel[1] = bg->channel[2] = 0;
2397   }
2398   /* always full alpha */
2399   bg->channel[3] = 255;
2400 }
2401
2402 /*
2403 =item i_get_file_backgroundf(im, &bg)
2404
2405 Retrieve the file write background color tag from the image as a
2406 floating point color.
2407
2408 Implemented in terms of i_get_file_background().
2409
2410 If not present, returns black.
2411
2412 =cut
2413 */
2414
2415 void
2416 i_get_file_backgroundf(i_img *im, i_fcolor *fbg) {
2417   i_color bg;
2418
2419   i_get_file_background(im, &bg);
2420   fbg->rgba.r = Sample8ToF(bg.rgba.r);
2421   fbg->rgba.g = Sample8ToF(bg.rgba.g);
2422   fbg->rgba.b = Sample8ToF(bg.rgba.b);
2423   fbg->rgba.a = 1.0;
2424 }
2425
2426 /*
2427 =back
2428
2429 =head1 AUTHOR
2430
2431 Arnar M. Hrafnkelsson <addi@umich.edu>
2432
2433 Tony Cook <tony@develop-help.com>
2434
2435 =head1 SEE ALSO
2436
2437 L<Imager>, L<gif.c>
2438
2439 =cut
2440 */