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