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