correct the type of the im_decode_exif() data parameter
[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
05c9b356
TC
90static struct tag_name
91sample_format_values[] =
92 {
98747309
TC
93 { "uint", SAMPLEFORMAT_UINT },
94 { "int", SAMPLEFORMAT_INT },
95 { "ieeefp", SAMPLEFORMAT_IEEEFP },
96 { "undefined", SAMPLEFORMAT_VOID },
05c9b356
TC
97 };
98
99static const int sample_format_value_count =
100 sizeof(sample_format_values) / sizeof(*sample_format_values);
101
f8d72f20
TC
102static int
103myTIFFIsCODECConfigured(uint16 scheme);
104
bd8052a6
TC
105typedef struct read_state_tag read_state_t;
106/* the setup function creates the image object, allocates the line buffer */
107typedef 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
8d14daab
TC
115typedef 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);
bd8052a6
TC
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 */
121typedef int (*read_getter_t)(read_state_t *state, read_putter_t putter);
122
123struct read_state_tag {
124 TIFF *tif;
125 i_img *img;
126 void *raster;
8d14daab 127 i_img_dim pixels_read;
bd8052a6
TC
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;
05c9b356
TC
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;
bd8052a6
TC
153};
154
155static int tile_contig_getter(read_state_t *state, read_putter_t putter);
156static int strip_contig_getter(read_state_t *state, read_putter_t putter);
157
158static int setup_paletted(read_state_t *state);
8d14daab
TC
159static int paletted_putter8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
160static int paletted_putter4(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
bd8052a6
TC
161
162static int setup_16_rgb(read_state_t *state);
163static int setup_16_grey(read_state_t *state);
8d14daab 164static int putter_16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
bd8052a6
TC
165
166static int setup_8_rgb(read_state_t *state);
167static int setup_8_grey(read_state_t *state);
8d14daab 168static int putter_8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
bd8052a6
TC
169
170static int setup_32_rgb(read_state_t *state);
171static int setup_32_grey(read_state_t *state);
8d14daab 172static int putter_32(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
bd8052a6
TC
173
174static int setup_bilevel(read_state_t *state);
8d14daab 175static int putter_bilevel(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
bd8052a6
TC
176
177static int setup_cmyk8(read_state_t *state);
8d14daab 178static int putter_cmyk8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
bd8052a6
TC
179
180static int setup_cmyk16(read_state_t *state);
8d14daab 181static int putter_cmyk16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
6b7197d0
TC
182static void
183rgb_channels(read_state_t *state, int *out_channels);
184static void
185grey_channels(read_state_t *state, int *out_channels);
186static void
187cmyk_channels(read_state_t *state, int *out_channels);
188static void
189fallback_rgb_channels(TIFF *tif, i_img_dim width, i_img_dim height, int *channels, int *alpha_chan);
bd8052a6 190
fd9a31d2
TC
191static const int text_tag_count =
192 sizeof(text_tag_names) / sizeof(*text_tag_names);
5c829fcf 193
60715047
TC
194#if TIFFLIB_VERSION >= 20051230
195#define USE_EXT_WARN_HANDLER
196#endif
197
198#define TIFFIO_MAGIC 0xC6A340CC
199
5bb828f1 200static void error_handler(char const *module, char const *fmt, va_list ap) {
bd8052a6 201 mm_log((1, "tiff error fmt %s\n", fmt));
5bb828f1
TC
202 i_push_errorvf(0, fmt, ap);
203}
204
60715047
TC
205typedef 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
214static void
215tiffio_context_init(tiffio_context_t *c, io_glue *ig);
216static void
217tiffio_context_final(tiffio_context_t *c);
218
ffeb4a67 219#define WARN_BUFFER_LIMIT 10000
60715047
TC
220
221#ifdef USE_EXT_WARN_HANDLER
222
223static void
224warn_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
ffeb4a67
TC
257static char *warn_buffer = NULL;
258static int warn_buffer_size = 0;
259
be371490 260static void warn_handler(char const *module, char const *fmt, va_list ap) {
ffeb4a67
TC
261 char buf[1000];
262
263 buf[0] = '\0';
86c8d19a 264#ifdef IMAGER_VSNPRINTF
ffeb4a67
TC
265 vsnprintf(buf, sizeof(buf), fmt, ap);
266#else
267 vsprintf(buf, fmt, ap);
268#endif
bd8052a6
TC
269 mm_log((1, "tiff warning %s\n", buf));
270
ffeb4a67
TC
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 }
be371490
TC
285}
286
60715047
TC
287#endif
288
33ca1a7e
TC
289static i_mutex_t mutex;
290
291void
292i_tiff_init(void) {
293 mutex = i_mutex_new();
294}
295
5bb828f1
TC
296static int save_tiff_tags(TIFF *tif, i_img *im);
297
bd8052a6 298static void
8d14daab 299pack_4bit_to(unsigned char *dest, const unsigned char *src, i_img_dim count);
f62b2d84 300
caa833d5
AMH
301
302static toff_t sizeproc(thandle_t x) {
303 return 0;
304}
305
306
02d1d628
AMH
307/*
308=item comp_seek(h, o, w)
309
310Compatability 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
319static
320toff_t
321comp_seek(thandle_t h, toff_t o, int w) {
60715047 322 io_glue *ig = ((tiffio_context_t *)h)->ig;
6d5c85a2 323 return (toff_t) i_io_seek(ig, o, w);
02d1d628
AMH
324}
325
e18f39b3
TC
326/*
327=item comp_mmap(thandle_t, tdata_t*, toff_t*)
328
329Dummy mmap stub.
330
331This shouldn't ever be called but newer tifflibs want it anyway.
332
333=cut
334*/
335
336static
337int
338comp_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
345Dummy munmap stub.
346
347This shouldn't ever be called but newer tifflibs want it anyway.
348
349=cut
350*/
351
352static void
353comp_munmap(thandle_t h, tdata_t p, toff_t off) {
354 /* do nothing */
355}
356
6d5c85a2
TC
357static tsize_t
358comp_read(thandle_t h, tdata_t p, tsize_t size) {
60715047 359 return i_io_read(((tiffio_context_t *)h)->ig, p, size);
6d5c85a2
TC
360}
361
362static tsize_t
363comp_write(thandle_t h, tdata_t p, tsize_t size) {
60715047 364 return i_io_write(((tiffio_context_t *)h)->ig, p, size);
6d5c85a2
TC
365}
366
367static int
368comp_close(thandle_t h) {
60715047 369 return i_io_close(((tiffio_context_t *)h)->ig);
6d5c85a2
TC
370}
371
d87dc9a4 372static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
02d1d628
AMH
373 i_img *im;
374 uint32 width, height;
bd8052a6 375 uint16 samples_per_pixel;
98747309 376 int tiled;
faa9b3e7
TC
377 float xres, yres;
378 uint16 resunit;
379 int gotXres, gotYres;
fd9a31d2 380 uint16 photometric;
5bb828f1 381 uint16 bits_per_sample;
bd8052a6
TC
382 uint16 planar_config;
383 uint16 inkset;
384 uint16 compress;
05c9b356 385 uint16 sample_format;
fd9a31d2 386 int i;
bd8052a6
TC
387 read_state_t state;
388 read_setup_t setupf = NULL;
389 read_getter_t getterf = NULL;
390 read_putter_t putterf = NULL;
6b7197d0
TC
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;
05c9b356 394 int samples_integral;
02d1d628 395
02d1d628
AMH
396 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
397 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
bd8052a6 398 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
02d1d628 399 tiled = TIFFIsTiled(tif);
5bb828f1
TC
400 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
401 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
bd8052a6
TC
402 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
403 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
02d1d628 404
05c9b356
TC
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
bd8052a6 412 mm_log((1, "i_readtiff_wiol: width=%d, height=%d, channels=%d\n", width, height, samples_per_pixel));
02d1d628
AMH
413 mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
414 mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
faa9b3e7 415
6b7197d0
TC
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;
05c9b356
TC
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 */
6b7197d0 431
bd8052a6 432 /* yes, this if() is horrible */
05c9b356
TC
433 if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8
434 && samples_integral) {
bd8052a6
TC
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));
6b7197d0
TC
442
443 sample_size = sizeof(i_sample_t);
444 channels = 1;
a50608d2 445 }
bd8052a6
TC
446 else if (bits_per_sample == 16
447 && photometric == PHOTOMETRIC_RGB
05c9b356
TC
448 && samples_per_pixel >= 3
449 && samples_integral) {
bd8052a6
TC
450 setupf = setup_16_rgb;
451 putterf = putter_16;
6b7197d0
TC
452 sample_size = 2;
453 rgb_channels(&state, &channels);
bd8052a6
TC
454 }
455 else if (bits_per_sample == 16
05c9b356
TC
456 && photometric == PHOTOMETRIC_MINISBLACK
457 && samples_integral) {
bd8052a6
TC
458 setupf = setup_16_grey;
459 putterf = putter_16;
6b7197d0
TC
460 sample_size = 2;
461 grey_channels(&state, &channels);
bd8052a6
TC
462 }
463 else if (bits_per_sample == 8
05c9b356
TC
464 && photometric == PHOTOMETRIC_MINISBLACK
465 && samples_integral) {
bd8052a6
TC
466 setupf = setup_8_grey;
467 putterf = putter_8;
6b7197d0
TC
468 sample_size = 1;
469 grey_channels(&state, &channels);
bd8052a6
TC
470 }
471 else if (bits_per_sample == 8
05c9b356
TC
472 && photometric == PHOTOMETRIC_RGB
473 && samples_integral) {
bd8052a6
TC
474 setupf = setup_8_rgb;
475 putterf = putter_8;
6b7197d0
TC
476 sample_size = 1;
477 rgb_channels(&state, &channels);
bd8052a6
TC
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;
6b7197d0
TC
484 sample_size = sizeof(i_fsample_t);
485 rgb_channels(&state, &channels);
bd8052a6
TC
486 }
487 else if (bits_per_sample == 32
488 && photometric == PHOTOMETRIC_MINISBLACK) {
489 setupf = setup_32_grey;
490 putterf = putter_32;
6b7197d0
TC
491 sample_size = sizeof(i_fsample_t);
492 grey_channels(&state, &channels);
bd8052a6
TC
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;
6b7197d0
TC
500 sample_size = sizeof(i_palidx);
501 channels = 1;
bd8052a6
TC
502 }
503 else if (bits_per_sample == 8
504 && photometric == PHOTOMETRIC_SEPARATED
505 && inkset == INKSET_CMYK
05c9b356
TC
506 && samples_per_pixel >= 4
507 && samples_integral) {
bd8052a6
TC
508 setupf = setup_cmyk8;
509 putterf = putter_cmyk8;
6b7197d0
TC
510 sample_size = 1;
511 cmyk_channels(&state, &channels);
bd8052a6
TC
512 }
513 else if (bits_per_sample == 16
514 && photometric == PHOTOMETRIC_SEPARATED
515 && inkset == INKSET_CMYK
05c9b356
TC
516 && samples_per_pixel >= 4
517 && samples_integral) {
bd8052a6
TC
518 setupf = setup_cmyk16;
519 putterf = putter_cmyk16;
6b7197d0
TC
520 sample_size = 2;
521 cmyk_channels(&state, &channels);
bd8052a6 522 }
6b7197d0
TC
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
bd8052a6
TC
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) {
bd8052a6
TC
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 }
a50608d2 555
bd8052a6
TC
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);
5bb828f1
TC
567 }
568 else {
bd8052a6
TC
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 }
5bb828f1 575 }
8c3af7b3
TC
576
577 if (!im)
578 return NULL;
f00e06a0
TC
579
580 /* general metadata */
e5ee047b
TC
581 i_tags_setn(&im->tags, "tiff_bitspersample", bits_per_sample);
582 i_tags_setn(&im->tags, "tiff_photometric", photometric);
bd8052a6 583 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
5bb828f1 584
fd9a31d2 585 /* resolution tags */
5bb828f1 586 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
faa9b3e7
TC
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;
e5ee047b 594 i_tags_setn(&im->tags, "tiff_resolutionunit", resunit);
faa9b3e7
TC
595 if (resunit == RESUNIT_CENTIMETER) {
596 /* from dots per cm to dpi */
597 xres *= 2.54;
598 yres *= 2.54;
e5ee047b 599 i_tags_set(&im->tags, "tiff_resolutionunit_name", "centimeter", -1);
faa9b3e7 600 }
3cff89e2 601 else if (resunit == RESUNIT_NONE) {
e5ee047b
TC
602 i_tags_setn(&im->tags, "i_aspect_only", 1);
603 i_tags_set(&im->tags, "tiff_resolutionunit_name", "none", -1);
3cff89e2
TC
604 }
605 else if (resunit == RESUNIT_INCH) {
e5ee047b 606 i_tags_set(&im->tags, "tiff_resolutionunit_name", "inch", -1);
3cff89e2
TC
607 }
608 else {
e5ee047b 609 i_tags_set(&im->tags, "tiff_resolutionunit_name", "unknown", -1);
3cff89e2 610 }
2e41e30b
TC
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);
faa9b3e7 616 }
fd9a31d2
TC
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));
e5ee047b 624 i_tags_set(&im->tags, text_tag_names[i].name, data, -1);
fd9a31d2
TC
625 }
626 }
8c3af7b3 627
e5ee047b 628 i_tags_set(&im->tags, "i_format", "tiff", 4);
60715047
TC
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
ffeb4a67 638 if (warn_buffer && *warn_buffer) {
e5ee047b 639 i_tags_set(&im->tags, "i_warning", warn_buffer, -1);
ffeb4a67
TC
640 *warn_buffer = '\0';
641 }
60715047 642#endif
bd8052a6
TC
643
644 for (i = 0; i < compress_value_count; ++i) {
645 if (compress_values[i].tag == compress) {
e5ee047b 646 i_tags_set(&im->tags, "tiff_compression", compress_values[i].name, -1);
bd8052a6 647 break;
5bb828f1 648 }
5bb828f1 649 }
05c9b356
TC
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
10461f9a
TC
664 return im;
665}
666
667/*
05c9b356 668=item i_readtiff_wiol(ig, allow_incomplete, page)
10461f9a
TC
669
670=cut
671*/
672i_img*
d87dc9a4 673i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
10461f9a
TC
674 TIFF* tif;
675 TIFFErrorHandler old_handler;
be371490 676 TIFFErrorHandler old_warn_handler;
60715047
TC
677#ifdef USE_EXT_WARN_HANDLER
678 TIFFErrorHandlerExt old_ext_warn_handler;
679#endif
10461f9a 680 i_img *im;
69287763 681 int current_page;
60715047 682 tiffio_context_t ctx;
e482e0b3 683
33ca1a7e
TC
684 i_mutex_lock(mutex);
685
10461f9a
TC
686 i_clear_error();
687 old_handler = TIFFSetErrorHandler(error_handler);
60715047
TC
688#ifdef USE_EXT_WARN_HANDLER
689 old_warn_handler = TIFFSetWarningHandler(NULL);
690 old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex);
691#else
be371490 692 old_warn_handler = TIFFSetWarningHandler(warn_handler);
ffeb4a67
TC
693 if (warn_buffer)
694 *warn_buffer = '\0';
60715047 695#endif
10461f9a
TC
696
697 /* Add code to get the filename info from the iolayer */
698 /* Also add code to check for mmapped code */
699
d87dc9a4 700 mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
10461f9a 701
60715047 702 tiffio_context_init(&ctx, ig);
10461f9a
TC
703 tif = TIFFClientOpen("(Iolayer)",
704 "rm",
60715047 705 (thandle_t) &ctx,
6d5c85a2
TC
706 comp_read,
707 comp_write,
708 comp_seek,
709 comp_close,
710 sizeproc,
711 comp_mmap,
712 comp_munmap);
10461f9a
TC
713
714 if (!tif) {
715 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
2691d220 716 i_push_error(0, "Error opening file");
10461f9a 717 TIFFSetErrorHandler(old_handler);
be371490 718 TIFFSetWarningHandler(old_warn_handler);
60715047
TC
719#ifdef USE_EXT_WARN_HANDLER
720 TIFFSetWarningHandlerExt(old_ext_warn_handler);
721#endif
722 tiffio_context_final(&ctx);
33ca1a7e 723 i_mutex_unlock(mutex);
10461f9a
TC
724 return NULL;
725 }
726
69287763
TC
727 for (current_page = 0; current_page < page; ++current_page) {
728 if (!TIFFReadDirectory(tif)) {
8f8bd9aa
TC
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);
60715047
TC
733#ifdef USE_EXT_WARN_HANDLER
734 TIFFSetWarningHandlerExt(old_ext_warn_handler);
735#endif
01f2d357 736 TIFFClose(tif);
60715047 737 tiffio_context_final(&ctx);
33ca1a7e 738 i_mutex_unlock(mutex);
8f8bd9aa
TC
739 return NULL;
740 }
741 }
742
d87dc9a4 743 im = read_one_tiff(tif, allow_incomplete);
10461f9a 744
02d1d628 745 if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
5bb828f1 746 TIFFSetErrorHandler(old_handler);
be371490 747 TIFFSetWarningHandler(old_warn_handler);
60715047
TC
748#ifdef USE_EXT_WARN_HANDLER
749 TIFFSetWarningHandlerExt(old_ext_warn_handler);
750#endif
5bb828f1 751 TIFFClose(tif);
60715047 752 tiffio_context_final(&ctx);
33ca1a7e 753 i_mutex_unlock(mutex);
60715047 754
02d1d628
AMH
755 return im;
756}
757
10461f9a 758/*
e5ee047b 759=item i_readtiff_multi_wiol(ig, *count)
02d1d628 760
10461f9a 761Reads multiple images from a TIFF.
02d1d628 762
10461f9a
TC
763=cut
764*/
765i_img**
e5ee047b 766i_readtiff_multi_wiol(io_glue *ig, int *count) {
10461f9a
TC
767 TIFF* tif;
768 TIFFErrorHandler old_handler;
be371490 769 TIFFErrorHandler old_warn_handler;
60715047
TC
770#ifdef USE_EXT_WARN_HANDLER
771 TIFFErrorHandlerExt old_ext_warn_handler;
772#endif
10461f9a
TC
773 i_img **results = NULL;
774 int result_alloc = 0;
60715047 775 tiffio_context_t ctx;
e482e0b3 776
33ca1a7e
TC
777 i_mutex_lock(mutex);
778
10461f9a
TC
779 i_clear_error();
780 old_handler = TIFFSetErrorHandler(error_handler);
60715047
TC
781#ifdef USE_EXT_WARN_HANDLER
782 old_warn_handler = TIFFSetWarningHandler(NULL);
783 old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex);
784#else
be371490 785 old_warn_handler = TIFFSetWarningHandler(warn_handler);
ffeb4a67
TC
786 if (warn_buffer)
787 *warn_buffer = '\0';
60715047
TC
788#endif
789
790 tiffio_context_init(&ctx, ig);
02d1d628 791
10461f9a
TC
792 /* Add code to get the filename info from the iolayer */
793 /* Also add code to check for mmapped code */
02d1d628 794
5e84d110 795 mm_log((1, "i_readtiff_wiol(ig %p)\n", ig));
10461f9a
TC
796
797 tif = TIFFClientOpen("(Iolayer)",
798 "rm",
60715047 799 (thandle_t) &ctx,
6d5c85a2
TC
800 comp_read,
801 comp_write,
802 comp_seek,
803 comp_close,
804 sizeproc,
805 comp_mmap,
806 comp_munmap);
10461f9a
TC
807
808 if (!tif) {
809 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
2691d220 810 i_push_error(0, "Error opening file");
10461f9a 811 TIFFSetErrorHandler(old_handler);
be371490 812 TIFFSetWarningHandler(old_warn_handler);
60715047
TC
813#ifdef USE_EXT_WARN_HANDLER
814 TIFFSetWarningHandlerExt(old_ext_warn_handler);
815#endif
816 tiffio_context_final(&ctx);
33ca1a7e 817 i_mutex_unlock(mutex);
10461f9a
TC
818 return NULL;
819 }
02d1d628 820
10461f9a
TC
821 *count = 0;
822 do {
9c106321 823 i_img *im = read_one_tiff(tif, 0);
10461f9a
TC
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 *));
be371490
TC
835 if (!newresults) {
836 i_img_destroy(im); /* don't leak it */
837 break;
838 }
839 results = newresults;
10461f9a
TC
840 }
841 }
842 results[*count-1] = im;
69287763 843 } while (TIFFReadDirectory(tif));
10461f9a 844
be371490 845 TIFFSetWarningHandler(old_warn_handler);
10461f9a 846 TIFFSetErrorHandler(old_handler);
60715047
TC
847#ifdef USE_EXT_WARN_HANDLER
848 TIFFSetWarningHandlerExt(old_ext_warn_handler);
849#endif
10461f9a 850 TIFFClose(tif);
60715047 851 tiffio_context_final(&ctx);
33ca1a7e 852 i_mutex_unlock(mutex);
60715047 853
10461f9a
TC
854 return results;
855}
02d1d628
AMH
856
857undef_int
10461f9a
TC
858i_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;
10461f9a
TC
864 uint32 rowsperstrip;
865 float vres = fine ? 196 : 98;
866 int luma_chan;
867
868 width = im->xsize;
869 height = im->ysize;
870
8d14daab
TC
871 if (width != im->xsize || height != im->ysize) {
872 i_push_error(0, "image too large for TIFF");
873 return 0;
874 }
875
10461f9a
TC
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; }
799d55a6 909 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
10461f9a
TC
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));
98747309
TC
923 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField scanlinesize=%lu\n",
924 (unsigned long)TIFFScanlineSize(tif) ));
10461f9a
TC
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++) {
799d55a6 950 linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
10461f9a
TC
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
bd8052a6
TC
965static uint16
966find_compression(char const *name, uint16 *compress) {
967 int i;
02d1d628 968
bd8052a6
TC
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;
f62b2d84 973 }
02d1d628 974 }
bd8052a6 975 *compress = COMPRESSION_NONE;
02d1d628 976
bd8052a6
TC
977 return 0;
978}
02d1d628 979
bd8052a6
TC
980static uint16
981get_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)
f8d72f20 989 && myTIFFIsCODECConfigured(compress))
bd8052a6 990 return compress;
10461f9a 991 }
bd8052a6
TC
992 if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
993 if ((uint16)value == value
f8d72f20 994 && myTIFFIsCODECConfigured((uint16)value))
bd8052a6 995 return (uint16)value;
10461f9a 996 }
bd8052a6
TC
997
998 return def_compress;
999}
1000
1001int
1002i_tiff_has_compression(const char *name) {
1003 uint16 compress;
1004
1005 if (!find_compression(name, &compress))
1006 return 0;
1007
f8d72f20 1008 return myTIFFIsCODECConfigured(compress);
bd8052a6
TC
1009}
1010
1011static int
1012set_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;
10461f9a 1022 }
bd8052a6
TC
1023 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
1024 i_push_error(0, "write TIFF: setting length tag");
1025 return 0;
10461f9a 1026 }
bd8052a6
TC
1027 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
1028 i_push_error(0, "write TIFF: setting orientation tag");
1029 return 0;
10461f9a 1030 }
bd8052a6
TC
1031 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
1032 i_push_error(0, "write TIFF: setting planar configuration tag");
1033 return 0;
02d1d628 1034 }
bd8052a6
TC
1035 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
1036 i_push_error(0, "write TIFF: setting photometric tag");
1037 return 0;
f62b2d84 1038 }
bd8052a6
TC
1039 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
1040 i_push_error(0, "write TIFF: setting compression tag");
1041 return 0;
f62b2d84 1042 }
bd8052a6
TC
1043 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
1044 i_push_error(0, "write TIFF: setting bits per sample tag");
f62b2d84
TC
1045 return 0;
1046 }
bd8052a6
TC
1047 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
1048 i_push_error(0, "write TIFF: setting samples per pixel tag");
02d1d628
AMH
1049 return 0;
1050 }
02d1d628 1051
faa9b3e7
TC
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)) {
bd8052a6 1076 i_push_error(0, "write TIFF: setting xresolution tag");
faa9b3e7
TC
1077 return 0;
1078 }
1079 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
bd8052a6 1080 i_push_error(0, "write TIFF: setting yresolution tag");
faa9b3e7
TC
1081 return 0;
1082 }
1083 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
bd8052a6 1084 i_push_error(0, "write TIFF: setting resolutionunit tag");
faa9b3e7 1085 return 0;
02d1d628
AMH
1086 }
1087 }
fd9a31d2 1088
bd8052a6
TC
1089 return 1;
1090}
1091
1092static int
1093write_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;
8d14daab 1099 i_img_dim x, y;
bd8052a6
TC
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;
fd9a31d2
TC
1121 }
1122
bd8052a6
TC
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;
f62b2d84 1129 }
bd8052a6
TC
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;
f62b2d84 1145 }
bd8052a6
TC
1146 mask >>= 1;
1147 if (!mask) {
1148 ++outp;
1149 mask = 0x80;
f62b2d84 1150 }
02d1d628 1151 }
bd8052a6
TC
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 }
02d1d628 1158 }
d2dfdcc9 1159
bd8052a6
TC
1160 _TIFFfree(out_row);
1161 myfree(in_row);
d2dfdcc9 1162
bd8052a6
TC
1163 return 1;
1164}
d2dfdcc9 1165
bd8052a6
TC
1166static int
1167set_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}
d2dfdcc9 1198
bd8052a6
TC
1199static int
1200write_one_paletted8(TIFF *tif, i_img *im) {
1201 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1202 unsigned char *out_row;
1203 unsigned out_size;
8d14daab 1204 i_img_dim y;
d2dfdcc9 1205
bd8052a6 1206 mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
2691d220 1207
bd8052a6
TC
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;
d2dfdcc9 1214
bd8052a6
TC
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 }
10461f9a 1219
bd8052a6
TC
1220 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
1221 return 0;
10461f9a 1222
bd8052a6 1223 if (!set_palette(tif, im, 256))
d2dfdcc9 1224 return 0;
d2dfdcc9 1225
bd8052a6
TC
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");
10461f9a
TC
1234 return 0;
1235 }
bd8052a6 1236 }
10461f9a 1237
bd8052a6
TC
1238 _TIFFfree(out_row);
1239
1240 return 1;
1241}
1242
1243static int
1244write_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;
8d14daab
TC
1248 size_t out_size;
1249 i_img_dim y;
bd8052a6
TC
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
1292static int
1293set_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
1326static int
1327write_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;
8d14daab 1332 i_img_dim y;
bd8052a6
TC
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
1370static int
1371write_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;
8d14daab 1376 i_img_dim y;
bd8052a6
TC
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
1414static int
1415write_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;
8d14daab 1419 i_img_dim y;
bd8052a6
TC
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
1448static int
1449i_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
8d14daab
TC
1458 if (width != im->xsize || height != im->ysize) {
1459 i_push_error(0, "image too large for TIFF");
1460 return 0;
1461 }
1462
bd8052a6
TC
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
1504Stores 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
1512undef_int
1513i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1514 TIFF* tif;
1515 TIFFErrorHandler old_handler;
1516 int i;
60715047 1517 tiffio_context_t ctx;
e482e0b3 1518
33ca1a7e
TC
1519 i_mutex_lock(mutex);
1520
bd8052a6
TC
1521 old_handler = TIFFSetErrorHandler(error_handler);
1522
bd8052a6 1523 i_clear_error();
8d14daab 1524 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
bd8052a6
TC
1525 ig, imgs, count));
1526
60715047 1527 tiffio_context_init(&ctx, ig);
bd8052a6
TC
1528
1529 tif = TIFFClientOpen("No name",
1530 "wm",
60715047 1531 (thandle_t) &ctx,
6d5c85a2
TC
1532 comp_read,
1533 comp_write,
1534 comp_seek,
1535 comp_close,
1536 sizeproc,
1537 comp_mmap,
1538 comp_munmap);
bd8052a6
TC
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);
60715047 1546 tiffio_context_final(&ctx);
33ca1a7e 1547 i_mutex_unlock(mutex);
bd8052a6
TC
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);
60715047 1555 tiffio_context_final(&ctx);
33ca1a7e 1556 i_mutex_unlock(mutex);
bd8052a6
TC
1557 return 0;
1558 }
1559
1560 if (!TIFFWriteDirectory(tif)) {
1561 i_push_error(0, "Cannot write TIFF directory");
1562 TIFFClose(tif);
2691d220 1563 TIFFSetErrorHandler(old_handler);
60715047 1564 tiffio_context_final(&ctx);
33ca1a7e 1565 i_mutex_unlock(mutex);
10461f9a
TC
1566 return 0;
1567 }
1568 }
1569
2691d220 1570 TIFFSetErrorHandler(old_handler);
10461f9a 1571 (void) TIFFClose(tif);
60715047 1572 tiffio_context_final(&ctx);
e482e0b3 1573
33ca1a7e
TC
1574 i_mutex_unlock(mutex);
1575
6d5c85a2
TC
1576 if (i_io_close(ig))
1577 return 0;
1578
10461f9a
TC
1579 return 1;
1580}
1581
1582/*
1583=item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1584
1585Stores 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
1595undef_int
1596i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1597 TIFF* tif;
1598 int i;
2691d220 1599 TIFFErrorHandler old_handler;
60715047 1600 tiffio_context_t ctx;
e482e0b3 1601
33ca1a7e
TC
1602 i_mutex_lock(mutex);
1603
2691d220 1604 old_handler = TIFFSetErrorHandler(error_handler);
d2dfdcc9 1605
10461f9a 1606 i_clear_error();
8d14daab 1607 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
10461f9a 1608 ig, imgs, count));
d2dfdcc9 1609
60715047 1610 tiffio_context_init(&ctx, ig);
d2dfdcc9
TC
1611
1612 tif = TIFFClientOpen("No name",
1613 "wm",
60715047 1614 (thandle_t) &ctx,
6d5c85a2
TC
1615 comp_read,
1616 comp_write,
1617 comp_seek,
1618 comp_close,
1619 sizeproc,
1620 comp_mmap,
1621 comp_munmap);
10461f9a
TC
1622
1623
d2dfdcc9
TC
1624
1625 if (!tif) {
10461f9a 1626 mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
2691d220
TC
1627 i_push_error(0, "Could not create TIFF object");
1628 TIFFSetErrorHandler(old_handler);
60715047 1629 tiffio_context_final(&ctx);
33ca1a7e 1630 i_mutex_unlock(mutex);
d2dfdcc9
TC
1631 return 0;
1632 }
1633
10461f9a
TC
1634 for (i = 0; i < count; ++i) {
1635 if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1636 TIFFClose(tif);
2691d220 1637 TIFFSetErrorHandler(old_handler);
60715047 1638 tiffio_context_final(&ctx);
33ca1a7e 1639 i_mutex_unlock(mutex);
10461f9a
TC
1640 return 0;
1641 }
d2dfdcc9 1642
10461f9a
TC
1643 if (!TIFFWriteDirectory(tif)) {
1644 i_push_error(0, "Cannot write TIFF directory");
1645 TIFFClose(tif);
2691d220 1646 TIFFSetErrorHandler(old_handler);
60715047 1647 tiffio_context_final(&ctx);
33ca1a7e 1648 i_mutex_unlock(mutex);
10461f9a
TC
1649 return 0;
1650 }
1651 }
d2dfdcc9 1652
10461f9a 1653 (void) TIFFClose(tif);
2691d220 1654 TIFFSetErrorHandler(old_handler);
60715047 1655 tiffio_context_final(&ctx);
e482e0b3 1656
33ca1a7e
TC
1657 i_mutex_unlock(mutex);
1658
6d5c85a2
TC
1659 if (i_io_close(ig))
1660 return 0;
1661
10461f9a
TC
1662 return 1;
1663}
d2dfdcc9 1664
10461f9a
TC
1665/*
1666=item i_writetiff_wiol(im, ig)
d2dfdcc9 1667
10461f9a
TC
1668Stores 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*/
1675undef_int
1676i_writetiff_wiol(i_img *img, io_glue *ig) {
1677 TIFF* tif;
2691d220 1678 TIFFErrorHandler old_handler;
60715047 1679 tiffio_context_t ctx;
e482e0b3 1680
33ca1a7e
TC
1681 i_mutex_lock(mutex);
1682
2691d220 1683 old_handler = TIFFSetErrorHandler(error_handler);
10461f9a 1684
10461f9a 1685 i_clear_error();
8d14daab 1686 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", img, ig));
10461f9a 1687
60715047 1688 tiffio_context_init(&ctx, ig);
2691d220 1689
10461f9a
TC
1690 tif = TIFFClientOpen("No name",
1691 "wm",
60715047 1692 (thandle_t) &ctx,
6d5c85a2
TC
1693 comp_read,
1694 comp_write,
1695 comp_seek,
1696 comp_close,
1697 sizeproc,
1698 comp_mmap,
1699 comp_munmap);
10461f9a
TC
1700
1701
1702
1703 if (!tif) {
1704 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
2691d220 1705 i_push_error(0, "Could not create TIFF object");
60715047 1706 tiffio_context_final(&ctx);
2691d220 1707 TIFFSetErrorHandler(old_handler);
33ca1a7e 1708 i_mutex_unlock(mutex);
10461f9a 1709 return 0;
d2dfdcc9 1710 }
d2dfdcc9 1711
10461f9a 1712 if (!i_writetiff_low(tif, img)) {
fd9a31d2 1713 TIFFClose(tif);
60715047 1714 tiffio_context_final(&ctx);
2691d220 1715 TIFFSetErrorHandler(old_handler);
33ca1a7e 1716 i_mutex_unlock(mutex);
fd9a31d2
TC
1717 return 0;
1718 }
1719
10461f9a 1720 (void) TIFFClose(tif);
2691d220 1721 TIFFSetErrorHandler(old_handler);
33ca1a7e
TC
1722 tiffio_context_final(&ctx);
1723 i_mutex_unlock(mutex);
2691d220 1724
6d5c85a2
TC
1725 if (i_io_close(ig))
1726 return 0;
1727
10461f9a
TC
1728 return 1;
1729}
1730
1731
1732
1733/*
1734=item i_writetiff_wiol_faxable(i_img *, io_glue *)
1735
1736Stores 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
1741Note, this may be rewritten to use to simply be a call to a
1742lower-level function that gives more options for writing tiff at some
1743point.
1744
1745=cut
1746*/
1747
1748undef_int
1749i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1750 TIFF* tif;
2691d220 1751 TIFFErrorHandler old_handler;
60715047 1752 tiffio_context_t ctx;
e482e0b3 1753
33ca1a7e
TC
1754 i_mutex_lock(mutex);
1755
2691d220 1756 old_handler = TIFFSetErrorHandler(error_handler);
10461f9a 1757
10461f9a 1758 i_clear_error();
8d14daab 1759 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", im, ig));
10461f9a 1760
60715047 1761 tiffio_context_init(&ctx, ig);
10461f9a
TC
1762
1763 tif = TIFFClientOpen("No name",
1764 "wm",
60715047 1765 (thandle_t) &ctx,
6d5c85a2
TC
1766 comp_read,
1767 comp_write,
1768 comp_seek,
1769 comp_close,
1770 sizeproc,
1771 comp_mmap,
1772 comp_munmap);
10461f9a
TC
1773
1774
1775
1776 if (!tif) {
1777 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
2691d220
TC
1778 i_push_error(0, "Could not create TIFF object");
1779 TIFFSetErrorHandler(old_handler);
60715047 1780 tiffio_context_final(&ctx);
33ca1a7e 1781 i_mutex_unlock(mutex);
10461f9a 1782 return 0;
d2dfdcc9 1783 }
10461f9a
TC
1784
1785 if (!i_writetiff_low_faxable(tif, im, fine)) {
1786 TIFFClose(tif);
2691d220 1787 TIFFSetErrorHandler(old_handler);
60715047 1788 tiffio_context_final(&ctx);
33ca1a7e 1789 i_mutex_unlock(mutex);
10461f9a
TC
1790 return 0;
1791 }
1792
d2dfdcc9 1793 (void) TIFFClose(tif);
2691d220 1794 TIFFSetErrorHandler(old_handler);
60715047 1795 tiffio_context_final(&ctx);
33ca1a7e 1796 i_mutex_unlock(mutex);
2691d220 1797
6d5c85a2
TC
1798 if (i_io_close(ig))
1799 return 0;
1800
d2dfdcc9
TC
1801 return 1;
1802}
1803
fd9a31d2
TC
1804static int save_tiff_tags(TIFF *tif, i_img *im) {
1805 int i;
10461f9a 1806
fd9a31d2
TC
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,
10461f9a
TC
1811 im->tags.tags[entry].data)) {
1812 i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1813 return 0;
fd9a31d2
TC
1814 }
1815 }
1816 }
60715047 1817
fd9a31d2
TC
1818 return 1;
1819}
b8c2033e 1820
10461f9a 1821
bd8052a6
TC
1822static void
1823unpack_4bit_to(unsigned char *dest, const unsigned char *src,
8d14daab 1824 size_t src_byte_count) {
bd8052a6
TC
1825 while (src_byte_count > 0) {
1826 *dest++ = *src >> 4;
1827 *dest++ = *src++ & 0xf;
1828 --src_byte_count;
1829 }
1830}
5bb828f1 1831
bd8052a6 1832static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
8d14daab 1833 i_img_dim pixel_count) {
bd8052a6
TC
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}
5bb828f1 1845
6b7197d0
TC
1846/*
1847=item fallback_rgb_channels
1848
1849Calculate the number of output channels when we fallback to the RGBA
1850family of functions.
1851
1852=cut
1853*/
1854
1855static void
1856fallback_rgb_channels(TIFF *tif, i_img_dim width, i_img_dim height, int *channels, int *alpha_chan) {
bd8052a6 1857 uint16 photometric;
6b7197d0 1858 uint16 in_channels;
bd8052a6
TC
1859 uint16 extra_count;
1860 uint16 *extras;
5bb828f1 1861
bd8052a6
TC
1862 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1863 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
5bb828f1 1864
bd8052a6
TC
1865 switch (photometric) {
1866 case PHOTOMETRIC_SEPARATED:
6b7197d0 1867 *channels = 3;
bd8052a6
TC
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 */
6b7197d0 1875 *channels = 1;
bd8052a6 1876 break;
5bb828f1 1877
bd8052a6 1878 default:
6b7197d0 1879 *channels = 3;
bd8052a6
TC
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) {
6b7197d0 1888 *alpha_chan = (*channels)++;
5bb828f1 1889 }
6b7197d0
TC
1890}
1891
1892static i_img *
1893make_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);
bd8052a6
TC
1897
1898 return i_img_8_new(width, height, channels);
5bb828f1
TC
1899}
1900
bd8052a6 1901static i_img *
8d14daab 1902read_one_rgb_lines(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
bd8052a6
TC
1903 i_img *im;
1904 uint32* raster = NULL;
1905 uint32 rowsperstrip, row;
1906 i_color *line_buf;
1907 int alpha_chan;
694d935c 1908 int rc;
bd8052a6
TC
1909
1910 im = make_rgb(tif, width, height, &alpha_chan);
1911 if (!im)
1912 return NULL;
1913
694d935c 1914 rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
bd8052a6
TC
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 }
f62b2d84 1976 }
bd8052a6
TC
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 */
1996static int
1997myTIFFReadRGBATile(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);
f62b2d84 2070}
5bb828f1 2071
bd8052a6 2072static i_img *
8d14daab 2073read_one_rgb_tiled(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
bd8052a6
TC
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
2183char const *
2184i_tiff_libversion(void) {
2185 return TIFFGetVersion();
2186}
2187
2188static int
2189setup_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
2215static int
2216tile_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
2258static int
2259strip_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
2290static int
8d14daab 2291paletted_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
2292 unsigned char *p = state->raster;
2293
8d14daab 2294 state->pixels_read += width * height;
bd8052a6
TC
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
2305static int
8d14daab 2306paletted_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
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
8d14daab 2314 state->pixels_read += width * height;
bd8052a6
TC
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
2326static void
2327rgb_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;
05c9b356 2335 state->color_channels = 3;
bd8052a6
TC
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
2372static void
2373grey_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;
05c9b356 2381 state->color_channels = 1;
bd8052a6
TC
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
2417static int
2418setup_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
2431static int
2432setup_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
2445static int
8d14daab 2446putter_16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
bd8052a6
TC
2447 int row_extras) {
2448 uint16 *p = state->raster;
2449 int out_chan = state->img->channels;
2450
8d14daab 2451 state->pixels_read += width * height;
bd8052a6 2452 while (height > 0) {
8d14daab 2453 i_img_dim i;
bd8052a6
TC
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 }
05c9b356
TC
2461 if (state->sample_signed) {
2462 for (ch = 0; ch < state->color_channels; ++ch)
2463 outp[ch] ^= 0x8000;
2464 }
bd8052a6
TC
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
2485static int
2486setup_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
2499static int
2500setup_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
2513static int
8d14daab 2514putter_8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
bd8052a6
TC
2515 int row_extras) {
2516 unsigned char *p = state->raster;
2517 int out_chan = state->img->channels;
2518
8d14daab 2519 state->pixels_read += width * height;
bd8052a6 2520 while (height > 0) {
8d14daab 2521 i_img_dim i;
bd8052a6
TC
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 }
05c9b356
TC
2529 if (state->sample_signed) {
2530 for (ch = 0; ch < state->color_channels; ++ch)
2531 outp->channel[ch] ^= 0x80;
2532 }
bd8052a6
TC
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
2555static int
2556setup_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
2569static int
2570setup_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
2583static int
8d14daab 2584putter_32(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
bd8052a6
TC
2585 int row_extras) {
2586 uint32 *p = state->raster;
2587 int out_chan = state->img->channels;
2588
8d14daab 2589 state->pixels_read += width * height;
bd8052a6 2590 while (height > 0) {
8d14daab 2591 i_img_dim i;
bd8052a6
TC
2592 int ch;
2593 i_fcolor *outp = state->line_buf;
2594
2595 for (i = 0; i < width; ++i) {
05c9b356
TC
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
bd8052a6 2612 }
05c9b356
TC
2613#endif
2614
bd8052a6
TC
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
2633static int
2634setup_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
2656static int
8d14daab 2657putter_bilevel(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
bd8052a6
TC
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 */
8d14daab 2664 state->pixels_read += width * height;
bd8052a6 2665 while (height > 0) {
8d14daab 2666 i_img_dim i;
bd8052a6
TC
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
2690static void
2691cmyk_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;
05c9b356 2699 state->color_channels = 3;
bd8052a6
TC
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
2735static int
2736setup_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
2747static int
8d14daab 2748putter_cmyk8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
bd8052a6
TC
2749 int row_extras) {
2750 unsigned char *p = state->raster;
2751
8d14daab 2752 state->pixels_read += width * height;
bd8052a6 2753 while (height > 0) {
8d14daab 2754 i_img_dim i;
bd8052a6
TC
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];
05c9b356
TC
2764 if (state->sample_signed) {
2765 c ^= 0x80;
2766 m ^= 0x80;
2767 y ^= 0x80;
2768 k ^= 0x80;
2769 }
bd8052a6
TC
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
2797static int
2798setup_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
2809static int
8d14daab 2810putter_cmyk16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
bd8052a6
TC
2811 int row_extras) {
2812 uint16 *p = state->raster;
2813 int out_chan = state->img->channels;
2814
5e84d110 2815 mm_log((4, "putter_cmyk16(%p, %" i_DF ", %" i_DF ", %" i_DF
cd496c63
TC
2816 ", %" i_DF ", %d)\n", state, i_DFcp(x, y), i_DFcp(width, height),
2817 row_extras));
bd8052a6 2818
8d14daab 2819 state->pixels_read += width * height;
bd8052a6 2820 while (height > 0) {
8d14daab 2821 i_img_dim i;
bd8052a6
TC
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];
05c9b356
TC
2831 if (state->sample_signed) {
2832 c ^= 0x8000;
2833 m ^= 0x8000;
2834 y ^= 0x8000;
2835 k ^= 0x8000;
2836 }
bd8052a6
TC
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
f8d72f20
TC
2869 If you want this detection to do anything useful, use a newer
2870 release of tifflib.
2871
bd8052a6
TC
2872 */
2873#if TIFFLIB_VERSION < 20031121
2874
f8d72f20
TC
2875int
2876TIFFIsCODECConfigured(uint16 scheme) {
bd8052a6 2877 switch (scheme) {
f8d72f20 2878 /* these schemes are all shipped with tifflib */
bd8052a6 2879 case COMPRESSION_NONE:
bd8052a6 2880 case COMPRESSION_PACKBITS:
bd8052a6
TC
2881 case COMPRESSION_CCITTRLE:
2882 case COMPRESSION_CCITTRLEW:
2883 case COMPRESSION_CCITTFAX3:
2884 case COMPRESSION_CCITTFAX4:
f8d72f20 2885 return 1;
bd8052a6 2886
f8d72f20
TC
2887 /* these require external library support */
2888 default:
bd8052a6 2889 case COMPRESSION_JPEG:
bd8052a6 2890 case COMPRESSION_LZW:
bd8052a6
TC
2891 case COMPRESSION_DEFLATE:
2892 case COMPRESSION_ADOBE_DEFLATE:
bd8052a6
TC
2893 return 0;
2894 }
2895}
2896
2897#endif
2898
f8d72f20
TC
2899static int
2900myTIFFIsCODECConfigured(uint16 scheme) {
2901#if TIFFLIB_VERSION < 20040724
2902 if (scheme == COMPRESSION_LZW)
2903 return 0;
2904#endif
2905
2906 return TIFFIsCODECConfigured(scheme);
2907}
2908
60715047
TC
2909static void
2910tiffio_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
2919static void
2920tiffio_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
b8c2033e
AMH
2928/*
2929=back
2930
2931=head1 AUTHOR
2932
5b480b14 2933Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tonyc@cpan.org>
b8c2033e
AMH
2934
2935=head1 SEE ALSO
2936
2937Imager(3)
2938
2939=cut
2940*/