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