handle a slightly different warning from libtiff 4.x
[imager.git] / TIFF / imtiff.c
1 #include <tiffio.h>
2 #include <string.h>
3 #include "imtiff.h"
4 #include "imext.h"
5
6 /* needed to implement our substitute TIFFIsCODECConfigured */
7 #if TIFFLIB_VERSION < 20031121
8 static int TIFFIsCODECConfigured(uint16 scheme);
9 #endif
10
11 /*
12 =head1 NAME
13
14 tiff.c - implements reading and writing tiff files, uses io layer.
15
16 =head1 SYNOPSIS
17
18    io_glue *ig = io_new_fd( fd );
19    i_img *im   = i_readtiff_wiol(ig, -1); // no limit on how much is read
20    // or 
21    io_glue *ig = io_new_fd( fd );
22    return_code = i_writetiff_wiol(im, ig); 
23
24 =head1 DESCRIPTION
25
26 tiff.c implements the basic functions to read and write tiff files.
27 It uses the iolayer and needs either a seekable source or an entire
28 memory mapped buffer.
29
30 =head1 FUNCTION REFERENCE
31
32 Some of these functions are internal.
33
34 =over
35
36 =cut
37 */
38
39 #define byteswap_macro(x) \
40      ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |     \
41       (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
42
43 #define CLAMP8(x) ((x) < 0 ? 0 : (x) > 255 ? 255 : (x))
44 #define CLAMP16(x) ((x) < 0 ? 0 : (x) > 65535 ? 65535 : (x))
45
46 #define Sample16To8(num) ((num) / 257)
47
48 struct tag_name {
49   char *name;
50   uint32 tag;
51 };
52
53 static i_img *read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete);
54 static i_img *read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete);
55
56 static struct tag_name text_tag_names[] =
57 {
58   { "tiff_documentname", TIFFTAG_DOCUMENTNAME, },
59   { "tiff_imagedescription", TIFFTAG_IMAGEDESCRIPTION, },
60   { "tiff_make", TIFFTAG_MAKE, },
61   { "tiff_model", TIFFTAG_MODEL, },
62   { "tiff_pagename", TIFFTAG_PAGENAME, },
63   { "tiff_software", TIFFTAG_SOFTWARE, },
64   { "tiff_datetime", TIFFTAG_DATETIME, },
65   { "tiff_artist", TIFFTAG_ARTIST, },
66   { "tiff_hostcomputer", TIFFTAG_HOSTCOMPUTER, },
67 };
68
69 static struct tag_name 
70 compress_values[] =
71   {
72     { "none",     COMPRESSION_NONE },
73     { "ccittrle", COMPRESSION_CCITTRLE },
74     { "fax3",     COMPRESSION_CCITTFAX3 },
75     { "t4",       COMPRESSION_CCITTFAX3 },
76     { "fax4",     COMPRESSION_CCITTFAX4 },
77     { "t6",       COMPRESSION_CCITTFAX4 },
78     { "lzw",      COMPRESSION_LZW },
79     { "jpeg",     COMPRESSION_JPEG },
80     { "packbits", COMPRESSION_PACKBITS },
81     { "deflate",  COMPRESSION_ADOBE_DEFLATE },
82     { "zip",      COMPRESSION_ADOBE_DEFLATE },
83     { "oldzip",   COMPRESSION_DEFLATE },
84     { "ccittrlew", COMPRESSION_CCITTRLEW },
85   };
86
87 static const int compress_value_count = 
88   sizeof(compress_values) / sizeof(*compress_values);
89
90 static int 
91 myTIFFIsCODECConfigured(uint16 scheme);
92
93 typedef struct read_state_tag read_state_t;
94 /* the setup function creates the image object, allocates the line buffer */
95 typedef int (*read_setup_t)(read_state_t *state);
96
97 /* the putter writes the image data provided by the getter to the
98    image, x, y, width, height describe the target area of the image,
99    extras is the extra number of pixels stored for each scanline in
100    the raster buffer, (for tiles against the right side of the
101    image) */
102
103 typedef int (*read_putter_t)(read_state_t *state, int x, int y, int width, 
104                              int height, int extras);
105
106 /* reads from a tiled or strip image and calls the putter.
107    This may need a second type for handling non-contiguous images
108    at some point */
109 typedef int (*read_getter_t)(read_state_t *state, read_putter_t putter);
110
111 struct read_state_tag {
112   TIFF *tif;
113   i_img *img;
114   void *raster;
115   unsigned long pixels_read;
116   int allow_incomplete;
117   void *line_buf;
118   uint32 width, height;
119   uint16 bits_per_sample;
120   uint16 photometric;
121
122   /* the total number of channels (samples per pixel) */
123   int samples_per_pixel;
124
125   /* if non-zero, which channel is the alpha channel, typically 3 for rgb */
126   int alpha_chan;
127
128   /* whether or not to scale the color channels based on the alpha
129      channel.  TIFF has 2 types of alpha channel, if the alpha channel
130      we use is EXTRASAMPLE_ASSOCALPHA then the color data will need to
131      be scaled to match Imager's conventions */
132   int scale_alpha;
133 };
134
135 static int tile_contig_getter(read_state_t *state, read_putter_t putter);
136 static int strip_contig_getter(read_state_t *state, read_putter_t putter);
137
138 static int setup_paletted(read_state_t *state);
139 static int paletted_putter8(read_state_t *, int, int, int, int, int);
140 static int paletted_putter4(read_state_t *, int, int, int, int, int);
141
142 static int setup_16_rgb(read_state_t *state);
143 static int setup_16_grey(read_state_t *state);
144 static int putter_16(read_state_t *, int, int, int, int, int);
145
146 static int setup_8_rgb(read_state_t *state);
147 static int setup_8_grey(read_state_t *state);
148 static int putter_8(read_state_t *, int, int, int, int, int);
149
150 static int setup_32_rgb(read_state_t *state);
151 static int setup_32_grey(read_state_t *state);
152 static int putter_32(read_state_t *, int, int, int, int, int);
153
154 static int setup_bilevel(read_state_t *state);
155 static int putter_bilevel(read_state_t *, int, int, int, int, int);
156
157 static int setup_cmyk8(read_state_t *state);
158 static int putter_cmyk8(read_state_t *, int, int, int, int, int);
159
160 static int setup_cmyk16(read_state_t *state);
161 static int putter_cmyk16(read_state_t *, int, int, int, int, int);
162
163 static const int text_tag_count = 
164   sizeof(text_tag_names) / sizeof(*text_tag_names);
165
166 static void error_handler(char const *module, char const *fmt, va_list ap) {
167   mm_log((1, "tiff error fmt %s\n", fmt));
168   i_push_errorvf(0, fmt, ap);
169 }
170
171 #define WARN_BUFFER_LIMIT 10000
172 static char *warn_buffer = NULL;
173 static int warn_buffer_size = 0;
174
175 static void warn_handler(char const *module, char const *fmt, va_list ap) {
176   char buf[1000];
177
178   buf[0] = '\0';
179 #ifdef HAVE_SNPRINTF
180   vsnprintf(buf, sizeof(buf), fmt, ap);
181 #else
182   vsprintf(buf, fmt, ap);
183 #endif
184   mm_log((1, "tiff warning %s\n", buf));
185
186   if (!warn_buffer || strlen(warn_buffer)+strlen(buf)+2 > warn_buffer_size) {
187     int new_size = warn_buffer_size + strlen(buf) + 2;
188     char *old_buffer = warn_buffer;
189     if (new_size > WARN_BUFFER_LIMIT) {
190       new_size = WARN_BUFFER_LIMIT;
191     }
192     warn_buffer = myrealloc(warn_buffer, new_size);
193     if (!old_buffer) *warn_buffer = '\0';
194     warn_buffer_size = new_size;
195   }
196   if (strlen(warn_buffer)+strlen(buf)+2 <= warn_buffer_size) {
197     strcat(warn_buffer, buf);
198     strcat(warn_buffer, "\n");
199   }
200 }
201
202 static int save_tiff_tags(TIFF *tif, i_img *im);
203
204 static void 
205 pack_4bit_to(unsigned char *dest, const unsigned char *src, int count);
206
207
208 static toff_t sizeproc(thandle_t x) {
209         return 0;
210 }
211
212
213 /*
214 =item comp_seek(h, o, w)
215
216 Compatability for 64 bit systems like latest freebsd (internal)
217
218    h - tiff handle, cast an io_glue object
219    o - offset
220    w - whence
221
222 =cut
223 */
224
225 static
226 toff_t
227 comp_seek(thandle_t h, toff_t o, int w) {
228   io_glue *ig = (io_glue*)h;
229   return (toff_t) ig->seekcb(ig, o, w);
230 }
231
232 /*
233 =item comp_mmap(thandle_t, tdata_t*, toff_t*)
234
235 Dummy mmap stub.
236
237 This shouldn't ever be called but newer tifflibs want it anyway.
238
239 =cut
240 */
241
242 static 
243 int
244 comp_mmap(thandle_t h, tdata_t*p, toff_t*off) {
245   return -1;
246 }
247
248 /*
249 =item comp_munmap(thandle_t h, tdata_t p, toff_t off)
250
251 Dummy munmap stub.
252
253 This shouldn't ever be called but newer tifflibs want it anyway.
254
255 =cut
256 */
257
258 static void
259 comp_munmap(thandle_t h, tdata_t p, toff_t off) {
260   /* do nothing */
261 }
262
263 static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
264   i_img *im;
265   uint32 width, height;
266   uint16 samples_per_pixel;
267   int tiled, error;
268   float xres, yres;
269   uint16 resunit;
270   int gotXres, gotYres;
271   uint16 photometric;
272   uint16 bits_per_sample;
273   uint16 planar_config;
274   uint16 inkset;
275   uint16 compress;
276   int i;
277   read_state_t state;
278   read_setup_t setupf = NULL;
279   read_getter_t getterf = NULL;
280   read_putter_t putterf = NULL;
281
282   error = 0;
283
284   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
285   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
286   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
287   tiled = TIFFIsTiled(tif);
288   TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
289   TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
290   TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
291   TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
292
293   mm_log((1, "i_readtiff_wiol: width=%d, height=%d, channels=%d\n", width, height, samples_per_pixel));
294   mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
295   mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
296
297   /* yes, this if() is horrible */
298   if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8) {
299     setupf = setup_paletted;
300     if (bits_per_sample == 8)
301       putterf = paletted_putter8;
302     else if (bits_per_sample == 4)
303       putterf = paletted_putter4;
304     else
305       mm_log((1, "unsupported paletted bits_per_sample %d\n", bits_per_sample));
306   }
307   else if (bits_per_sample == 16 
308            && photometric == PHOTOMETRIC_RGB
309            && samples_per_pixel >= 3) {
310     setupf = setup_16_rgb;
311     putterf = putter_16;
312   }
313   else if (bits_per_sample == 16
314            && photometric == PHOTOMETRIC_MINISBLACK) {
315     setupf = setup_16_grey;
316     putterf = putter_16;
317   }
318   else if (bits_per_sample == 8
319            && photometric == PHOTOMETRIC_MINISBLACK) {
320     setupf = setup_8_grey;
321     putterf = putter_8;
322   }
323   else if (bits_per_sample == 8
324            && photometric == PHOTOMETRIC_RGB) {
325     setupf = setup_8_rgb;
326     putterf = putter_8;
327   }
328   else if (bits_per_sample == 32 
329            && photometric == PHOTOMETRIC_RGB
330            && samples_per_pixel >= 3) {
331     setupf = setup_32_rgb;
332     putterf = putter_32;
333   }
334   else if (bits_per_sample == 32
335            && photometric == PHOTOMETRIC_MINISBLACK) {
336     setupf = setup_32_grey;
337     putterf = putter_32;
338   }
339   else if (bits_per_sample == 1
340            && (photometric == PHOTOMETRIC_MINISBLACK
341                || photometric == PHOTOMETRIC_MINISWHITE)
342            && samples_per_pixel == 1) {
343     setupf = setup_bilevel;
344     putterf = putter_bilevel;
345   }
346   else if (bits_per_sample == 8
347            && photometric == PHOTOMETRIC_SEPARATED
348            && inkset == INKSET_CMYK
349            && samples_per_pixel >= 4) {
350     setupf = setup_cmyk8;
351     putterf = putter_cmyk8;
352   }
353   else if (bits_per_sample == 16
354            && photometric == PHOTOMETRIC_SEPARATED
355            && inkset == INKSET_CMYK
356            && samples_per_pixel >= 4) {
357     setupf = setup_cmyk16;
358     putterf = putter_cmyk16;
359   }
360   if (tiled) {
361     if (planar_config == PLANARCONFIG_CONTIG)
362       getterf = tile_contig_getter;
363   }
364   else {
365     if (planar_config == PLANARCONFIG_CONTIG)
366       getterf = strip_contig_getter;
367   }
368   if (setupf && getterf && putterf) {
369     unsigned long total_pixels = (unsigned long)width * height;
370     memset(&state, 0, sizeof(state));
371     state.tif = tif;
372     state.allow_incomplete = allow_incomplete;
373     state.width = width;
374     state.height = height;
375     state.bits_per_sample = bits_per_sample;
376     state.samples_per_pixel = samples_per_pixel;
377     state.photometric = photometric;
378
379     if (!setupf(&state))
380       return NULL;
381     if (!getterf(&state, putterf) || !state.pixels_read) {
382       if (state.img)
383         i_img_destroy(state.img);
384       if (state.raster)
385         _TIFFfree(state.raster);
386       if (state.line_buf)
387         myfree(state.line_buf);
388       
389       return NULL;
390     }
391
392     if (allow_incomplete && state.pixels_read < total_pixels) {
393       i_tags_setn(&(state.img->tags), "i_incomplete", 1);
394       i_tags_setn(&(state.img->tags), "i_lines_read", 
395                   state.pixels_read / width);
396     }
397     im = state.img;
398     
399     if (state.raster)
400       _TIFFfree(state.raster);
401     if (state.line_buf)
402       myfree(state.line_buf);
403   }
404   else {
405     if (tiled) {
406       im = read_one_rgb_tiled(tif, width, height, allow_incomplete);
407     }
408     else {
409       im = read_one_rgb_lines(tif, width, height, allow_incomplete);
410     }
411   }
412
413   if (!im)
414     return NULL;
415
416   /* general metadata */
417   i_tags_setn(&im->tags, "tiff_bitspersample", bits_per_sample);
418   i_tags_setn(&im->tags, "tiff_photometric", photometric);
419   TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
420     
421   /* resolution tags */
422   TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
423   gotXres = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
424   gotYres = TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
425   if (gotXres || gotYres) {
426     if (!gotXres)
427       xres = yres;
428     else if (!gotYres)
429       yres = xres;
430     i_tags_setn(&im->tags, "tiff_resolutionunit", resunit);
431     if (resunit == RESUNIT_CENTIMETER) {
432       /* from dots per cm to dpi */
433       xres *= 2.54;
434       yres *= 2.54;
435       i_tags_set(&im->tags, "tiff_resolutionunit_name", "centimeter", -1);
436     }
437     else if (resunit == RESUNIT_NONE) {
438       i_tags_setn(&im->tags, "i_aspect_only", 1);
439       i_tags_set(&im->tags, "tiff_resolutionunit_name", "none", -1);
440     }
441     else if (resunit == RESUNIT_INCH) {
442       i_tags_set(&im->tags, "tiff_resolutionunit_name", "inch", -1);
443     }
444     else {
445       i_tags_set(&im->tags, "tiff_resolutionunit_name", "unknown", -1);
446     }
447     /* tifflib doesn't seem to provide a way to get to the original rational
448        value of these, which would let me provide a more reasonable
449        precision. So make up a number. */
450     i_tags_set_float2(&im->tags, "i_xres", 0, xres, 6);
451     i_tags_set_float2(&im->tags, "i_yres", 0, yres, 6);
452   }
453
454   /* Text tags */
455   for (i = 0; i < text_tag_count; ++i) {
456     char *data;
457     if (TIFFGetField(tif, text_tag_names[i].tag, &data)) {
458       mm_log((1, "i_readtiff_wiol: tag %d has value %s\n", 
459               text_tag_names[i].tag, data));
460       i_tags_set(&im->tags, text_tag_names[i].name, data, -1);
461     }
462   }
463
464   i_tags_set(&im->tags, "i_format", "tiff", 4);
465   if (warn_buffer && *warn_buffer) {
466     i_tags_set(&im->tags, "i_warning", warn_buffer, -1);
467     *warn_buffer = '\0';
468   }
469
470   for (i = 0; i < compress_value_count; ++i) {
471     if (compress_values[i].tag == compress) {
472       i_tags_set(&im->tags, "tiff_compression", compress_values[i].name, -1);
473       break;
474     }
475   }
476   
477   return im;
478 }
479
480 /*
481 =item i_readtiff_wiol(im, ig)
482
483 =cut
484 */
485 i_img*
486 i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
487   TIFF* tif;
488   TIFFErrorHandler old_handler;
489   TIFFErrorHandler old_warn_handler;
490   i_img *im;
491
492   i_clear_error();
493   old_handler = TIFFSetErrorHandler(error_handler);
494   old_warn_handler = TIFFSetWarningHandler(warn_handler);
495   if (warn_buffer)
496     *warn_buffer = '\0';
497
498   /* Add code to get the filename info from the iolayer */
499   /* Also add code to check for mmapped code */
500
501   mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
502   
503   tif = TIFFClientOpen("(Iolayer)", 
504                        "rm", 
505                        (thandle_t) ig,
506                        (TIFFReadWriteProc) ig->readcb,
507                        (TIFFReadWriteProc) ig->writecb,
508                        (TIFFSeekProc) comp_seek,
509                        (TIFFCloseProc) ig->closecb,
510                        ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
511                        (TIFFMapFileProc) comp_mmap,
512                        (TIFFUnmapFileProc) comp_munmap);
513   
514   if (!tif) {
515     mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
516     i_push_error(0, "Error opening file");
517     TIFFSetErrorHandler(old_handler);
518     TIFFSetWarningHandler(old_warn_handler);
519     return NULL;
520   }
521
522   if (page != 0) {
523     if (!TIFFSetDirectory(tif, page)) {
524       mm_log((1, "i_readtiff_wiol: Unable to switch to directory %d\n", page));
525       i_push_errorf(0, "could not switch to page %d", page);
526       TIFFSetErrorHandler(old_handler);
527       TIFFSetWarningHandler(old_warn_handler);
528       TIFFClose(tif);
529       return NULL;
530     }
531   }
532
533   im = read_one_tiff(tif, allow_incomplete);
534
535   if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
536   TIFFSetErrorHandler(old_handler);
537   TIFFSetWarningHandler(old_warn_handler);
538   TIFFClose(tif);
539   return im;
540 }
541
542 /*
543 =item i_readtiff_multi_wiol(ig, *count)
544
545 Reads multiple images from a TIFF.
546
547 =cut
548 */
549 i_img**
550 i_readtiff_multi_wiol(io_glue *ig, int *count) {
551   TIFF* tif;
552   TIFFErrorHandler old_handler;
553   TIFFErrorHandler old_warn_handler;
554   i_img **results = NULL;
555   int result_alloc = 0;
556   int dirnum = 0;
557
558   i_clear_error();
559   old_handler = TIFFSetErrorHandler(error_handler);
560   old_warn_handler = TIFFSetWarningHandler(warn_handler);
561   if (warn_buffer)
562     *warn_buffer = '\0';
563
564   /* Add code to get the filename info from the iolayer */
565   /* Also add code to check for mmapped code */
566
567   mm_log((1, "i_readtiff_wiol(ig %p, length %d)\n", ig));
568   
569   tif = TIFFClientOpen("(Iolayer)", 
570                        "rm", 
571                        (thandle_t) ig,
572                        (TIFFReadWriteProc) ig->readcb,
573                        (TIFFReadWriteProc) ig->writecb,
574                        (TIFFSeekProc) comp_seek,
575                        (TIFFCloseProc) ig->closecb,
576                        ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
577                        (TIFFMapFileProc) comp_mmap,
578                        (TIFFUnmapFileProc) comp_munmap);
579   
580   if (!tif) {
581     mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
582     i_push_error(0, "Error opening file");
583     TIFFSetErrorHandler(old_handler);
584     TIFFSetWarningHandler(old_warn_handler);
585     return NULL;
586   }
587
588   *count = 0;
589   do {
590     i_img *im = read_one_tiff(tif, 0);
591     if (!im)
592       break;
593     if (++*count > result_alloc) {
594       if (result_alloc == 0) {
595         result_alloc = 5;
596         results = mymalloc(result_alloc * sizeof(i_img *));
597       }
598       else {
599         i_img **newresults;
600         result_alloc *= 2;
601         newresults = myrealloc(results, result_alloc * sizeof(i_img *));
602         if (!newresults) {
603           i_img_destroy(im); /* don't leak it */
604           break;
605         }
606         results = newresults;
607       }
608     }
609     results[*count-1] = im;
610   } while (TIFFSetDirectory(tif, ++dirnum));
611
612   TIFFSetWarningHandler(old_warn_handler);
613   TIFFSetErrorHandler(old_handler);
614   TIFFClose(tif);
615   return results;
616 }
617
618 undef_int
619 i_writetiff_low_faxable(TIFF *tif, i_img *im, int fine) {
620   uint32 width, height;
621   unsigned char *linebuf = NULL;
622   uint32 y;
623   int rc;
624   uint32 x;
625   uint32 rowsperstrip;
626   float vres = fine ? 196 : 98;
627   int luma_chan;
628
629   width    = im->xsize;
630   height   = im->ysize;
631
632   switch (im->channels) {
633   case 1:
634   case 2:
635     luma_chan = 0;
636     break;
637   case 3:
638   case 4:
639     luma_chan = 1;
640     break;
641   default:
642     /* This means a colorspace we don't handle yet */
643     mm_log((1, "i_writetiff_wiol_faxable: don't handle %d channel images.\n", im->channels));
644     return 0;
645   }
646
647   /* Add code to get the filename info from the iolayer */
648   /* Also add code to check for mmapped code */
649
650
651   mm_log((1, "i_writetiff_wiol_faxable: width=%d, height=%d, channels=%d\n", width, height, im->channels));
652   
653   if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH,      width)   )
654     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField width=%d failed\n", width)); return 0; }
655   if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH,     height)  )
656     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField length=%d failed\n", height)); return 0; }
657   if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
658     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField samplesperpixel=1 failed\n")); return 0; }
659   if (!TIFFSetField(tif, TIFFTAG_ORIENTATION,  ORIENTATION_TOPLEFT))
660     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Orientation=topleft\n")); return 0; }
661   if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,   1)        )
662     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField bitpersample=1\n")); return 0; }
663   if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG))
664     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField planarconfig\n")); return 0; }
665   if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
666     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField photometric=%d\n", PHOTOMETRIC_MINISBLACK)); return 0; }
667   if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, 3))
668     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField compression=3\n")); return 0; }
669
670   linebuf = (unsigned char *)_TIFFmalloc( TIFFScanlineSize(tif) );
671   
672   if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
673     mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField rowsperstrip=-1\n")); return 0; }
674
675   TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
676   TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rc);
677
678   mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField rowsperstrip=%d\n", rowsperstrip));
679   mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField scanlinesize=%d\n", TIFFScanlineSize(tif) ));
680   mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField planarconfig=%d == %d\n", rc, PLANARCONFIG_CONTIG));
681
682   if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)204))
683     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Xresolution=204\n")); return 0; }
684   if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, vres))
685     { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Yresolution=196\n")); return 0; }
686   if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)) {
687     mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField ResolutionUnit=%d\n", RESUNIT_INCH)); return 0; 
688   }
689
690   if (!save_tiff_tags(tif, im)) {
691     return 0;
692   }
693
694   for (y=0; y<height; y++) {
695     int linebufpos=0;
696     for(x=0; x<width; x+=8) { 
697       int bits;
698       int bitpos;
699       i_sample_t luma[8];
700       uint8 bitval = 128;
701       linebuf[linebufpos]=0;
702       bits = width-x; if(bits>8) bits=8;
703       i_gsamp(im, x, x+8, y, luma, &luma_chan, 1);
704       for(bitpos=0;bitpos<bits;bitpos++) {
705         linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
706         bitval >>= 1;
707       }
708       linebufpos++;
709     }
710     if (TIFFWriteScanline(tif, linebuf, y, 0) < 0) {
711       mm_log((1, "i_writetiff_wiol_faxable: TIFFWriteScanline failed.\n"));
712       break;
713     }
714   }
715   if (linebuf) _TIFFfree(linebuf);
716
717   return 1;
718 }
719
720 static uint16
721 find_compression(char const *name, uint16 *compress) {
722   int i;
723
724   for (i = 0; i < compress_value_count; ++i) {
725     if (strcmp(compress_values[i].name, name) == 0) {
726       *compress = (uint16)compress_values[i].tag;
727       return 1;
728     }
729   }
730   *compress = COMPRESSION_NONE;
731
732   return 0;
733 }
734
735 static uint16
736 get_compression(i_img *im, uint16 def_compress) {
737   int entry;
738   int value;
739
740   if (i_tags_find(&im->tags, "tiff_compression", 0, &entry)
741       && im->tags.tags[entry].data) {
742     uint16 compress;
743     if (find_compression(im->tags.tags[entry].data, &compress)
744         && myTIFFIsCODECConfigured(compress))
745       return compress;
746   }
747   if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
748     if ((uint16)value == value
749         && myTIFFIsCODECConfigured((uint16)value))
750       return (uint16)value;
751   }
752
753   return def_compress;
754 }
755
756 int
757 i_tiff_has_compression(const char *name) {
758   uint16 compress;
759
760   if (!find_compression(name, &compress))
761     return 0;
762
763   return myTIFFIsCODECConfigured(compress);
764 }
765
766 static int
767 set_base_tags(TIFF *tif, i_img *im, uint16 compress, uint16 photometric, 
768               uint16 bits_per_sample, uint16 samples_per_pixel) {
769   double xres, yres;
770   int resunit;
771   int got_xres, got_yres;
772   int aspect_only;
773
774   if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->xsize)) {
775     i_push_error(0, "write TIFF: setting width tag");
776     return 0;
777   }
778   if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
779     i_push_error(0, "write TIFF: setting length tag");
780     return 0;
781   }
782   if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
783     i_push_error(0, "write TIFF: setting orientation tag");
784     return 0;
785   }
786   if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
787     i_push_error(0, "write TIFF: setting planar configuration tag");
788     return 0;
789   }
790   if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
791     i_push_error(0, "write TIFF: setting photometric tag");
792     return 0;
793   }
794   if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
795     i_push_error(0, "write TIFF: setting compression tag");
796     return 0;
797   }
798   if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
799     i_push_error(0, "write TIFF: setting bits per sample tag");
800     return 0;
801   }
802   if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
803     i_push_error(0, "write TIFF: setting samples per pixel tag");
804     return 0;
805   }
806
807   got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
808   got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
809   if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
810     aspect_only = 0;
811   if (!i_tags_get_int(&im->tags, "tiff_resolutionunit", 0, &resunit))
812     resunit = RESUNIT_INCH;
813   if (got_xres || got_yres) {
814     if (!got_xres)
815       xres = yres;
816     else if (!got_yres)
817       yres = xres;
818     if (aspect_only) {
819       resunit = RESUNIT_NONE;
820     }
821     else {
822       if (resunit == RESUNIT_CENTIMETER) {
823         xres /= 2.54;
824         yres /= 2.54;
825       }
826       else {
827         resunit  = RESUNIT_INCH;
828       }
829     }
830     if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xres)) {
831       i_push_error(0, "write TIFF: setting xresolution tag");
832       return 0;
833     }
834     if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
835       i_push_error(0, "write TIFF: setting yresolution tag");
836       return 0;
837     }
838     if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
839       i_push_error(0, "write TIFF: setting resolutionunit tag");
840       return 0;
841     }
842   }
843
844   return 1;
845 }
846
847 static int 
848 write_one_bilevel(TIFF *tif, i_img *im, int zero_is_white) {
849   uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
850   uint16 photometric;
851   unsigned char *in_row;
852   unsigned char *out_row;
853   unsigned out_size;
854   int x, y;
855   int invert;
856
857   mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n", 
858           tif, im, zero_is_white));
859
860   /* ignore a silly choice */
861   if (compress == COMPRESSION_JPEG)
862     compress = COMPRESSION_PACKBITS;
863
864   switch (compress) {
865   case COMPRESSION_CCITTRLE:
866   case COMPRESSION_CCITTFAX3:
867   case COMPRESSION_CCITTFAX4:
868     /* natural fax photometric */
869     photometric = PHOTOMETRIC_MINISWHITE;
870     break;
871
872   default:
873     /* natural for most computer images */
874     photometric = PHOTOMETRIC_MINISBLACK;
875     break;
876   }
877
878   if (!set_base_tags(tif, im, compress, photometric, 1, 1))
879     return 0;
880
881   if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
882     i_push_error(0, "write TIFF: setting rows per strip tag");
883     return 0; 
884   }
885
886   out_size = TIFFScanlineSize(tif);
887   out_row = (unsigned char *)_TIFFmalloc( out_size );
888   in_row = mymalloc(im->xsize);
889
890   invert = (photometric == PHOTOMETRIC_MINISWHITE) != (zero_is_white != 0);
891
892   for (y = 0; y < im->ysize; ++y) {
893     int mask = 0x80;
894     unsigned char *outp = out_row;
895     memset(out_row, 0, out_size);
896     i_gpal(im, 0, im->xsize, y, in_row);
897     for (x = 0; x < im->xsize; ++x) {
898       if (invert ? !in_row[x] : in_row[x]) {
899         *outp |= mask;
900       }
901       mask >>= 1;
902       if (!mask) {
903         ++outp;
904         mask = 0x80;
905       }
906     }
907     if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
908       _TIFFfree(out_row);
909       myfree(in_row);
910       i_push_error(0, "write TIFF: write scan line failed");
911       return 0;
912     }
913   }
914
915   _TIFFfree(out_row);
916   myfree(in_row);
917
918   return 1;
919 }
920
921 static int
922 set_palette(TIFF *tif, i_img *im, int size) {
923   int count;
924   uint16 *colors;
925   uint16 *out[3];
926   i_color c;
927   int i, ch;
928   
929   colors = (uint16 *)_TIFFmalloc(sizeof(uint16) * 3 * size);
930   out[0] = colors;
931   out[1] = colors + size;
932   out[2] = colors + 2 * size;
933     
934   count = i_colorcount(im);
935   for (i = 0; i < count; ++i) {
936     i_getcolors(im, i, &c, 1);
937     for (ch = 0; ch < 3; ++ch)
938       out[ch][i] = c.channel[ch] * 257;
939   }
940   for (; i < size; ++i) {
941     for (ch = 0; ch < 3; ++ch)
942       out[ch][i] = 0;
943   }
944   if (!TIFFSetField(tif, TIFFTAG_COLORMAP, out[0], out[1], out[2])) {
945     _TIFFfree(colors);
946     i_push_error(0, "write TIFF: setting color map");
947     return 0;
948   }
949   _TIFFfree(colors);
950   
951   return 1;
952 }
953
954 static int
955 write_one_paletted8(TIFF *tif, i_img *im) {
956   uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
957   unsigned char *out_row;
958   unsigned out_size;
959   int y;
960
961   mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
962
963   /* ignore a silly choice */
964   if (compress == COMPRESSION_JPEG ||
965       compress == COMPRESSION_CCITTRLE ||
966       compress == COMPRESSION_CCITTFAX3 ||
967       compress == COMPRESSION_CCITTFAX4)
968     compress = COMPRESSION_PACKBITS;
969
970   if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
971     i_push_error(0, "write TIFF: setting rows per strip tag");
972     return 0; 
973   }
974
975   if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
976     return 0;
977
978   if (!set_palette(tif, im, 256))
979     return 0;
980
981   out_size = TIFFScanlineSize(tif);
982   out_row = (unsigned char *)_TIFFmalloc( out_size );
983
984   for (y = 0; y < im->ysize; ++y) {
985     i_gpal(im, 0, im->xsize, y, out_row);
986     if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
987       _TIFFfree(out_row);
988       i_push_error(0, "write TIFF: write scan line failed");
989       return 0;
990     }
991   }
992
993   _TIFFfree(out_row);
994
995   return 1;
996 }
997
998 static int
999 write_one_paletted4(TIFF *tif, i_img *im) {
1000   uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1001   unsigned char *in_row;
1002   unsigned char *out_row;
1003   unsigned out_size;
1004   int y;
1005
1006   mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
1007
1008   /* ignore a silly choice */
1009   if (compress == COMPRESSION_JPEG ||
1010       compress == COMPRESSION_CCITTRLE ||
1011       compress == COMPRESSION_CCITTFAX3 ||
1012       compress == COMPRESSION_CCITTFAX4)
1013     compress = COMPRESSION_PACKBITS;
1014
1015   if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 4, 1))
1016     return 0;
1017
1018   if (!set_palette(tif, im, 16))
1019     return 0;
1020
1021   if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1022     i_push_error(0, "write TIFF: setting rows per strip tag");
1023     return 0; 
1024   }
1025
1026   in_row = mymalloc(im->xsize);
1027   out_size = TIFFScanlineSize(tif);
1028   out_row = (unsigned char *)_TIFFmalloc( out_size );
1029
1030   for (y = 0; y < im->ysize; ++y) {
1031     i_gpal(im, 0, im->xsize, y, in_row);
1032     memset(out_row, 0, out_size);
1033     pack_4bit_to(out_row, in_row, im->xsize);
1034     if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1035       _TIFFfree(out_row);
1036       i_push_error(0, "write TIFF: write scan line failed");
1037       return 0;
1038     }
1039   }
1040
1041   myfree(in_row);
1042   _TIFFfree(out_row);
1043
1044   return 1;
1045 }
1046
1047 static int
1048 set_direct_tags(TIFF *tif, i_img *im, uint16 compress, 
1049                 uint16 bits_per_sample) {
1050   uint16 extras = EXTRASAMPLE_ASSOCALPHA;
1051   uint16 extra_count = im->channels == 2 || im->channels == 4;
1052   uint16 photometric = im->channels >= 3 ? 
1053     PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
1054
1055   if (!set_base_tags(tif, im, compress, photometric, bits_per_sample, 
1056                      im->channels)) {
1057     return 0;
1058   }
1059   
1060   if (extra_count) {
1061     if (!TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extra_count, &extras)) {
1062       i_push_error(0, "write TIFF: setting extra samples tag");
1063       return 0;
1064     }
1065   }
1066
1067   if (compress == COMPRESSION_JPEG) {
1068     int jpeg_quality;
1069     if (i_tags_get_int(&im->tags, "tiff_jpegquality", 0, &jpeg_quality)
1070         && jpeg_quality >= 0 && jpeg_quality <= 100) {
1071       if (!TIFFSetField(tif, TIFFTAG_JPEGQUALITY, jpeg_quality)) {
1072         i_push_error(0, "write TIFF: setting jpeg quality pseudo-tag");
1073         return 0;
1074       }
1075     }
1076   }
1077
1078   return 1;
1079 }
1080
1081 static int 
1082 write_one_32(TIFF *tif, i_img *im) {
1083   uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1084   unsigned *in_row;
1085   size_t out_size;
1086   uint32 *out_row;
1087   int y;
1088   size_t sample_count = im->xsize * im->channels;
1089   size_t sample_index;
1090     
1091   mm_log((1, "tiff - write_one_32(tif %p, im %p)\n", tif, im));
1092
1093   /* only 8 and 12 bit samples are supported by jpeg compression */
1094   if (compress == COMPRESSION_JPEG)
1095     compress = COMPRESSION_PACKBITS;
1096
1097   if (!set_direct_tags(tif, im, compress, 32))
1098     return 0;
1099
1100   in_row = mymalloc(sample_count * sizeof(unsigned));
1101   out_size = TIFFScanlineSize(tif);
1102   out_row = (uint32 *)_TIFFmalloc( out_size );
1103
1104   for (y = 0; y < im->ysize; ++y) {
1105     if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 32) <= 0) {
1106       i_push_error(0, "Cannot read 32-bit samples");
1107       return 0;
1108     }
1109     for (sample_index = 0; sample_index < sample_count; ++sample_index)
1110       out_row[sample_index] = in_row[sample_index];
1111     if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1112       myfree(in_row);
1113       _TIFFfree(out_row);
1114       i_push_error(0, "write TIFF: write scan line failed");
1115       return 0;
1116     }
1117   }
1118
1119   myfree(in_row);
1120   _TIFFfree(out_row);
1121   
1122   return 1;
1123 }
1124
1125 static int 
1126 write_one_16(TIFF *tif, i_img *im) {
1127   uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1128   unsigned *in_row;
1129   size_t out_size;
1130   uint16 *out_row;
1131   int y;
1132   size_t sample_count = im->xsize * im->channels;
1133   size_t sample_index;
1134     
1135   mm_log((1, "tiff - write_one_16(tif %p, im %p)\n", tif, im));
1136
1137   /* only 8 and 12 bit samples are supported by jpeg compression */
1138   if (compress == COMPRESSION_JPEG)
1139     compress = COMPRESSION_PACKBITS;
1140
1141   if (!set_direct_tags(tif, im, compress, 16))
1142     return 0;
1143
1144   in_row = mymalloc(sample_count * sizeof(unsigned));
1145   out_size = TIFFScanlineSize(tif);
1146   out_row = (uint16 *)_TIFFmalloc( out_size );
1147
1148   for (y = 0; y < im->ysize; ++y) {
1149     if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 16) <= 0) {
1150       i_push_error(0, "Cannot read 16-bit samples");
1151       return 0;
1152     }
1153     for (sample_index = 0; sample_index < sample_count; ++sample_index)
1154       out_row[sample_index] = in_row[sample_index];
1155     if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1156       myfree(in_row);
1157       _TIFFfree(out_row);
1158       i_push_error(0, "write TIFF: write scan line failed");
1159       return 0;
1160     }
1161   }
1162
1163   myfree(in_row);
1164   _TIFFfree(out_row);
1165   
1166   return 1;
1167 }
1168
1169 static int 
1170 write_one_8(TIFF *tif, i_img *im) {
1171   uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1172   size_t out_size;
1173   unsigned char *out_row;
1174   int y;
1175   size_t sample_count = im->xsize * im->channels;
1176     
1177   mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
1178
1179   if (!set_direct_tags(tif, im, compress, 8))
1180     return 0;
1181
1182   out_size = TIFFScanlineSize(tif);
1183   if (out_size < sample_count)
1184     out_size = sample_count;
1185   out_row = (unsigned char *)_TIFFmalloc( out_size );
1186
1187   for (y = 0; y < im->ysize; ++y) {
1188     if (i_gsamp(im, 0, im->xsize, y, out_row, NULL, im->channels) <= 0) {
1189       i_push_error(0, "Cannot read 8-bit samples");
1190       return 0;
1191     }
1192     if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1193       _TIFFfree(out_row);
1194       i_push_error(0, "write TIFF: write scan line failed");
1195       return 0;
1196     }
1197   }
1198   _TIFFfree(out_row);
1199   
1200   return 1;
1201 }
1202
1203 static int
1204 i_writetiff_low(TIFF *tif, i_img *im) {
1205   uint32 width, height;
1206   uint16 channels;
1207   int zero_is_white;
1208
1209   width    = im->xsize;
1210   height   = im->ysize;
1211   channels = im->channels;
1212
1213   mm_log((1, "i_writetiff_low: width=%d, height=%d, channels=%d, bits=%d\n", width, height, channels, im->bits));
1214   if (im->type == i_palette_type) {
1215     mm_log((1, "i_writetiff_low: paletted, colors=%d\n", i_colorcount(im)));
1216   }
1217   
1218   if (i_img_is_monochrome(im, &zero_is_white)) {
1219     if (!write_one_bilevel(tif, im, zero_is_white))
1220       return 0;
1221   }
1222   else if (im->type == i_palette_type) {
1223     if (i_colorcount(im) <= 16) {
1224       if (!write_one_paletted4(tif, im))
1225         return 0;
1226     }
1227     else {
1228       if (!write_one_paletted8(tif, im))
1229         return 0;
1230     }
1231   }
1232   else if (im->bits > 16) {
1233     if (!write_one_32(tif, im))
1234       return 0;
1235   }
1236   else if (im->bits > 8) {
1237     if (!write_one_16(tif, im))
1238       return 0;
1239   }
1240   else {
1241     if (!write_one_8(tif, im))
1242       return 0;
1243   }
1244
1245   if (!save_tiff_tags(tif, im))
1246     return 0;
1247
1248   return 1;
1249 }
1250
1251 /*
1252 =item i_writetiff_multi_wiol(ig, imgs, count, fine_mode)
1253
1254 Stores an image in the iolayer object.
1255
1256    ig - io_object that defines source to write to 
1257    imgs,count - the images to write
1258
1259 =cut 
1260 */
1261
1262 undef_int
1263 i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1264   TIFF* tif;
1265   TIFFErrorHandler old_handler;
1266   int i;
1267
1268   old_handler = TIFFSetErrorHandler(error_handler);
1269
1270   i_clear_error();
1271   mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n", 
1272           ig, imgs, count));
1273
1274   /* FIXME: Enable the mmap interface */
1275   
1276   tif = TIFFClientOpen("No name", 
1277                        "wm",
1278                        (thandle_t) ig, 
1279                        (TIFFReadWriteProc) ig->readcb,
1280                        (TIFFReadWriteProc) ig->writecb,
1281                        (TIFFSeekProc)      comp_seek,
1282                        (TIFFCloseProc)     ig->closecb, 
1283                        ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1284                        (TIFFMapFileProc)   comp_mmap,
1285                        (TIFFUnmapFileProc) comp_munmap);
1286   
1287
1288
1289   if (!tif) {
1290     mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n"));
1291     i_push_error(0, "Could not create TIFF object");
1292     TIFFSetErrorHandler(old_handler);
1293     return 0;
1294   }
1295
1296   for (i = 0; i < count; ++i) {
1297     if (!i_writetiff_low(tif, imgs[i])) {
1298       TIFFClose(tif);
1299       TIFFSetErrorHandler(old_handler);
1300       return 0;
1301     }
1302
1303     if (!TIFFWriteDirectory(tif)) {
1304       i_push_error(0, "Cannot write TIFF directory");
1305       TIFFClose(tif);
1306       TIFFSetErrorHandler(old_handler);
1307       return 0;
1308     }
1309   }
1310
1311   TIFFSetErrorHandler(old_handler);
1312   (void) TIFFClose(tif);
1313
1314   return 1;
1315 }
1316
1317 /*
1318 =item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1319
1320 Stores an image in the iolayer object.
1321
1322    ig - io_object that defines source to write to 
1323    imgs,count - the images to write
1324    fine_mode - select fine or normal mode fax images
1325
1326 =cut 
1327 */
1328
1329
1330 undef_int
1331 i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1332   TIFF* tif;
1333   int i;
1334   TIFFErrorHandler old_handler;
1335
1336   old_handler = TIFFSetErrorHandler(error_handler);
1337
1338   i_clear_error();
1339   mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n", 
1340           ig, imgs, count));
1341
1342   /* FIXME: Enable the mmap interface */
1343   
1344   tif = TIFFClientOpen("No name", 
1345                        "wm",
1346                        (thandle_t) ig, 
1347                        (TIFFReadWriteProc) ig->readcb,
1348                        (TIFFReadWriteProc) ig->writecb,
1349                        (TIFFSeekProc)      comp_seek,
1350                        (TIFFCloseProc)     ig->closecb, 
1351                        ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1352                        (TIFFMapFileProc)   comp_mmap,
1353                        (TIFFUnmapFileProc) comp_munmap);
1354   
1355
1356
1357   if (!tif) {
1358     mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
1359     i_push_error(0, "Could not create TIFF object");
1360     TIFFSetErrorHandler(old_handler);
1361     return 0;
1362   }
1363
1364   for (i = 0; i < count; ++i) {
1365     if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1366       TIFFClose(tif);
1367       TIFFSetErrorHandler(old_handler);
1368       return 0;
1369     }
1370
1371     if (!TIFFWriteDirectory(tif)) {
1372       i_push_error(0, "Cannot write TIFF directory");
1373       TIFFClose(tif);
1374       TIFFSetErrorHandler(old_handler);
1375       return 0;
1376     }
1377   }
1378
1379   (void) TIFFClose(tif);
1380   TIFFSetErrorHandler(old_handler);
1381
1382   return 1;
1383 }
1384
1385 /*
1386 =item i_writetiff_wiol(im, ig)
1387
1388 Stores an image in the iolayer object.
1389
1390    im - image object to write out
1391    ig - io_object that defines source to write to 
1392
1393 =cut 
1394 */
1395 undef_int
1396 i_writetiff_wiol(i_img *img, io_glue *ig) {
1397   TIFF* tif;
1398   TIFFErrorHandler old_handler;
1399
1400   old_handler = TIFFSetErrorHandler(error_handler);
1401
1402   i_clear_error();
1403   mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", img, ig));
1404
1405   /* FIXME: Enable the mmap interface */
1406
1407   tif = TIFFClientOpen("No name", 
1408                        "wm",
1409                        (thandle_t) ig, 
1410                        (TIFFReadWriteProc) ig->readcb,
1411                        (TIFFReadWriteProc) ig->writecb,
1412                        (TIFFSeekProc)      comp_seek,
1413                        (TIFFCloseProc)     ig->closecb, 
1414                        ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1415                        (TIFFMapFileProc)   comp_mmap,
1416                        (TIFFUnmapFileProc) comp_munmap);
1417   
1418
1419
1420   if (!tif) {
1421     mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1422     i_push_error(0, "Could not create TIFF object");
1423     TIFFSetErrorHandler(old_handler);
1424     return 0;
1425   }
1426
1427   if (!i_writetiff_low(tif, img)) {
1428     TIFFClose(tif);
1429     TIFFSetErrorHandler(old_handler);
1430     return 0;
1431   }
1432
1433   (void) TIFFClose(tif);
1434   TIFFSetErrorHandler(old_handler);
1435
1436   return 1;
1437 }
1438
1439
1440
1441 /*
1442 =item i_writetiff_wiol_faxable(i_img *, io_glue *)
1443
1444 Stores an image in the iolayer object in faxable tiff format.
1445
1446    im - image object to write out
1447    ig - io_object that defines source to write to 
1448
1449 Note, this may be rewritten to use to simply be a call to a
1450 lower-level function that gives more options for writing tiff at some
1451 point.
1452
1453 =cut
1454 */
1455
1456 undef_int
1457 i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1458   TIFF* tif;
1459   TIFFErrorHandler old_handler;
1460
1461   old_handler = TIFFSetErrorHandler(error_handler);
1462
1463   i_clear_error();
1464   mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", im, ig));
1465
1466   /* FIXME: Enable the mmap interface */
1467   
1468   tif = TIFFClientOpen("No name", 
1469                        "wm",
1470                        (thandle_t) ig, 
1471                        (TIFFReadWriteProc) ig->readcb,
1472                        (TIFFReadWriteProc) ig->writecb,
1473                        (TIFFSeekProc)      comp_seek,
1474                        (TIFFCloseProc)     ig->closecb, 
1475                        ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1476                        (TIFFMapFileProc)   comp_mmap,
1477                        (TIFFUnmapFileProc) comp_munmap);
1478   
1479
1480
1481   if (!tif) {
1482     mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1483     i_push_error(0, "Could not create TIFF object");
1484     TIFFSetErrorHandler(old_handler);
1485     return 0;
1486   }
1487
1488   if (!i_writetiff_low_faxable(tif, im, fine)) {
1489     TIFFClose(tif);
1490     TIFFSetErrorHandler(old_handler);
1491     return 0;
1492   }
1493
1494   (void) TIFFClose(tif);
1495   TIFFSetErrorHandler(old_handler);
1496
1497   return 1;
1498 }
1499
1500 static int save_tiff_tags(TIFF *tif, i_img *im) {
1501   int i;
1502  
1503   for (i = 0; i < text_tag_count; ++i) {
1504     int entry;
1505     if (i_tags_find(&im->tags, text_tag_names[i].name, 0, &entry)) {
1506       if (!TIFFSetField(tif, text_tag_names[i].tag, 
1507                        im->tags.tags[entry].data)) {
1508        i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1509        return 0;
1510       }
1511     }
1512   }
1513  
1514   return 1;
1515 }
1516
1517
1518 static void
1519 unpack_4bit_to(unsigned char *dest, const unsigned char *src, 
1520                int src_byte_count) {
1521   while (src_byte_count > 0) {
1522     *dest++ = *src >> 4;
1523     *dest++ = *src++ & 0xf;
1524     --src_byte_count;
1525   }
1526 }
1527
1528 static void pack_4bit_to(unsigned char *dest, const unsigned char *src, 
1529                          int pixel_count) {
1530   int i = 0;
1531   while (i < pixel_count) {
1532     if ((i & 1) == 0) {
1533       *dest = *src++ << 4;
1534     }
1535     else {
1536       *dest++ |= *src++;
1537     }
1538     ++i;
1539   }
1540 }
1541
1542 static i_img *
1543 make_rgb(TIFF *tif, int width, int height, int *alpha_chan) {
1544   uint16 photometric;
1545   uint16 channels, in_channels;
1546   uint16 extra_count;
1547   uint16 *extras;
1548
1549   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1550   TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1551
1552   switch (photometric) {
1553   case PHOTOMETRIC_SEPARATED:
1554     channels = 3;
1555     break;
1556   
1557   case PHOTOMETRIC_MINISWHITE:
1558   case PHOTOMETRIC_MINISBLACK:
1559     /* the TIFF RGBA functions expand single channel grey into RGB,
1560        so reduce it, we move the alpha channel into the right place 
1561        if needed */
1562     channels = 1;
1563     break;
1564
1565   default:
1566     channels = 3;
1567     break;
1568   }
1569   /* TIFF images can have more than one alpha channel, but Imager can't
1570      this ignores the possibility of 2 channel images with 2 alpha,
1571      but there's not much I can do about that */
1572   *alpha_chan = 0;
1573   if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)
1574       && extra_count) {
1575     *alpha_chan = channels++;
1576   }
1577
1578   return i_img_8_new(width, height, channels);
1579 }
1580
1581 static i_img *
1582 read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete) {
1583   i_img *im;
1584   uint32* raster = NULL;
1585   uint32 rowsperstrip, row;
1586   i_color *line_buf;
1587   int alpha_chan;
1588   int rc;
1589
1590   im = make_rgb(tif, width, height, &alpha_chan);
1591   if (!im)
1592     return NULL;
1593
1594   rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1595   mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
1596   
1597   if (rc != 1 || rowsperstrip==-1) {
1598     rowsperstrip = height;
1599   }
1600   
1601   raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
1602   if (!raster) {
1603     i_img_destroy(im);
1604     i_push_error(0, "No space for raster buffer");
1605     return NULL;
1606   }
1607
1608   line_buf = mymalloc(sizeof(i_color) * width);
1609   
1610   for( row = 0; row < height; row += rowsperstrip ) {
1611     uint32 newrows, i_row;
1612     
1613     if (!TIFFReadRGBAStrip(tif, row, raster)) {
1614       if (allow_incomplete) {
1615         i_tags_setn(&im->tags, "i_lines_read", row);
1616         i_tags_setn(&im->tags, "i_incomplete", 1);
1617         break;
1618       }
1619       else {
1620         i_push_error(0, "could not read TIFF image strip");
1621         _TIFFfree(raster);
1622         i_img_destroy(im);
1623         return NULL;
1624       }
1625     }
1626     
1627     newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
1628     mm_log((1, "newrows=%d\n", newrows));
1629     
1630     for( i_row = 0; i_row < newrows; i_row++ ) { 
1631       uint32 x;
1632       i_color *outp = line_buf;
1633
1634       for(x = 0; x<width; x++) {
1635         uint32 temp = raster[x+width*(newrows-i_row-1)];
1636         outp->rgba.r = TIFFGetR(temp);
1637         outp->rgba.g = TIFFGetG(temp);
1638         outp->rgba.b = TIFFGetB(temp);
1639
1640         if (alpha_chan) {
1641           /* the libtiff RGBA code expands greyscale into RGBA, so put the
1642              alpha in the right place and scale it */
1643           int ch;
1644           outp->channel[alpha_chan] = TIFFGetA(temp);
1645           if (outp->channel[alpha_chan]) {
1646             for (ch = 0; ch < alpha_chan; ++ch) {
1647               outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1648             }
1649           }
1650         }
1651
1652         outp++;
1653       }
1654       i_plin(im, 0, width, i_row+row, line_buf);
1655     }
1656   }
1657
1658   myfree(line_buf);
1659   _TIFFfree(raster);
1660   
1661   return im;
1662 }
1663
1664 /* adapted from libtiff 
1665
1666   libtiff's TIFFReadRGBATile succeeds even when asked to read an
1667   invalid tile, which means we have no way of knowing whether the data
1668   we received from it is valid or not.
1669
1670   So the caller here has set stoponerror to 1 so that
1671   TIFFRGBAImageGet() will fail.
1672
1673   read_one_rgb_tiled() then takes that into account for i_incomplete
1674   or failure.
1675  */
1676 static int
1677 myTIFFReadRGBATile(TIFFRGBAImage *img, uint32 col, uint32 row, uint32 * raster)
1678
1679 {
1680     int         ok;
1681     uint32      tile_xsize, tile_ysize;
1682     uint32      read_xsize, read_ysize;
1683     uint32      i_row;
1684
1685     /*
1686      * Verify that our request is legal - on a tile file, and on a
1687      * tile boundary.
1688      */
1689     
1690     TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILEWIDTH, &tile_xsize);
1691     TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILELENGTH, &tile_ysize);
1692     if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
1693     {
1694       i_push_errorf(0, "Row/col passed to myTIFFReadRGBATile() must be top"
1695                     "left corner of a tile.");
1696       return 0;
1697     }
1698
1699     /*
1700      * The TIFFRGBAImageGet() function doesn't allow us to get off the
1701      * edge of the image, even to fill an otherwise valid tile.  So we
1702      * figure out how much we can read, and fix up the tile buffer to
1703      * a full tile configuration afterwards.
1704      */
1705
1706     if( row + tile_ysize > img->height )
1707         read_ysize = img->height - row;
1708     else
1709         read_ysize = tile_ysize;
1710     
1711     if( col + tile_xsize > img->width )
1712         read_xsize = img->width - col;
1713     else
1714         read_xsize = tile_xsize;
1715
1716     /*
1717      * Read the chunk of imagery.
1718      */
1719     
1720     img->row_offset = row;
1721     img->col_offset = col;
1722
1723     ok = TIFFRGBAImageGet(img, raster, read_xsize, read_ysize );
1724         
1725     /*
1726      * If our read was incomplete we will need to fix up the tile by
1727      * shifting the data around as if a full tile of data is being returned.
1728      *
1729      * This is all the more complicated because the image is organized in
1730      * bottom to top format. 
1731      */
1732
1733     if( read_xsize == tile_xsize && read_ysize == tile_ysize )
1734         return( ok );
1735
1736     for( i_row = 0; i_row < read_ysize; i_row++ ) {
1737         memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
1738                  raster + (read_ysize - i_row - 1) * read_xsize,
1739                  read_xsize * sizeof(uint32) );
1740         _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
1741                      0, sizeof(uint32) * (tile_xsize - read_xsize) );
1742     }
1743
1744     for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
1745         _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
1746                      0, sizeof(uint32) * tile_xsize );
1747     }
1748
1749     return (ok);
1750 }
1751
1752 static i_img *
1753 read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete) {
1754   i_img *im;
1755   uint32* raster = NULL;
1756   int ok = 1;
1757   uint32 row, col;
1758   uint32 tile_width, tile_height;
1759   unsigned long pixels = 0;
1760   char  emsg[1024] = "";
1761   TIFFRGBAImage img;
1762   i_color *line;
1763   int alpha_chan;
1764   
1765   im = make_rgb(tif, width, height, &alpha_chan);
1766   if (!im)
1767     return NULL;
1768   
1769   if (!TIFFRGBAImageOK(tif, emsg) 
1770       || !TIFFRGBAImageBegin(&img, tif, 1, emsg)) {
1771     i_push_error(0, emsg);
1772     i_img_destroy(im);
1773     return( 0 );
1774   }
1775
1776   TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
1777   TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
1778   mm_log((1, "i_readtiff_wiol: tile_width=%d, tile_height=%d\n", tile_width, tile_height));
1779   
1780   raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
1781   if (!raster) {
1782     i_img_destroy(im);
1783     i_push_error(0, "No space for raster buffer");
1784     TIFFRGBAImageEnd(&img);
1785     return NULL;
1786   }
1787   line = mymalloc(tile_width * sizeof(i_color));
1788   
1789   for( row = 0; row < height; row += tile_height ) {
1790     for( col = 0; col < width; col += tile_width ) {
1791       
1792       /* Read the tile into an RGBA array */
1793       if (myTIFFReadRGBATile(&img, col, row, raster)) {
1794         uint32 i_row, x;
1795         uint32 newrows = (row+tile_height > height) ? height-row : tile_height;
1796         uint32 newcols = (col+tile_width  > width ) ? width-col  : tile_width;
1797
1798         mm_log((1, "i_readtiff_wiol: tile(%d, %d) newcols=%d newrows=%d\n", col, row, newcols, newrows));
1799         for( i_row = 0; i_row < newrows; i_row++ ) {
1800           i_color *outp = line;
1801           for(x = 0; x < newcols; x++) {
1802             uint32 temp = raster[x+tile_width*(tile_height-i_row-1)];
1803             outp->rgba.r = TIFFGetR(temp);
1804             outp->rgba.g = TIFFGetG(temp);
1805             outp->rgba.b = TIFFGetB(temp);
1806             outp->rgba.a = TIFFGetA(temp);
1807
1808             if (alpha_chan) {
1809               /* the libtiff RGBA code expands greyscale into RGBA, so put the
1810                  alpha in the right place and scale it */
1811               int ch;
1812               outp->channel[alpha_chan] = TIFFGetA(temp);
1813               
1814               if (outp->channel[alpha_chan]) {
1815                 for (ch = 0; ch < alpha_chan; ++ch) {
1816                   outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1817                 }
1818               }
1819             }
1820
1821             ++outp;
1822           }
1823           i_plin(im, col, col+newcols, row+i_row, line);
1824         }
1825         pixels += newrows * newcols;
1826       }
1827       else {
1828         if (allow_incomplete) {
1829           ok = 0;
1830         }
1831         else {
1832           goto error;
1833         }
1834       }
1835     }
1836   }
1837
1838   if (!ok) {
1839     if (pixels == 0) {
1840       i_push_error(0, "TIFF: No image data could be read from the image");
1841       goto error;
1842     }
1843
1844     /* incomplete image */
1845     i_tags_setn(&im->tags, "i_incomplete", 1);
1846     i_tags_setn(&im->tags, "i_lines_read", pixels / width);
1847   }
1848
1849   myfree(line);
1850   TIFFRGBAImageEnd(&img);
1851   _TIFFfree(raster);
1852   
1853   return im;
1854
1855  error:
1856   myfree(line);
1857   _TIFFfree(raster);
1858   TIFFRGBAImageEnd(&img);
1859   i_img_destroy(im);
1860   return NULL;
1861 }
1862
1863 char const *
1864 i_tiff_libversion(void) {
1865   return TIFFGetVersion();
1866 }
1867
1868 static int 
1869 setup_paletted(read_state_t *state) {
1870   uint16 *maps[3];
1871   int i, ch;
1872   int color_count = 1 << state->bits_per_sample;
1873
1874   state->img = i_img_pal_new(state->width, state->height, 3, 256);
1875   if (!state->img)
1876     return 0;
1877
1878   /* setup the color map */
1879   if (!TIFFGetField(state->tif, TIFFTAG_COLORMAP, maps+0, maps+1, maps+2)) {
1880     i_push_error(0, "Cannot get colormap for paletted image");
1881     i_img_destroy(state->img);
1882     return 0;
1883   }
1884   for (i = 0; i < color_count; ++i) {
1885     i_color c;
1886     for (ch = 0; ch < 3; ++ch) {
1887       c.channel[ch] = Sample16To8(maps[ch][i]);
1888     }
1889     i_addcolors(state->img, &c, 1);
1890   }
1891
1892   return 1;
1893 }
1894
1895 static int 
1896 tile_contig_getter(read_state_t *state, read_putter_t putter) {
1897   uint32 tile_width, tile_height;
1898   uint32 this_tile_height, this_tile_width;
1899   uint32 rows_left, cols_left;
1900   uint32 x, y;
1901
1902   state->raster = _TIFFmalloc(TIFFTileSize(state->tif));
1903   if (!state->raster) {
1904     i_push_error(0, "tiff: Out of memory allocating tile buffer");
1905     return 0;
1906   }
1907
1908   TIFFGetField(state->tif, TIFFTAG_TILEWIDTH, &tile_width);
1909   TIFFGetField(state->tif, TIFFTAG_TILELENGTH, &tile_height);
1910   rows_left = state->height;
1911   for (y = 0; y < state->height; y += this_tile_height) {
1912     this_tile_height = rows_left > tile_height ? tile_height : rows_left;
1913
1914     cols_left = state->width;
1915     for (x = 0; x < state->width; x += this_tile_width) {
1916       this_tile_width = cols_left > tile_width ? tile_width : cols_left;
1917
1918       if (TIFFReadTile(state->tif,
1919                        state->raster,
1920                        x, y, 0, 0) < 0) {
1921         if (!state->allow_incomplete) {
1922           return 0;
1923         }
1924       }
1925       else {
1926         putter(state, x, y, this_tile_width, this_tile_height, tile_width - this_tile_width);
1927       }
1928
1929       cols_left -= this_tile_width;
1930     }
1931
1932     rows_left -= this_tile_height;
1933   }
1934
1935   return 1;
1936 }
1937
1938 static int 
1939 strip_contig_getter(read_state_t *state, read_putter_t putter) {
1940   uint32 rows_per_strip;
1941   tsize_t strip_size = TIFFStripSize(state->tif);
1942   uint32 y, strip_rows, rows_left;
1943
1944   state->raster = _TIFFmalloc(strip_size);
1945   if (!state->raster) {
1946     i_push_error(0, "tiff: Out of memory allocating strip buffer");
1947     return 0;
1948   }
1949   
1950   TIFFGetFieldDefaulted(state->tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
1951   rows_left = state->height;
1952   for (y = 0; y < state->height; y += strip_rows) {
1953     strip_rows = rows_left > rows_per_strip ? rows_per_strip : rows_left;
1954     if (TIFFReadEncodedStrip(state->tif,
1955                              TIFFComputeStrip(state->tif, y, 0),
1956                              state->raster,
1957                              strip_size) < 0) {
1958       if (!state->allow_incomplete)
1959         return 0;
1960     }
1961     else {
1962       putter(state, 0, y, state->width, strip_rows, 0);
1963     }
1964     rows_left -= strip_rows;
1965   }
1966
1967   return 1;
1968 }
1969
1970 static int 
1971 paletted_putter8(read_state_t *state, int x, int y, int width, int height, int extras) {
1972   unsigned char *p = state->raster;
1973
1974   state->pixels_read += (unsigned long) width * height;
1975   while (height > 0) {
1976     i_ppal(state->img, x, x + width, y, p);
1977     p += width + extras;
1978     --height;
1979     ++y;
1980   }
1981
1982   return 1;
1983 }
1984
1985 static int 
1986 paletted_putter4(read_state_t *state, int x, int y, int width, int height, int extras) {
1987   uint32 img_line_size = (width + 1) / 2;
1988   uint32 skip_line_size = (width + extras + 1) / 2;
1989   unsigned char *p = state->raster;
1990
1991   if (!state->line_buf)
1992     state->line_buf = mymalloc(state->width);
1993
1994   state->pixels_read += (unsigned long) width * height;
1995   while (height > 0) {
1996     unpack_4bit_to(state->line_buf, p, img_line_size);
1997     i_ppal(state->img, x, x + width, y, state->line_buf);
1998     p += skip_line_size;
1999     --height;
2000     ++y;
2001   }
2002
2003   return 1;
2004 }
2005
2006 static void
2007 rgb_channels(read_state_t *state, int *out_channels) {
2008   uint16 extra_count;
2009   uint16 *extras;
2010   
2011   /* safe defaults */
2012   *out_channels = 3;
2013   state->alpha_chan = 0;
2014   state->scale_alpha = 0;
2015
2016   /* plain RGB */
2017   if (state->samples_per_pixel == 3)
2018     return;
2019  
2020   if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2021     mm_log((1, "tiff: samples != 3 but no extra samples tag\n"));
2022     return;
2023   }
2024
2025   if (!extra_count) {
2026     mm_log((1, "tiff: samples != 3 but no extra samples listed"));
2027     return;
2028   }
2029
2030   ++*out_channels;
2031   state->alpha_chan = 3;
2032   switch (*extras) {
2033   case EXTRASAMPLE_UNSPECIFIED:
2034   case EXTRASAMPLE_ASSOCALPHA:
2035     state->scale_alpha = 1;
2036     break;
2037
2038   case EXTRASAMPLE_UNASSALPHA:
2039     state->scale_alpha = 0;
2040     break;
2041
2042   default:
2043     mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2044             *extras));
2045     state->scale_alpha = 1;
2046     break;
2047   }
2048   mm_log((1, "tiff alpha channel %d scale %d\n", state->alpha_chan, state->scale_alpha));
2049 }
2050
2051 static void
2052 grey_channels(read_state_t *state, int *out_channels) {
2053   uint16 extra_count;
2054   uint16 *extras;
2055   
2056   /* safe defaults */
2057   *out_channels = 1;
2058   state->alpha_chan = 0;
2059   state->scale_alpha = 0;
2060
2061   /* plain grey */
2062   if (state->samples_per_pixel == 1)
2063     return;
2064  
2065   if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2066     mm_log((1, "tiff: samples != 1 but no extra samples tag\n"));
2067     return;
2068   }
2069
2070   if (!extra_count) {
2071     mm_log((1, "tiff: samples != 1 but no extra samples listed"));
2072     return;
2073   }
2074
2075   ++*out_channels;
2076   state->alpha_chan = 1;
2077   switch (*extras) {
2078   case EXTRASAMPLE_UNSPECIFIED:
2079   case EXTRASAMPLE_ASSOCALPHA:
2080     state->scale_alpha = 1;
2081     break;
2082
2083   case EXTRASAMPLE_UNASSALPHA:
2084     state->scale_alpha = 0;
2085     break;
2086
2087   default:
2088     mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2089             *extras));
2090     state->scale_alpha = 1;
2091     break;
2092   }
2093 }
2094
2095 static int
2096 setup_16_rgb(read_state_t *state) {
2097   int out_channels;
2098
2099   rgb_channels(state, &out_channels);
2100
2101   state->img = i_img_16_new(state->width, state->height, out_channels);
2102   if (!state->img)
2103     return 0;
2104   state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2105
2106   return 1;
2107 }
2108
2109 static int
2110 setup_16_grey(read_state_t *state) {
2111   int out_channels;
2112
2113   grey_channels(state, &out_channels);
2114
2115   state->img = i_img_16_new(state->width, state->height, out_channels);
2116   if (!state->img)
2117     return 0;
2118   state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2119
2120   return 1;
2121 }
2122
2123 static int 
2124 putter_16(read_state_t *state, int x, int y, int width, int height, 
2125           int row_extras) {
2126   uint16 *p = state->raster;
2127   int out_chan = state->img->channels;
2128
2129   state->pixels_read += (unsigned long) width * height;
2130   while (height > 0) {
2131     int i;
2132     int ch;
2133     unsigned *outp = state->line_buf;
2134
2135     for (i = 0; i < width; ++i) {
2136       for (ch = 0; ch < out_chan; ++ch) {
2137         outp[ch] = p[ch];
2138       }
2139       if (state->alpha_chan && state->scale_alpha && outp[state->alpha_chan]) {
2140         for (ch = 0; ch < state->alpha_chan; ++ch) {
2141           int result = 0.5 + (outp[ch] * 65535.0 / outp[state->alpha_chan]);
2142           outp[ch] = CLAMP16(result);
2143         }
2144       }
2145       p += state->samples_per_pixel;
2146       outp += out_chan;
2147     }
2148
2149     i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2150
2151     p += row_extras * state->samples_per_pixel;
2152     --height;
2153     ++y;
2154   }
2155
2156   return 1;
2157 }
2158
2159 static int
2160 setup_8_rgb(read_state_t *state) {
2161   int out_channels;
2162
2163   rgb_channels(state, &out_channels);
2164
2165   state->img = i_img_8_new(state->width, state->height, out_channels);
2166   if (!state->img)
2167     return 0;
2168   state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2169
2170   return 1;
2171 }
2172
2173 static int
2174 setup_8_grey(read_state_t *state) {
2175   int out_channels;
2176
2177   grey_channels(state, &out_channels);
2178
2179   state->img = i_img_8_new(state->width, state->height, out_channels);
2180   if (!state->img)
2181     return 0;
2182   state->line_buf = mymalloc(sizeof(i_color) * state->width * out_channels);
2183
2184   return 1;
2185 }
2186
2187 static int 
2188 putter_8(read_state_t *state, int x, int y, int width, int height, 
2189           int row_extras) {
2190   unsigned char *p = state->raster;
2191   int out_chan = state->img->channels;
2192
2193   state->pixels_read += (unsigned long) width * height;
2194   while (height > 0) {
2195     int i;
2196     int ch;
2197     i_color *outp = state->line_buf;
2198
2199     for (i = 0; i < width; ++i) {
2200       for (ch = 0; ch < out_chan; ++ch) {
2201         outp->channel[ch] = p[ch];
2202       }
2203       if (state->alpha_chan && state->scale_alpha 
2204           && outp->channel[state->alpha_chan]) {
2205         for (ch = 0; ch < state->alpha_chan; ++ch) {
2206           int result = (outp->channel[ch] * 255 + 127) / outp->channel[state->alpha_chan];
2207         
2208           outp->channel[ch] = CLAMP8(result);
2209         }
2210       }
2211       p += state->samples_per_pixel;
2212       outp++;
2213     }
2214
2215     i_plin(state->img, x, x + width, y, state->line_buf);
2216
2217     p += row_extras * state->samples_per_pixel;
2218     --height;
2219     ++y;
2220   }
2221
2222   return 1;
2223 }
2224
2225 static int
2226 setup_32_rgb(read_state_t *state) {
2227   int out_channels;
2228
2229   rgb_channels(state, &out_channels);
2230
2231   state->img = i_img_double_new(state->width, state->height, out_channels);
2232   if (!state->img)
2233     return 0;
2234   state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2235
2236   return 1;
2237 }
2238
2239 static int
2240 setup_32_grey(read_state_t *state) {
2241   int out_channels;
2242
2243   grey_channels(state, &out_channels);
2244
2245   state->img = i_img_double_new(state->width, state->height, out_channels);
2246   if (!state->img)
2247     return 0;
2248   state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2249
2250   return 1;
2251 }
2252
2253 static int 
2254 putter_32(read_state_t *state, int x, int y, int width, int height, 
2255           int row_extras) {
2256   uint32 *p = state->raster;
2257   int out_chan = state->img->channels;
2258
2259   state->pixels_read += (unsigned long) width * height;
2260   while (height > 0) {
2261     int i;
2262     int ch;
2263     i_fcolor *outp = state->line_buf;
2264
2265     for (i = 0; i < width; ++i) {
2266       for (ch = 0; ch < out_chan; ++ch) {
2267         outp->channel[ch] = p[ch] / 4294967295.0;
2268       }
2269       if (state->alpha_chan && state->scale_alpha && outp->channel[state->alpha_chan]) {
2270         for (ch = 0; ch < state->alpha_chan; ++ch)
2271           outp->channel[ch] /= outp->channel[state->alpha_chan];
2272       }
2273       p += state->samples_per_pixel;
2274       outp++;
2275     }
2276
2277     i_plinf(state->img, x, x + width, y, state->line_buf);
2278
2279     p += row_extras * state->samples_per_pixel;
2280     --height;
2281     ++y;
2282   }
2283
2284   return 1;
2285 }
2286
2287 static int
2288 setup_bilevel(read_state_t *state) {
2289   i_color black, white;
2290   state->img = i_img_pal_new(state->width, state->height, 1, 256);
2291   if (!state->img)
2292     return 0;
2293   black.channel[0] = black.channel[1] = black.channel[2] = 
2294     black.channel[3] = 0;
2295   white.channel[0] = white.channel[1] = white.channel[2] = 
2296     white.channel[3] = 255;
2297   if (state->photometric == PHOTOMETRIC_MINISBLACK) {
2298     i_addcolors(state->img, &black, 1);
2299     i_addcolors(state->img, &white, 1);
2300   }
2301   else {
2302     i_addcolors(state->img, &white, 1);
2303     i_addcolors(state->img, &black, 1);
2304   }
2305   state->line_buf = mymalloc(state->width);
2306
2307   return 1;
2308 }
2309
2310 static int 
2311 putter_bilevel(read_state_t *state, int x, int y, int width, int height, 
2312                int row_extras) {
2313   unsigned char *line_in = state->raster;
2314   size_t line_size = (width + row_extras + 7) / 8;
2315   
2316   /* tifflib returns the bits in MSB2LSB order even when the file is
2317      in LSB2MSB, so we only need to handle MSB2LSB */
2318   state->pixels_read += (unsigned long) width * height;
2319   while (height > 0) {
2320     int i;
2321     unsigned char *outp = state->line_buf;
2322     unsigned char *inp = line_in;
2323     unsigned mask = 0x80;
2324
2325     for (i = 0; i < width; ++i) {
2326       *outp++ = *inp & mask ? 1 : 0;
2327       mask >>= 1;
2328       if (!mask) {
2329         ++inp;
2330         mask = 0x80;
2331       }
2332     }
2333
2334     i_ppal(state->img, x, x + width, y, state->line_buf);
2335
2336     line_in += line_size;
2337     --height;
2338     ++y;
2339   }
2340
2341   return 1;
2342 }
2343
2344 static void
2345 cmyk_channels(read_state_t *state, int *out_channels) {
2346   uint16 extra_count;
2347   uint16 *extras;
2348   
2349   /* safe defaults */
2350   *out_channels = 3;
2351   state->alpha_chan = 0;
2352   state->scale_alpha = 0;
2353
2354   /* plain CMYK */
2355   if (state->samples_per_pixel == 4)
2356     return;
2357  
2358   if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2359     mm_log((1, "tiff: CMYK samples != 4 but no extra samples tag\n"));
2360     return;
2361   }
2362
2363   if (!extra_count) {
2364     mm_log((1, "tiff: CMYK samples != 4 but no extra samples listed"));
2365     return;
2366   }
2367
2368   ++*out_channels;
2369   state->alpha_chan = 4;
2370   switch (*extras) {
2371   case EXTRASAMPLE_UNSPECIFIED:
2372   case EXTRASAMPLE_ASSOCALPHA:
2373     state->scale_alpha = 1;
2374     break;
2375
2376   case EXTRASAMPLE_UNASSALPHA:
2377     state->scale_alpha = 0;
2378     break;
2379
2380   default:
2381     mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2382             *extras));
2383     state->scale_alpha = 1;
2384     break;
2385   }
2386 }
2387
2388 static int
2389 setup_cmyk8(read_state_t *state) {
2390   int channels;
2391
2392   cmyk_channels(state, &channels);
2393   state->img = i_img_8_new(state->width, state->height, channels);
2394
2395   state->line_buf = mymalloc(sizeof(i_color) * state->width);
2396
2397   return 1;
2398 }
2399
2400 static int 
2401 putter_cmyk8(read_state_t *state, int x, int y, int width, int height, 
2402                int row_extras) {
2403   unsigned char *p = state->raster;
2404
2405   state->pixels_read += (unsigned long) width * height;
2406   while (height > 0) {
2407     int i;
2408     int ch;
2409     i_color *outp = state->line_buf;
2410
2411     for (i = 0; i < width; ++i) {
2412       unsigned char c, m, y, k;
2413       c = p[0];
2414       m = p[1];
2415       y = p[2];
2416       k = 255 - p[3];
2417       outp->rgba.r = (k * (255 - c)) / 255;
2418       outp->rgba.g = (k * (255 - m)) / 255;
2419       outp->rgba.b = (k * (255 - y)) / 255;
2420       if (state->alpha_chan) {
2421         outp->rgba.a = p[state->alpha_chan];
2422         if (state->scale_alpha 
2423             && outp->rgba.a) {
2424           for (ch = 0; ch < 3; ++ch) {
2425             int result = (outp->channel[ch] * 255 + 127) / outp->rgba.a;
2426             outp->channel[ch] = CLAMP8(result);
2427           }
2428         }
2429       }
2430       p += state->samples_per_pixel;
2431       outp++;
2432     }
2433
2434     i_plin(state->img, x, x + width, y, state->line_buf);
2435
2436     p += row_extras * state->samples_per_pixel;
2437     --height;
2438     ++y;
2439   }
2440
2441   return 1;
2442 }
2443
2444 static int
2445 setup_cmyk16(read_state_t *state) {
2446   int channels;
2447
2448   cmyk_channels(state, &channels);
2449   state->img = i_img_16_new(state->width, state->height, channels);
2450
2451   state->line_buf = mymalloc(sizeof(unsigned) * state->width * channels);
2452
2453   return 1;
2454 }
2455
2456 static int 
2457 putter_cmyk16(read_state_t *state, int x, int y, int width, int height, 
2458                int row_extras) {
2459   uint16 *p = state->raster;
2460   int out_chan = state->img->channels;
2461
2462   mm_log((4, "putter_cmyk16(%p, %d, %d, %d, %d, %d)\n", x, y, width, height, row_extras));
2463
2464   state->pixels_read += (unsigned long) width * height;
2465   while (height > 0) {
2466     int i;
2467     int ch;
2468     unsigned *outp = state->line_buf;
2469
2470     for (i = 0; i < width; ++i) {
2471       unsigned c, m, y, k;
2472       c = p[0];
2473       m = p[1];
2474       y = p[2];
2475       k = 65535 - p[3];
2476       outp[0] = (k * (65535U - c)) / 65535U;
2477       outp[1] = (k * (65535U - m)) / 65535U;
2478       outp[2] = (k * (65535U - y)) / 65535U;
2479       if (state->alpha_chan) {
2480         outp[3] = p[state->alpha_chan];
2481         if (state->scale_alpha 
2482             && outp[3]) {
2483           for (ch = 0; ch < 3; ++ch) {
2484             int result = (outp[ch] * 65535 + 32767) / outp[3];
2485             outp[3] = CLAMP16(result);
2486           }
2487         }
2488       }
2489       p += state->samples_per_pixel;
2490       outp += out_chan;
2491     }
2492
2493     i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2494
2495     p += row_extras * state->samples_per_pixel;
2496     --height;
2497     ++y;
2498   }
2499
2500   return 1;
2501 }
2502
2503 /*
2504
2505   Older versions of tifflib we support don't define this, so define it
2506   ourselves.
2507
2508   If you want this detection to do anything useful, use a newer
2509   release of tifflib.
2510
2511  */
2512 #if TIFFLIB_VERSION < 20031121
2513
2514 int 
2515 TIFFIsCODECConfigured(uint16 scheme) {
2516   switch (scheme) {
2517     /* these schemes are all shipped with tifflib */
2518  case COMPRESSION_NONE:
2519  case COMPRESSION_PACKBITS:
2520  case COMPRESSION_CCITTRLE:
2521  case COMPRESSION_CCITTRLEW:
2522  case COMPRESSION_CCITTFAX3:
2523  case COMPRESSION_CCITTFAX4:
2524     return 1;
2525
2526     /* these require external library support */
2527   default:
2528  case COMPRESSION_JPEG:
2529  case COMPRESSION_LZW:
2530  case COMPRESSION_DEFLATE:
2531  case COMPRESSION_ADOBE_DEFLATE:
2532     return 0;
2533   }
2534 }
2535
2536 #endif
2537
2538 static int 
2539 myTIFFIsCODECConfigured(uint16 scheme) {
2540 #if TIFFLIB_VERSION < 20040724
2541   if (scheme == COMPRESSION_LZW)
2542     return 0;
2543 #endif
2544
2545   return TIFFIsCODECConfigured(scheme);
2546 }
2547
2548 /*
2549 =back
2550
2551 =head1 AUTHOR
2552
2553 Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tony@imager.perl.org>
2554
2555 =head1 SEE ALSO
2556
2557 Imager(3)
2558
2559 =cut
2560 */