6 /* needed to implement our substitute TIFFIsCODECConfigured */
7 #if TIFFLIB_VERSION < 20031121
8 static int TIFFIsCODECConfigured(uint16 scheme);
14 tiff.c - implements reading and writing tiff files, uses io layer.
18 io_glue *ig = io_new_fd( fd );
19 i_img *im = i_readtiff_wiol(ig, -1); // no limit on how much is read
21 io_glue *ig = io_new_fd( fd );
22 return_code = i_writetiff_wiol(im, ig);
26 tiff.c implements the basic functions to read and write tiff files.
27 It uses the iolayer and needs either a seekable source or an entire
30 =head1 FUNCTION REFERENCE
32 Some of these functions are internal.
39 #define byteswap_macro(x) \
40 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
41 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
43 #define CLAMP8(x) ((x) < 0 ? 0 : (x) > 255 ? 255 : (x))
44 #define CLAMP16(x) ((x) < 0 ? 0 : (x) > 65535 ? 65535 : (x))
51 static i_img *read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete);
52 static i_img *read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete);
54 static struct tag_name text_tag_names[] =
56 { "tiff_documentname", TIFFTAG_DOCUMENTNAME, },
57 { "tiff_imagedescription", TIFFTAG_IMAGEDESCRIPTION, },
58 { "tiff_make", TIFFTAG_MAKE, },
59 { "tiff_model", TIFFTAG_MODEL, },
60 { "tiff_pagename", TIFFTAG_PAGENAME, },
61 { "tiff_software", TIFFTAG_SOFTWARE, },
62 { "tiff_datetime", TIFFTAG_DATETIME, },
63 { "tiff_artist", TIFFTAG_ARTIST, },
64 { "tiff_hostcomputer", TIFFTAG_HOSTCOMPUTER, },
67 static struct tag_name
70 { "none", COMPRESSION_NONE },
71 { "ccittrle", COMPRESSION_CCITTRLE },
72 { "fax3", COMPRESSION_CCITTFAX3 },
73 { "t4", COMPRESSION_CCITTFAX3 },
74 { "fax4", COMPRESSION_CCITTFAX4 },
75 { "t6", COMPRESSION_CCITTFAX4 },
76 { "lzw", COMPRESSION_LZW },
77 { "jpeg", COMPRESSION_JPEG },
78 { "packbits", COMPRESSION_PACKBITS },
79 { "deflate", COMPRESSION_ADOBE_DEFLATE },
80 { "zip", COMPRESSION_ADOBE_DEFLATE },
81 { "oldzip", COMPRESSION_DEFLATE },
82 { "ccittrlew", COMPRESSION_CCITTRLEW },
85 static const int compress_value_count =
86 sizeof(compress_values) / sizeof(*compress_values);
89 myTIFFIsCODECConfigured(uint16 scheme);
91 typedef struct read_state_tag read_state_t;
92 /* the setup function creates the image object, allocates the line buffer */
93 typedef int (*read_setup_t)(read_state_t *state);
95 /* the putter writes the image data provided by the getter to the
96 image, x, y, width, height describe the target area of the image,
97 extras is the extra number of pixels stored for each scanline in
98 the raster buffer, (for tiles against the right side of the
101 typedef int (*read_putter_t)(read_state_t *state, int x, int y, int width,
102 int height, int extras);
104 /* reads from a tiled or strip image and calls the putter.
105 This may need a second type for handling non-contiguous images
107 typedef int (*read_getter_t)(read_state_t *state, read_putter_t putter);
109 struct read_state_tag {
113 unsigned long pixels_read;
114 int allow_incomplete;
116 uint32 width, height;
117 uint16 bits_per_sample;
120 /* the total number of channels (samples per pixel) */
121 int samples_per_pixel;
123 /* if non-zero, which channel is the alpha channel, typically 3 for rgb */
126 /* whether or not to scale the color channels based on the alpha
127 channel. TIFF has 2 types of alpha channel, if the alpha channel
128 we use is EXTRASAMPLE_ASSOCALPHA then the color data will need to
129 be scaled to match Imager's conventions */
133 static int tile_contig_getter(read_state_t *state, read_putter_t putter);
134 static int strip_contig_getter(read_state_t *state, read_putter_t putter);
136 static int setup_paletted(read_state_t *state);
137 static int paletted_putter8(read_state_t *, int, int, int, int, int);
138 static int paletted_putter4(read_state_t *, int, int, int, int, int);
140 static int setup_16_rgb(read_state_t *state);
141 static int setup_16_grey(read_state_t *state);
142 static int putter_16(read_state_t *, int, int, int, int, int);
144 static int setup_8_rgb(read_state_t *state);
145 static int setup_8_grey(read_state_t *state);
146 static int putter_8(read_state_t *, int, int, int, int, int);
148 static int setup_32_rgb(read_state_t *state);
149 static int setup_32_grey(read_state_t *state);
150 static int putter_32(read_state_t *, int, int, int, int, int);
152 static int setup_bilevel(read_state_t *state);
153 static int putter_bilevel(read_state_t *, int, int, int, int, int);
155 static int setup_cmyk8(read_state_t *state);
156 static int putter_cmyk8(read_state_t *, int, int, int, int, int);
158 static int setup_cmyk16(read_state_t *state);
159 static int putter_cmyk16(read_state_t *, int, int, int, int, int);
161 static const int text_tag_count =
162 sizeof(text_tag_names) / sizeof(*text_tag_names);
164 static void error_handler(char const *module, char const *fmt, va_list ap) {
165 mm_log((1, "tiff error fmt %s\n", fmt));
166 i_push_errorvf(0, fmt, ap);
169 #define WARN_BUFFER_LIMIT 10000
170 static char *warn_buffer = NULL;
171 static int warn_buffer_size = 0;
173 static void warn_handler(char const *module, char const *fmt, va_list ap) {
178 vsnprintf(buf, sizeof(buf), fmt, ap);
180 vsprintf(buf, fmt, ap);
182 mm_log((1, "tiff warning %s\n", buf));
184 if (!warn_buffer || strlen(warn_buffer)+strlen(buf)+2 > warn_buffer_size) {
185 int new_size = warn_buffer_size + strlen(buf) + 2;
186 char *old_buffer = warn_buffer;
187 if (new_size > WARN_BUFFER_LIMIT) {
188 new_size = WARN_BUFFER_LIMIT;
190 warn_buffer = myrealloc(warn_buffer, new_size);
191 if (!old_buffer) *warn_buffer = '\0';
192 warn_buffer_size = new_size;
194 if (strlen(warn_buffer)+strlen(buf)+2 <= warn_buffer_size) {
195 strcat(warn_buffer, buf);
196 strcat(warn_buffer, "\n");
200 static int save_tiff_tags(TIFF *tif, i_img *im);
203 pack_4bit_to(unsigned char *dest, const unsigned char *src, int count);
206 static toff_t sizeproc(thandle_t x) {
212 =item comp_seek(h, o, w)
214 Compatability for 64 bit systems like latest freebsd (internal)
216 h - tiff handle, cast an io_glue object
225 comp_seek(thandle_t h, toff_t o, int w) {
226 io_glue *ig = (io_glue*)h;
227 return (toff_t) ig->seekcb(ig, o, w);
231 =item comp_mmap(thandle_t, tdata_t*, toff_t*)
235 This shouldn't ever be called but newer tifflibs want it anyway.
242 comp_mmap(thandle_t h, tdata_t*p, toff_t*off) {
247 =item comp_munmap(thandle_t h, tdata_t p, toff_t off)
251 This shouldn't ever be called but newer tifflibs want it anyway.
257 comp_munmap(thandle_t h, tdata_t p, toff_t off) {
261 static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
263 uint32 width, height;
264 uint16 samples_per_pixel;
268 int gotXres, gotYres;
270 uint16 bits_per_sample;
271 uint16 planar_config;
276 read_setup_t setupf = NULL;
277 read_getter_t getterf = NULL;
278 read_putter_t putterf = NULL;
282 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
283 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
284 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
285 tiled = TIFFIsTiled(tif);
286 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
287 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
288 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
289 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
291 mm_log((1, "i_readtiff_wiol: width=%d, height=%d, channels=%d\n", width, height, samples_per_pixel));
292 mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
293 mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
295 /* yes, this if() is horrible */
296 if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8) {
297 setupf = setup_paletted;
298 if (bits_per_sample == 8)
299 putterf = paletted_putter8;
300 else if (bits_per_sample == 4)
301 putterf = paletted_putter4;
303 mm_log((1, "unsupported paletted bits_per_sample %d\n", bits_per_sample));
305 else if (bits_per_sample == 16
306 && photometric == PHOTOMETRIC_RGB
307 && samples_per_pixel >= 3) {
308 setupf = setup_16_rgb;
311 else if (bits_per_sample == 16
312 && photometric == PHOTOMETRIC_MINISBLACK) {
313 setupf = setup_16_grey;
316 else if (bits_per_sample == 8
317 && photometric == PHOTOMETRIC_MINISBLACK) {
318 setupf = setup_8_grey;
321 else if (bits_per_sample == 8
322 && photometric == PHOTOMETRIC_RGB) {
323 setupf = setup_8_rgb;
326 else if (bits_per_sample == 32
327 && photometric == PHOTOMETRIC_RGB
328 && samples_per_pixel >= 3) {
329 setupf = setup_32_rgb;
332 else if (bits_per_sample == 32
333 && photometric == PHOTOMETRIC_MINISBLACK) {
334 setupf = setup_32_grey;
337 else if (bits_per_sample == 1
338 && (photometric == PHOTOMETRIC_MINISBLACK
339 || photometric == PHOTOMETRIC_MINISWHITE)
340 && samples_per_pixel == 1) {
341 setupf = setup_bilevel;
342 putterf = putter_bilevel;
344 else if (bits_per_sample == 8
345 && photometric == PHOTOMETRIC_SEPARATED
346 && inkset == INKSET_CMYK
347 && samples_per_pixel >= 4) {
348 setupf = setup_cmyk8;
349 putterf = putter_cmyk8;
351 else if (bits_per_sample == 16
352 && photometric == PHOTOMETRIC_SEPARATED
353 && inkset == INKSET_CMYK
354 && samples_per_pixel >= 4) {
355 setupf = setup_cmyk16;
356 putterf = putter_cmyk16;
359 if (planar_config == PLANARCONFIG_CONTIG)
360 getterf = tile_contig_getter;
363 if (planar_config == PLANARCONFIG_CONTIG)
364 getterf = strip_contig_getter;
366 if (setupf && getterf && putterf) {
367 unsigned long total_pixels = (unsigned long)width * height;
368 memset(&state, 0, sizeof(state));
370 state.allow_incomplete = allow_incomplete;
372 state.height = height;
373 state.bits_per_sample = bits_per_sample;
374 state.samples_per_pixel = samples_per_pixel;
375 state.photometric = photometric;
379 if (!getterf(&state, putterf) || !state.pixels_read) {
381 i_img_destroy(state.img);
383 _TIFFfree(state.raster);
385 myfree(state.line_buf);
390 if (allow_incomplete && state.pixels_read < total_pixels) {
391 i_tags_setn(&(state.img->tags), "i_incomplete", 1);
392 i_tags_setn(&(state.img->tags), "i_lines_read",
393 state.pixels_read / width);
398 _TIFFfree(state.raster);
400 myfree(state.line_buf);
404 im = read_one_rgb_tiled(tif, width, height, allow_incomplete);
407 im = read_one_rgb_lines(tif, width, height, allow_incomplete);
414 /* general metadata */
415 i_tags_addn(&im->tags, "tiff_bitspersample", 0, bits_per_sample);
416 i_tags_addn(&im->tags, "tiff_photometric", 0, photometric);
417 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
419 /* resolution tags */
420 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
421 gotXres = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
422 gotYres = TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
423 if (gotXres || gotYres) {
428 i_tags_addn(&im->tags, "tiff_resolutionunit", 0, resunit);
429 if (resunit == RESUNIT_CENTIMETER) {
430 /* from dots per cm to dpi */
433 i_tags_add(&im->tags, "tiff_resolutionunit_name", 0, "centimeter", -1, 0);
435 else if (resunit == RESUNIT_NONE) {
436 i_tags_addn(&im->tags, "i_aspect_only", 0, 1);
437 i_tags_add(&im->tags, "tiff_resolutionunit_name", 0, "none", -1, 0);
439 else if (resunit == RESUNIT_INCH) {
440 i_tags_add(&im->tags, "tiff_resolutionunit_name", 0, "inch", -1, 0);
443 i_tags_add(&im->tags, "tiff_resolutionunit_name", 0, "unknown", -1, 0);
445 /* tifflib doesn't seem to provide a way to get to the original rational
446 value of these, which would let me provide a more reasonable
447 precision. So make up a number. */
448 i_tags_set_float2(&im->tags, "i_xres", 0, xres, 6);
449 i_tags_set_float2(&im->tags, "i_yres", 0, yres, 6);
453 for (i = 0; i < text_tag_count; ++i) {
455 if (TIFFGetField(tif, text_tag_names[i].tag, &data)) {
456 mm_log((1, "i_readtiff_wiol: tag %d has value %s\n",
457 text_tag_names[i].tag, data));
458 i_tags_add(&im->tags, text_tag_names[i].name, 0, data,
463 i_tags_add(&im->tags, "i_format", 0, "tiff", -1, 0);
464 if (warn_buffer && *warn_buffer) {
465 i_tags_add(&im->tags, "i_warning", 0, warn_buffer, -1, 0);
469 for (i = 0; i < compress_value_count; ++i) {
470 if (compress_values[i].tag == compress) {
471 i_tags_add(&im->tags, "tiff_compression", 0, compress_values[i].name, -1, 0);
480 =item i_readtiff_wiol(im, ig)
485 i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
487 TIFFErrorHandler old_handler;
488 TIFFErrorHandler old_warn_handler;
492 old_handler = TIFFSetErrorHandler(error_handler);
493 old_warn_handler = TIFFSetWarningHandler(warn_handler);
497 /* Add code to get the filename info from the iolayer */
498 /* Also add code to check for mmapped code */
500 io_glue_commit_types(ig);
501 mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
503 tif = TIFFClientOpen("(Iolayer)",
506 (TIFFReadWriteProc) ig->readcb,
507 (TIFFReadWriteProc) ig->writecb,
508 (TIFFSeekProc) comp_seek,
509 (TIFFCloseProc) ig->closecb,
510 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
511 (TIFFMapFileProc) comp_mmap,
512 (TIFFUnmapFileProc) comp_munmap);
515 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
516 i_push_error(0, "Error opening file");
517 TIFFSetErrorHandler(old_handler);
518 TIFFSetWarningHandler(old_warn_handler);
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);
533 im = read_one_tiff(tif, allow_incomplete);
535 if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
536 TIFFSetErrorHandler(old_handler);
537 TIFFSetWarningHandler(old_warn_handler);
543 =item i_readtiff_multi_wiol(ig, length, *count)
545 Reads multiple images from a TIFF.
550 i_readtiff_multi_wiol(io_glue *ig, int length, int *count) {
552 TIFFErrorHandler old_handler;
553 TIFFErrorHandler old_warn_handler;
554 i_img **results = NULL;
555 int result_alloc = 0;
559 old_handler = TIFFSetErrorHandler(error_handler);
560 old_warn_handler = TIFFSetWarningHandler(warn_handler);
564 /* Add code to get the filename info from the iolayer */
565 /* Also add code to check for mmapped code */
567 io_glue_commit_types(ig);
568 mm_log((1, "i_readtiff_wiol(ig %p, length %d)\n", ig, length));
570 tif = TIFFClientOpen("(Iolayer)",
573 (TIFFReadWriteProc) ig->readcb,
574 (TIFFReadWriteProc) ig->writecb,
575 (TIFFSeekProc) comp_seek,
576 (TIFFCloseProc) ig->closecb,
577 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
578 (TIFFMapFileProc) comp_mmap,
579 (TIFFUnmapFileProc) comp_munmap);
582 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
583 i_push_error(0, "Error opening file");
584 TIFFSetErrorHandler(old_handler);
585 TIFFSetWarningHandler(old_warn_handler);
591 i_img *im = read_one_tiff(tif, 0);
594 if (++*count > result_alloc) {
595 if (result_alloc == 0) {
597 results = mymalloc(result_alloc * sizeof(i_img *));
602 newresults = myrealloc(results, result_alloc * sizeof(i_img *));
604 i_img_destroy(im); /* don't leak it */
607 results = newresults;
610 results[*count-1] = im;
611 } while (TIFFSetDirectory(tif, ++dirnum));
613 TIFFSetWarningHandler(old_warn_handler);
614 TIFFSetErrorHandler(old_handler);
620 i_writetiff_low_faxable(TIFF *tif, i_img *im, int fine) {
621 uint32 width, height;
622 unsigned char *linebuf = NULL;
627 float vres = fine ? 196 : 98;
633 switch (im->channels) {
643 /* This means a colorspace we don't handle yet */
644 mm_log((1, "i_writetiff_wiol_faxable: don't handle %d channel images.\n", im->channels));
648 /* Add code to get the filename info from the iolayer */
649 /* Also add code to check for mmapped code */
652 mm_log((1, "i_writetiff_wiol_faxable: width=%d, height=%d, channels=%d\n", width, height, im->channels));
654 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width) )
655 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField width=%d failed\n", width)); return 0; }
656 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height) )
657 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField length=%d failed\n", height)); return 0; }
658 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
659 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField samplesperpixel=1 failed\n")); return 0; }
660 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT))
661 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Orientation=topleft\n")); return 0; }
662 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1) )
663 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField bitpersample=1\n")); return 0; }
664 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG))
665 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField planarconfig\n")); return 0; }
666 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
667 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField photometric=%d\n", PHOTOMETRIC_MINISBLACK)); return 0; }
668 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, 3))
669 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField compression=3\n")); return 0; }
671 linebuf = (unsigned char *)_TIFFmalloc( TIFFScanlineSize(tif) );
673 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
674 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField rowsperstrip=-1\n")); return 0; }
676 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
677 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rc);
679 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField rowsperstrip=%d\n", rowsperstrip));
680 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField scanlinesize=%d\n", TIFFScanlineSize(tif) ));
681 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField planarconfig=%d == %d\n", rc, PLANARCONFIG_CONTIG));
683 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)204))
684 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Xresolution=204\n")); return 0; }
685 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, vres))
686 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Yresolution=196\n")); return 0; }
687 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)) {
688 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField ResolutionUnit=%d\n", RESUNIT_INCH)); return 0;
691 if (!save_tiff_tags(tif, im)) {
695 for (y=0; y<height; y++) {
697 for(x=0; x<width; x+=8) {
702 linebuf[linebufpos]=0;
703 bits = width-x; if(bits>8) bits=8;
704 i_gsamp(im, x, x+8, y, luma, &luma_chan, 1);
705 for(bitpos=0;bitpos<bits;bitpos++) {
706 linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
711 if (TIFFWriteScanline(tif, linebuf, y, 0) < 0) {
712 mm_log((1, "i_writetiff_wiol_faxable: TIFFWriteScanline failed.\n"));
716 if (linebuf) _TIFFfree(linebuf);
722 find_compression(char const *name, uint16 *compress) {
725 for (i = 0; i < compress_value_count; ++i) {
726 if (strcmp(compress_values[i].name, name) == 0) {
727 *compress = (uint16)compress_values[i].tag;
731 *compress = COMPRESSION_NONE;
737 get_compression(i_img *im, uint16 def_compress) {
741 if (i_tags_find(&im->tags, "tiff_compression", 0, &entry)
742 && im->tags.tags[entry].data) {
744 if (find_compression(im->tags.tags[entry].data, &compress)
745 && myTIFFIsCODECConfigured(compress))
748 if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
749 if ((uint16)value == value
750 && myTIFFIsCODECConfigured((uint16)value))
751 return (uint16)value;
758 i_tiff_has_compression(const char *name) {
761 if (!find_compression(name, &compress))
764 return myTIFFIsCODECConfigured(compress);
768 set_base_tags(TIFF *tif, i_img *im, uint16 compress, uint16 photometric,
769 uint16 bits_per_sample, uint16 samples_per_pixel) {
772 int got_xres, got_yres;
775 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->xsize)) {
776 i_push_error(0, "write TIFF: setting width tag");
779 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
780 i_push_error(0, "write TIFF: setting length tag");
783 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
784 i_push_error(0, "write TIFF: setting orientation tag");
787 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
788 i_push_error(0, "write TIFF: setting planar configuration tag");
791 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
792 i_push_error(0, "write TIFF: setting photometric tag");
795 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
796 i_push_error(0, "write TIFF: setting compression tag");
799 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
800 i_push_error(0, "write TIFF: setting bits per sample tag");
803 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
804 i_push_error(0, "write TIFF: setting samples per pixel tag");
808 got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
809 got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
810 if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
812 if (!i_tags_get_int(&im->tags, "tiff_resolutionunit", 0, &resunit))
813 resunit = RESUNIT_INCH;
814 if (got_xres || got_yres) {
820 resunit = RESUNIT_NONE;
823 if (resunit == RESUNIT_CENTIMETER) {
828 resunit = RESUNIT_INCH;
831 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xres)) {
832 i_push_error(0, "write TIFF: setting xresolution tag");
835 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
836 i_push_error(0, "write TIFF: setting yresolution tag");
839 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
840 i_push_error(0, "write TIFF: setting resolutionunit tag");
849 write_one_bilevel(TIFF *tif, i_img *im, int zero_is_white) {
850 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
852 unsigned char *in_row;
853 unsigned char *out_row;
858 mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n",
859 tif, im, zero_is_white));
861 /* ignore a silly choice */
862 if (compress == COMPRESSION_JPEG)
863 compress = COMPRESSION_PACKBITS;
866 case COMPRESSION_CCITTRLE:
867 case COMPRESSION_CCITTFAX3:
868 case COMPRESSION_CCITTFAX4:
869 /* natural fax photometric */
870 photometric = PHOTOMETRIC_MINISWHITE;
874 /* natural for most computer images */
875 photometric = PHOTOMETRIC_MINISBLACK;
879 if (!set_base_tags(tif, im, compress, photometric, 1, 1))
882 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
883 i_push_error(0, "write TIFF: setting rows per strip tag");
887 out_size = TIFFScanlineSize(tif);
888 out_row = (unsigned char *)_TIFFmalloc( out_size );
889 in_row = mymalloc(im->xsize);
891 invert = (photometric == PHOTOMETRIC_MINISWHITE) != (zero_is_white != 0);
893 for (y = 0; y < im->ysize; ++y) {
895 unsigned char *outp = out_row;
896 memset(out_row, 0, out_size);
897 i_gpal(im, 0, im->xsize, y, in_row);
898 for (x = 0; x < im->xsize; ++x) {
899 if (invert ? !in_row[x] : in_row[x]) {
908 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
911 i_push_error(0, "write TIFF: write scan line failed");
923 set_palette(TIFF *tif, i_img *im, int size) {
930 colors = (uint16 *)_TIFFmalloc(sizeof(uint16) * 3 * size);
932 out[1] = colors + size;
933 out[2] = colors + 2 * size;
935 count = i_colorcount(im);
936 for (i = 0; i < count; ++i) {
937 i_getcolors(im, i, &c, 1);
938 for (ch = 0; ch < 3; ++ch)
939 out[ch][i] = c.channel[ch] * 257;
941 for (; i < size; ++i) {
942 for (ch = 0; ch < 3; ++ch)
945 if (!TIFFSetField(tif, TIFFTAG_COLORMAP, out[0], out[1], out[2])) {
947 i_push_error(0, "write TIFF: setting color map");
956 write_one_paletted8(TIFF *tif, i_img *im) {
957 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
958 unsigned char *out_row;
962 mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
964 /* ignore a silly choice */
965 if (compress == COMPRESSION_JPEG ||
966 compress == COMPRESSION_CCITTRLE ||
967 compress == COMPRESSION_CCITTFAX3 ||
968 compress == COMPRESSION_CCITTFAX4)
969 compress = COMPRESSION_PACKBITS;
971 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
972 i_push_error(0, "write TIFF: setting rows per strip tag");
976 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
979 if (!set_palette(tif, im, 256))
982 out_size = TIFFScanlineSize(tif);
983 out_row = (unsigned char *)_TIFFmalloc( out_size );
985 for (y = 0; y < im->ysize; ++y) {
986 i_gpal(im, 0, im->xsize, y, out_row);
987 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
989 i_push_error(0, "write TIFF: write scan line failed");
1000 write_one_paletted4(TIFF *tif, i_img *im) {
1001 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1002 unsigned char *in_row;
1003 unsigned char *out_row;
1007 mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
1009 /* ignore a silly choice */
1010 if (compress == COMPRESSION_JPEG ||
1011 compress == COMPRESSION_CCITTRLE ||
1012 compress == COMPRESSION_CCITTFAX3 ||
1013 compress == COMPRESSION_CCITTFAX4)
1014 compress = COMPRESSION_PACKBITS;
1016 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 4, 1))
1019 if (!set_palette(tif, im, 16))
1022 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1023 i_push_error(0, "write TIFF: setting rows per strip tag");
1027 in_row = mymalloc(im->xsize);
1028 out_size = TIFFScanlineSize(tif);
1029 out_row = (unsigned char *)_TIFFmalloc( out_size );
1031 for (y = 0; y < im->ysize; ++y) {
1032 i_gpal(im, 0, im->xsize, y, in_row);
1033 memset(out_row, 0, out_size);
1034 pack_4bit_to(out_row, in_row, im->xsize);
1035 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1037 i_push_error(0, "write TIFF: write scan line failed");
1049 set_direct_tags(TIFF *tif, i_img *im, uint16 compress,
1050 uint16 bits_per_sample) {
1051 uint16 extras = EXTRASAMPLE_ASSOCALPHA;
1052 uint16 extra_count = im->channels == 2 || im->channels == 4;
1053 uint16 photometric = im->channels >= 3 ?
1054 PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
1056 if (!set_base_tags(tif, im, compress, photometric, bits_per_sample,
1062 if (!TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extra_count, &extras)) {
1063 i_push_error(0, "write TIFF: setting extra samples tag");
1068 if (compress == COMPRESSION_JPEG) {
1070 if (i_tags_get_int(&im->tags, "tiff_jpegquality", 0, &jpeg_quality)
1071 && jpeg_quality >= 0 && jpeg_quality <= 100) {
1072 if (!TIFFSetField(tif, TIFFTAG_JPEGQUALITY, jpeg_quality)) {
1073 i_push_error(0, "write TIFF: setting jpeg quality pseudo-tag");
1083 write_one_32(TIFF *tif, i_img *im) {
1084 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1089 size_t sample_count = im->xsize * im->channels;
1090 size_t sample_index;
1092 mm_log((1, "tiff - write_one_32(tif %p, im %p)\n", tif, im));
1094 /* only 8 and 12 bit samples are supported by jpeg compression */
1095 if (compress == COMPRESSION_JPEG)
1096 compress = COMPRESSION_PACKBITS;
1098 if (!set_direct_tags(tif, im, compress, 32))
1101 in_row = mymalloc(sample_count * sizeof(unsigned));
1102 out_size = TIFFScanlineSize(tif);
1103 out_row = (uint32 *)_TIFFmalloc( out_size );
1105 for (y = 0; y < im->ysize; ++y) {
1106 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 32) <= 0) {
1107 i_push_error(0, "Cannot read 32-bit samples");
1110 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1111 out_row[sample_index] = in_row[sample_index];
1112 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1115 i_push_error(0, "write TIFF: write scan line failed");
1127 write_one_16(TIFF *tif, i_img *im) {
1128 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1133 size_t sample_count = im->xsize * im->channels;
1134 size_t sample_index;
1136 mm_log((1, "tiff - write_one_16(tif %p, im %p)\n", tif, im));
1138 /* only 8 and 12 bit samples are supported by jpeg compression */
1139 if (compress == COMPRESSION_JPEG)
1140 compress = COMPRESSION_PACKBITS;
1142 if (!set_direct_tags(tif, im, compress, 16))
1145 in_row = mymalloc(sample_count * sizeof(unsigned));
1146 out_size = TIFFScanlineSize(tif);
1147 out_row = (uint16 *)_TIFFmalloc( out_size );
1149 for (y = 0; y < im->ysize; ++y) {
1150 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 16) <= 0) {
1151 i_push_error(0, "Cannot read 16-bit samples");
1154 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1155 out_row[sample_index] = in_row[sample_index];
1156 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1159 i_push_error(0, "write TIFF: write scan line failed");
1171 write_one_8(TIFF *tif, i_img *im) {
1172 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1174 unsigned char *out_row;
1176 size_t sample_count = im->xsize * im->channels;
1178 mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
1180 if (!set_direct_tags(tif, im, compress, 8))
1183 out_size = TIFFScanlineSize(tif);
1184 if (out_size < sample_count)
1185 out_size = sample_count;
1186 out_row = (unsigned char *)_TIFFmalloc( out_size );
1188 for (y = 0; y < im->ysize; ++y) {
1189 if (i_gsamp(im, 0, im->xsize, y, out_row, NULL, im->channels) <= 0) {
1190 i_push_error(0, "Cannot read 8-bit samples");
1193 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1195 i_push_error(0, "write TIFF: write scan line failed");
1205 i_writetiff_low(TIFF *tif, i_img *im) {
1206 uint32 width, height;
1212 channels = im->channels;
1214 mm_log((1, "i_writetiff_low: width=%d, height=%d, channels=%d, bits=%d\n", width, height, channels, im->bits));
1215 if (im->type == i_palette_type) {
1216 mm_log((1, "i_writetiff_low: paletted, colors=%d\n", i_colorcount(im)));
1219 if (i_img_is_monochrome(im, &zero_is_white)) {
1220 if (!write_one_bilevel(tif, im, zero_is_white))
1223 else if (im->type == i_palette_type) {
1224 if (i_colorcount(im) <= 16) {
1225 if (!write_one_paletted4(tif, im))
1229 if (!write_one_paletted8(tif, im))
1233 else if (im->bits > 16) {
1234 if (!write_one_32(tif, im))
1237 else if (im->bits > 8) {
1238 if (!write_one_16(tif, im))
1242 if (!write_one_8(tif, im))
1246 if (!save_tiff_tags(tif, im))
1253 =item i_writetiff_multi_wiol(ig, imgs, count, fine_mode)
1255 Stores an image in the iolayer object.
1257 ig - io_object that defines source to write to
1258 imgs,count - the images to write
1264 i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1266 TIFFErrorHandler old_handler;
1269 old_handler = TIFFSetErrorHandler(error_handler);
1271 io_glue_commit_types(ig);
1273 mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
1276 /* FIXME: Enable the mmap interface */
1278 tif = TIFFClientOpen("No name",
1281 (TIFFReadWriteProc) ig->readcb,
1282 (TIFFReadWriteProc) ig->writecb,
1283 (TIFFSeekProc) comp_seek,
1284 (TIFFCloseProc) ig->closecb,
1285 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1286 (TIFFMapFileProc) comp_mmap,
1287 (TIFFUnmapFileProc) comp_munmap);
1292 mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n"));
1293 i_push_error(0, "Could not create TIFF object");
1294 TIFFSetErrorHandler(old_handler);
1298 for (i = 0; i < count; ++i) {
1299 if (!i_writetiff_low(tif, imgs[i])) {
1301 TIFFSetErrorHandler(old_handler);
1305 if (!TIFFWriteDirectory(tif)) {
1306 i_push_error(0, "Cannot write TIFF directory");
1308 TIFFSetErrorHandler(old_handler);
1313 TIFFSetErrorHandler(old_handler);
1314 (void) TIFFClose(tif);
1320 =item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1322 Stores an image in the iolayer object.
1324 ig - io_object that defines source to write to
1325 imgs,count - the images to write
1326 fine_mode - select fine or normal mode fax images
1333 i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1336 TIFFErrorHandler old_handler;
1338 old_handler = TIFFSetErrorHandler(error_handler);
1340 io_glue_commit_types(ig);
1342 mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
1345 /* FIXME: Enable the mmap interface */
1347 tif = TIFFClientOpen("No name",
1350 (TIFFReadWriteProc) ig->readcb,
1351 (TIFFReadWriteProc) ig->writecb,
1352 (TIFFSeekProc) comp_seek,
1353 (TIFFCloseProc) ig->closecb,
1354 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1355 (TIFFMapFileProc) comp_mmap,
1356 (TIFFUnmapFileProc) comp_munmap);
1361 mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
1362 i_push_error(0, "Could not create TIFF object");
1363 TIFFSetErrorHandler(old_handler);
1367 for (i = 0; i < count; ++i) {
1368 if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1370 TIFFSetErrorHandler(old_handler);
1374 if (!TIFFWriteDirectory(tif)) {
1375 i_push_error(0, "Cannot write TIFF directory");
1377 TIFFSetErrorHandler(old_handler);
1382 (void) TIFFClose(tif);
1383 TIFFSetErrorHandler(old_handler);
1389 =item i_writetiff_wiol(im, ig)
1391 Stores an image in the iolayer object.
1393 im - image object to write out
1394 ig - io_object that defines source to write to
1399 i_writetiff_wiol(i_img *img, io_glue *ig) {
1401 TIFFErrorHandler old_handler;
1403 old_handler = TIFFSetErrorHandler(error_handler);
1405 io_glue_commit_types(ig);
1407 mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", img, ig));
1409 /* FIXME: Enable the mmap interface */
1411 tif = TIFFClientOpen("No name",
1414 (TIFFReadWriteProc) ig->readcb,
1415 (TIFFReadWriteProc) ig->writecb,
1416 (TIFFSeekProc) comp_seek,
1417 (TIFFCloseProc) ig->closecb,
1418 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1419 (TIFFMapFileProc) comp_mmap,
1420 (TIFFUnmapFileProc) comp_munmap);
1425 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1426 i_push_error(0, "Could not create TIFF object");
1427 TIFFSetErrorHandler(old_handler);
1431 if (!i_writetiff_low(tif, img)) {
1433 TIFFSetErrorHandler(old_handler);
1437 (void) TIFFClose(tif);
1438 TIFFSetErrorHandler(old_handler);
1446 =item i_writetiff_wiol_faxable(i_img *, io_glue *)
1448 Stores an image in the iolayer object in faxable tiff format.
1450 im - image object to write out
1451 ig - io_object that defines source to write to
1453 Note, this may be rewritten to use to simply be a call to a
1454 lower-level function that gives more options for writing tiff at some
1461 i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1463 TIFFErrorHandler old_handler;
1465 old_handler = TIFFSetErrorHandler(error_handler);
1467 io_glue_commit_types(ig);
1469 mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", im, ig));
1471 /* FIXME: Enable the mmap interface */
1473 tif = TIFFClientOpen("No name",
1476 (TIFFReadWriteProc) ig->readcb,
1477 (TIFFReadWriteProc) ig->writecb,
1478 (TIFFSeekProc) comp_seek,
1479 (TIFFCloseProc) ig->closecb,
1480 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1481 (TIFFMapFileProc) comp_mmap,
1482 (TIFFUnmapFileProc) comp_munmap);
1487 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1488 i_push_error(0, "Could not create TIFF object");
1489 TIFFSetErrorHandler(old_handler);
1493 if (!i_writetiff_low_faxable(tif, im, fine)) {
1495 TIFFSetErrorHandler(old_handler);
1499 (void) TIFFClose(tif);
1500 TIFFSetErrorHandler(old_handler);
1505 static int save_tiff_tags(TIFF *tif, i_img *im) {
1508 for (i = 0; i < text_tag_count; ++i) {
1510 if (i_tags_find(&im->tags, text_tag_names[i].name, 0, &entry)) {
1511 if (!TIFFSetField(tif, text_tag_names[i].tag,
1512 im->tags.tags[entry].data)) {
1513 i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1524 unpack_4bit_to(unsigned char *dest, const unsigned char *src,
1525 int src_byte_count) {
1526 while (src_byte_count > 0) {
1527 *dest++ = *src >> 4;
1528 *dest++ = *src++ & 0xf;
1533 static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
1536 while (i < pixel_count) {
1538 *dest = *src++ << 4;
1548 make_rgb(TIFF *tif, int width, int height, int *alpha_chan) {
1550 uint16 channels, in_channels;
1554 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1555 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1557 switch (photometric) {
1558 case PHOTOMETRIC_SEPARATED:
1562 case PHOTOMETRIC_MINISWHITE:
1563 case PHOTOMETRIC_MINISBLACK:
1564 /* the TIFF RGBA functions expand single channel grey into RGB,
1565 so reduce it, we move the alpha channel into the right place
1574 /* TIFF images can have more than one alpha channel, but Imager can't
1575 this ignores the possibility of 2 channel images with 2 alpha,
1576 but there's not much I can do about that */
1578 if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)
1580 *alpha_chan = channels++;
1583 return i_img_8_new(width, height, channels);
1587 read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete) {
1589 uint32* raster = NULL;
1590 uint32 rowsperstrip, row;
1595 im = make_rgb(tif, width, height, &alpha_chan);
1599 rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1600 mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
1602 if (rc != 1 || rowsperstrip==-1) {
1603 rowsperstrip = height;
1606 raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
1609 i_push_error(0, "No space for raster buffer");
1613 line_buf = mymalloc(sizeof(i_color) * width);
1615 for( row = 0; row < height; row += rowsperstrip ) {
1616 uint32 newrows, i_row;
1618 if (!TIFFReadRGBAStrip(tif, row, raster)) {
1619 if (allow_incomplete) {
1620 i_tags_setn(&im->tags, "i_lines_read", row);
1621 i_tags_setn(&im->tags, "i_incomplete", 1);
1625 i_push_error(0, "could not read TIFF image strip");
1632 newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
1633 mm_log((1, "newrows=%d\n", newrows));
1635 for( i_row = 0; i_row < newrows; i_row++ ) {
1637 i_color *outp = line_buf;
1639 for(x = 0; x<width; x++) {
1640 uint32 temp = raster[x+width*(newrows-i_row-1)];
1641 outp->rgba.r = TIFFGetR(temp);
1642 outp->rgba.g = TIFFGetG(temp);
1643 outp->rgba.b = TIFFGetB(temp);
1646 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1647 alpha in the right place and scale it */
1649 outp->channel[alpha_chan] = TIFFGetA(temp);
1650 if (outp->channel[alpha_chan]) {
1651 for (ch = 0; ch < alpha_chan; ++ch) {
1652 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1659 i_plin(im, 0, width, i_row+row, line_buf);
1669 /* adapted from libtiff
1671 libtiff's TIFFReadRGBATile succeeds even when asked to read an
1672 invalid tile, which means we have no way of knowing whether the data
1673 we received from it is valid or not.
1675 So the caller here has set stoponerror to 1 so that
1676 TIFFRGBAImageGet() will fail.
1678 read_one_rgb_tiled() then takes that into account for i_incomplete
1682 myTIFFReadRGBATile(TIFFRGBAImage *img, uint32 col, uint32 row, uint32 * raster)
1686 uint32 tile_xsize, tile_ysize;
1687 uint32 read_xsize, read_ysize;
1691 * Verify that our request is legal - on a tile file, and on a
1695 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILEWIDTH, &tile_xsize);
1696 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILELENGTH, &tile_ysize);
1697 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
1699 i_push_errorf(0, "Row/col passed to myTIFFReadRGBATile() must be top"
1700 "left corner of a tile.");
1705 * The TIFFRGBAImageGet() function doesn't allow us to get off the
1706 * edge of the image, even to fill an otherwise valid tile. So we
1707 * figure out how much we can read, and fix up the tile buffer to
1708 * a full tile configuration afterwards.
1711 if( row + tile_ysize > img->height )
1712 read_ysize = img->height - row;
1714 read_ysize = tile_ysize;
1716 if( col + tile_xsize > img->width )
1717 read_xsize = img->width - col;
1719 read_xsize = tile_xsize;
1722 * Read the chunk of imagery.
1725 img->row_offset = row;
1726 img->col_offset = col;
1728 ok = TIFFRGBAImageGet(img, raster, read_xsize, read_ysize );
1731 * If our read was incomplete we will need to fix up the tile by
1732 * shifting the data around as if a full tile of data is being returned.
1734 * This is all the more complicated because the image is organized in
1735 * bottom to top format.
1738 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
1741 for( i_row = 0; i_row < read_ysize; i_row++ ) {
1742 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
1743 raster + (read_ysize - i_row - 1) * read_xsize,
1744 read_xsize * sizeof(uint32) );
1745 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
1746 0, sizeof(uint32) * (tile_xsize - read_xsize) );
1749 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
1750 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
1751 0, sizeof(uint32) * tile_xsize );
1758 read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete) {
1760 uint32* raster = NULL;
1763 uint32 tile_width, tile_height;
1764 unsigned long pixels = 0;
1765 char emsg[1024] = "";
1770 im = make_rgb(tif, width, height, &alpha_chan);
1774 if (!TIFFRGBAImageOK(tif, emsg)
1775 || !TIFFRGBAImageBegin(&img, tif, 1, emsg)) {
1776 i_push_error(0, emsg);
1781 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
1782 TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
1783 mm_log((1, "i_readtiff_wiol: tile_width=%d, tile_height=%d\n", tile_width, tile_height));
1785 raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
1788 i_push_error(0, "No space for raster buffer");
1789 TIFFRGBAImageEnd(&img);
1792 line = mymalloc(tile_width * sizeof(i_color));
1794 for( row = 0; row < height; row += tile_height ) {
1795 for( col = 0; col < width; col += tile_width ) {
1797 /* Read the tile into an RGBA array */
1798 if (myTIFFReadRGBATile(&img, col, row, raster)) {
1800 uint32 newrows = (row+tile_height > height) ? height-row : tile_height;
1801 uint32 newcols = (col+tile_width > width ) ? width-col : tile_width;
1803 mm_log((1, "i_readtiff_wiol: tile(%d, %d) newcols=%d newrows=%d\n", col, row, newcols, newrows));
1804 for( i_row = 0; i_row < newrows; i_row++ ) {
1805 i_color *outp = line;
1806 for(x = 0; x < newcols; x++) {
1807 uint32 temp = raster[x+tile_width*(tile_height-i_row-1)];
1808 outp->rgba.r = TIFFGetR(temp);
1809 outp->rgba.g = TIFFGetG(temp);
1810 outp->rgba.b = TIFFGetB(temp);
1811 outp->rgba.a = TIFFGetA(temp);
1814 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1815 alpha in the right place and scale it */
1817 outp->channel[alpha_chan] = TIFFGetA(temp);
1819 if (outp->channel[alpha_chan]) {
1820 for (ch = 0; ch < alpha_chan; ++ch) {
1821 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1828 i_plin(im, col, col+newcols, row+i_row, line);
1830 pixels += newrows * newcols;
1833 if (allow_incomplete) {
1845 i_push_error(0, "TIFF: No image data could be read from the image");
1849 /* incomplete image */
1850 i_tags_setn(&im->tags, "i_incomplete", 1);
1851 i_tags_setn(&im->tags, "i_lines_read", pixels / width);
1855 TIFFRGBAImageEnd(&img);
1863 TIFFRGBAImageEnd(&img);
1869 i_tiff_libversion(void) {
1870 return TIFFGetVersion();
1874 setup_paletted(read_state_t *state) {
1877 int color_count = 1 << state->bits_per_sample;
1879 state->img = i_img_pal_new(state->width, state->height, 3, 256);
1883 /* setup the color map */
1884 if (!TIFFGetField(state->tif, TIFFTAG_COLORMAP, maps+0, maps+1, maps+2)) {
1885 i_push_error(0, "Cannot get colormap for paletted image");
1886 i_img_destroy(state->img);
1889 for (i = 0; i < color_count; ++i) {
1891 for (ch = 0; ch < 3; ++ch) {
1892 c.channel[ch] = Sample16To8(maps[ch][i]);
1894 i_addcolors(state->img, &c, 1);
1901 tile_contig_getter(read_state_t *state, read_putter_t putter) {
1902 uint32 tile_width, tile_height;
1903 uint32 this_tile_height, this_tile_width;
1904 uint32 rows_left, cols_left;
1907 state->raster = _TIFFmalloc(TIFFTileSize(state->tif));
1908 if (!state->raster) {
1909 i_push_error(0, "tiff: Out of memory allocating tile buffer");
1913 TIFFGetField(state->tif, TIFFTAG_TILEWIDTH, &tile_width);
1914 TIFFGetField(state->tif, TIFFTAG_TILELENGTH, &tile_height);
1915 rows_left = state->height;
1916 for (y = 0; y < state->height; y += this_tile_height) {
1917 this_tile_height = rows_left > tile_height ? tile_height : rows_left;
1919 cols_left = state->width;
1920 for (x = 0; x < state->width; x += this_tile_width) {
1921 this_tile_width = cols_left > tile_width ? tile_width : cols_left;
1923 if (TIFFReadTile(state->tif,
1926 if (!state->allow_incomplete) {
1931 putter(state, x, y, this_tile_width, this_tile_height, tile_width - this_tile_width);
1934 cols_left -= this_tile_width;
1937 rows_left -= this_tile_height;
1944 strip_contig_getter(read_state_t *state, read_putter_t putter) {
1945 uint32 rows_per_strip;
1946 tsize_t strip_size = TIFFStripSize(state->tif);
1947 uint32 y, strip_rows, rows_left;
1949 state->raster = _TIFFmalloc(strip_size);
1950 if (!state->raster) {
1951 i_push_error(0, "tiff: Out of memory allocating strip buffer");
1955 TIFFGetFieldDefaulted(state->tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
1956 rows_left = state->height;
1957 for (y = 0; y < state->height; y += strip_rows) {
1958 strip_rows = rows_left > rows_per_strip ? rows_per_strip : rows_left;
1959 if (TIFFReadEncodedStrip(state->tif,
1960 TIFFComputeStrip(state->tif, y, 0),
1963 if (!state->allow_incomplete)
1967 putter(state, 0, y, state->width, strip_rows, 0);
1969 rows_left -= strip_rows;
1976 paletted_putter8(read_state_t *state, int x, int y, int width, int height, int extras) {
1977 unsigned char *p = state->raster;
1979 state->pixels_read += (unsigned long) width * height;
1980 while (height > 0) {
1981 i_ppal(state->img, x, x + width, y, p);
1982 p += width + extras;
1991 paletted_putter4(read_state_t *state, int x, int y, int width, int height, int extras) {
1992 uint32 img_line_size = (width + 1) / 2;
1993 uint32 skip_line_size = (width + extras + 1) / 2;
1994 unsigned char *p = state->raster;
1996 if (!state->line_buf)
1997 state->line_buf = mymalloc(state->width);
1999 state->pixels_read += (unsigned long) width * height;
2000 while (height > 0) {
2001 unpack_4bit_to(state->line_buf, p, img_line_size);
2002 i_ppal(state->img, x, x + width, y, state->line_buf);
2003 p += skip_line_size;
2012 rgb_channels(read_state_t *state, int *out_channels) {
2018 state->alpha_chan = 0;
2019 state->scale_alpha = 0;
2022 if (state->samples_per_pixel == 3)
2025 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2026 mm_log((1, "tiff: samples != 3 but no extra samples tag\n"));
2031 mm_log((1, "tiff: samples != 3 but no extra samples listed"));
2036 state->alpha_chan = 3;
2038 case EXTRASAMPLE_UNSPECIFIED:
2039 case EXTRASAMPLE_ASSOCALPHA:
2040 state->scale_alpha = 1;
2043 case EXTRASAMPLE_UNASSALPHA:
2044 state->scale_alpha = 0;
2048 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2050 state->scale_alpha = 1;
2053 mm_log((1, "tiff alpha channel %d scale %d\n", state->alpha_chan, state->scale_alpha));
2057 grey_channels(read_state_t *state, int *out_channels) {
2063 state->alpha_chan = 0;
2064 state->scale_alpha = 0;
2067 if (state->samples_per_pixel == 1)
2070 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2071 mm_log((1, "tiff: samples != 1 but no extra samples tag\n"));
2076 mm_log((1, "tiff: samples != 1 but no extra samples listed"));
2081 state->alpha_chan = 1;
2083 case EXTRASAMPLE_UNSPECIFIED:
2084 case EXTRASAMPLE_ASSOCALPHA:
2085 state->scale_alpha = 1;
2088 case EXTRASAMPLE_UNASSALPHA:
2089 state->scale_alpha = 0;
2093 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2095 state->scale_alpha = 1;
2101 setup_16_rgb(read_state_t *state) {
2104 rgb_channels(state, &out_channels);
2106 state->img = i_img_16_new(state->width, state->height, out_channels);
2109 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2115 setup_16_grey(read_state_t *state) {
2118 grey_channels(state, &out_channels);
2120 state->img = i_img_16_new(state->width, state->height, out_channels);
2123 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2129 putter_16(read_state_t *state, int x, int y, int width, int height,
2131 uint16 *p = state->raster;
2132 int out_chan = state->img->channels;
2134 state->pixels_read += (unsigned long) width * height;
2135 while (height > 0) {
2138 unsigned *outp = state->line_buf;
2140 for (i = 0; i < width; ++i) {
2141 for (ch = 0; ch < out_chan; ++ch) {
2144 if (state->alpha_chan && state->scale_alpha && outp[state->alpha_chan]) {
2145 for (ch = 0; ch < state->alpha_chan; ++ch) {
2146 int result = 0.5 + (outp[ch] * 65535.0 / outp[state->alpha_chan]);
2147 outp[ch] = CLAMP16(result);
2150 p += state->samples_per_pixel;
2154 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2156 p += row_extras * state->samples_per_pixel;
2165 setup_8_rgb(read_state_t *state) {
2168 rgb_channels(state, &out_channels);
2170 state->img = i_img_8_new(state->width, state->height, out_channels);
2173 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2179 setup_8_grey(read_state_t *state) {
2182 grey_channels(state, &out_channels);
2184 state->img = i_img_8_new(state->width, state->height, out_channels);
2187 state->line_buf = mymalloc(sizeof(i_color) * state->width * out_channels);
2193 putter_8(read_state_t *state, int x, int y, int width, int height,
2195 unsigned char *p = state->raster;
2196 int out_chan = state->img->channels;
2198 state->pixels_read += (unsigned long) width * height;
2199 while (height > 0) {
2202 i_color *outp = state->line_buf;
2204 for (i = 0; i < width; ++i) {
2205 for (ch = 0; ch < out_chan; ++ch) {
2206 outp->channel[ch] = p[ch];
2208 if (state->alpha_chan && state->scale_alpha
2209 && outp->channel[state->alpha_chan]) {
2210 for (ch = 0; ch < state->alpha_chan; ++ch) {
2211 int result = (outp->channel[ch] * 255 + 127) / outp->channel[state->alpha_chan];
2213 outp->channel[ch] = CLAMP8(result);
2216 p += state->samples_per_pixel;
2220 i_plin(state->img, x, x + width, y, state->line_buf);
2222 p += row_extras * state->samples_per_pixel;
2231 setup_32_rgb(read_state_t *state) {
2234 rgb_channels(state, &out_channels);
2236 state->img = i_img_double_new(state->width, state->height, out_channels);
2239 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2245 setup_32_grey(read_state_t *state) {
2248 grey_channels(state, &out_channels);
2250 state->img = i_img_double_new(state->width, state->height, out_channels);
2253 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2259 putter_32(read_state_t *state, int x, int y, int width, int height,
2261 uint32 *p = state->raster;
2262 int out_chan = state->img->channels;
2264 state->pixels_read += (unsigned long) width * height;
2265 while (height > 0) {
2268 i_fcolor *outp = state->line_buf;
2270 for (i = 0; i < width; ++i) {
2271 for (ch = 0; ch < out_chan; ++ch) {
2272 outp->channel[ch] = p[ch] / 4294967295.0;
2274 if (state->alpha_chan && state->scale_alpha && outp->channel[state->alpha_chan]) {
2275 for (ch = 0; ch < state->alpha_chan; ++ch)
2276 outp->channel[ch] /= outp->channel[state->alpha_chan];
2278 p += state->samples_per_pixel;
2282 i_plinf(state->img, x, x + width, y, state->line_buf);
2284 p += row_extras * state->samples_per_pixel;
2293 setup_bilevel(read_state_t *state) {
2294 i_color black, white;
2295 state->img = i_img_pal_new(state->width, state->height, 1, 256);
2298 black.channel[0] = black.channel[1] = black.channel[2] =
2299 black.channel[3] = 0;
2300 white.channel[0] = white.channel[1] = white.channel[2] =
2301 white.channel[3] = 255;
2302 if (state->photometric == PHOTOMETRIC_MINISBLACK) {
2303 i_addcolors(state->img, &black, 1);
2304 i_addcolors(state->img, &white, 1);
2307 i_addcolors(state->img, &white, 1);
2308 i_addcolors(state->img, &black, 1);
2310 state->line_buf = mymalloc(state->width);
2316 putter_bilevel(read_state_t *state, int x, int y, int width, int height,
2318 unsigned char *line_in = state->raster;
2319 size_t line_size = (width + row_extras + 7) / 8;
2321 /* tifflib returns the bits in MSB2LSB order even when the file is
2322 in LSB2MSB, so we only need to handle MSB2LSB */
2323 state->pixels_read += (unsigned long) width * height;
2324 while (height > 0) {
2326 unsigned char *outp = state->line_buf;
2327 unsigned char *inp = line_in;
2328 unsigned mask = 0x80;
2330 for (i = 0; i < width; ++i) {
2331 *outp++ = *inp & mask ? 1 : 0;
2339 i_ppal(state->img, x, x + width, y, state->line_buf);
2341 line_in += line_size;
2350 cmyk_channels(read_state_t *state, int *out_channels) {
2356 state->alpha_chan = 0;
2357 state->scale_alpha = 0;
2360 if (state->samples_per_pixel == 4)
2363 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2364 mm_log((1, "tiff: CMYK samples != 4 but no extra samples tag\n"));
2369 mm_log((1, "tiff: CMYK samples != 4 but no extra samples listed"));
2374 state->alpha_chan = 4;
2376 case EXTRASAMPLE_UNSPECIFIED:
2377 case EXTRASAMPLE_ASSOCALPHA:
2378 state->scale_alpha = 1;
2381 case EXTRASAMPLE_UNASSALPHA:
2382 state->scale_alpha = 0;
2386 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2388 state->scale_alpha = 1;
2394 setup_cmyk8(read_state_t *state) {
2397 cmyk_channels(state, &channels);
2398 state->img = i_img_8_new(state->width, state->height, channels);
2400 state->line_buf = mymalloc(sizeof(i_color) * state->width);
2406 putter_cmyk8(read_state_t *state, int x, int y, int width, int height,
2408 unsigned char *p = state->raster;
2410 state->pixels_read += (unsigned long) width * height;
2411 while (height > 0) {
2414 i_color *outp = state->line_buf;
2416 for (i = 0; i < width; ++i) {
2417 unsigned char c, m, y, k;
2422 outp->rgba.r = (k * (255 - c)) / 255;
2423 outp->rgba.g = (k * (255 - m)) / 255;
2424 outp->rgba.b = (k * (255 - y)) / 255;
2425 if (state->alpha_chan) {
2426 outp->rgba.a = p[state->alpha_chan];
2427 if (state->scale_alpha
2429 for (ch = 0; ch < 3; ++ch) {
2430 int result = (outp->channel[ch] * 255 + 127) / outp->rgba.a;
2431 outp->channel[ch] = CLAMP8(result);
2435 p += state->samples_per_pixel;
2439 i_plin(state->img, x, x + width, y, state->line_buf);
2441 p += row_extras * state->samples_per_pixel;
2450 setup_cmyk16(read_state_t *state) {
2453 cmyk_channels(state, &channels);
2454 state->img = i_img_16_new(state->width, state->height, channels);
2456 state->line_buf = mymalloc(sizeof(unsigned) * state->width * channels);
2462 putter_cmyk16(read_state_t *state, int x, int y, int width, int height,
2464 uint16 *p = state->raster;
2465 int out_chan = state->img->channels;
2467 mm_log((4, "putter_cmyk16(%p, %d, %d, %d, %d, %d)\n", x, y, width, height, row_extras));
2469 state->pixels_read += (unsigned long) width * height;
2470 while (height > 0) {
2473 unsigned *outp = state->line_buf;
2475 for (i = 0; i < width; ++i) {
2476 unsigned c, m, y, k;
2481 outp[0] = (k * (65535U - c)) / 65535U;
2482 outp[1] = (k * (65535U - m)) / 65535U;
2483 outp[2] = (k * (65535U - y)) / 65535U;
2484 if (state->alpha_chan) {
2485 outp[3] = p[state->alpha_chan];
2486 if (state->scale_alpha
2488 for (ch = 0; ch < 3; ++ch) {
2489 int result = (outp[ch] * 65535 + 32767) / outp[3];
2490 outp[3] = CLAMP16(result);
2494 p += state->samples_per_pixel;
2498 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2500 p += row_extras * state->samples_per_pixel;
2510 Older versions of tifflib we support don't define this, so define it
2513 If you want this detection to do anything useful, use a newer
2517 #if TIFFLIB_VERSION < 20031121
2520 TIFFIsCODECConfigured(uint16 scheme) {
2522 /* these schemes are all shipped with tifflib */
2523 case COMPRESSION_NONE:
2524 case COMPRESSION_PACKBITS:
2525 case COMPRESSION_CCITTRLE:
2526 case COMPRESSION_CCITTRLEW:
2527 case COMPRESSION_CCITTFAX3:
2528 case COMPRESSION_CCITTFAX4:
2531 /* these require external library support */
2533 case COMPRESSION_JPEG:
2534 case COMPRESSION_LZW:
2535 case COMPRESSION_DEFLATE:
2536 case COMPRESSION_ADOBE_DEFLATE:
2544 myTIFFIsCODECConfigured(uint16 scheme) {
2545 #if TIFFLIB_VERSION < 20040724
2546 if (scheme == COMPRESSION_LZW)
2550 return TIFFIsCODECConfigured(scheme);
2558 Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tony@imager.perl.org>