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