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