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