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