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