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))
46 #define Sample16To8(num) ((num) / 257)
53 static i_img *read_one_rgb_tiled(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete);
54 static i_img *read_one_rgb_lines(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete);
56 static struct tag_name text_tag_names[] =
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, },
69 static struct tag_name
72 { "none", COMPRESSION_NONE },
73 { "ccittrle", COMPRESSION_CCITTRLE },
74 { "fax3", COMPRESSION_CCITTFAX3 },
75 { "t4", COMPRESSION_CCITTFAX3 },
76 { "fax4", COMPRESSION_CCITTFAX4 },
77 { "t6", COMPRESSION_CCITTFAX4 },
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 },
87 static const int compress_value_count =
88 sizeof(compress_values) / sizeof(*compress_values);
90 static struct tag_name
91 sample_format_values[] =
93 { "uint", SAMPLEFORMAT_UINT },
94 { "int", SAMPLEFORMAT_INT },
95 { "ieeefp", SAMPLEFORMAT_IEEEFP },
96 { "undefined", SAMPLEFORMAT_VOID },
99 static const int sample_format_value_count =
100 sizeof(sample_format_values) / sizeof(*sample_format_values);
103 myTIFFIsCODECConfigured(uint16 scheme);
105 typedef struct read_state_tag read_state_t;
106 /* the setup function creates the image object, allocates the line buffer */
107 typedef int (*read_setup_t)(read_state_t *state);
109 /* the putter writes the image data provided by the getter to the
110 image, x, y, width, height describe the target area of the image,
111 extras is the extra number of pixels stored for each scanline in
112 the raster buffer, (for tiles against the right side of the
115 typedef int (*read_putter_t)(read_state_t *state, i_img_dim x, i_img_dim y,
116 i_img_dim width, i_img_dim height, int extras);
118 /* reads from a tiled or strip image and calls the putter.
119 This may need a second type for handling non-contiguous images
121 typedef int (*read_getter_t)(read_state_t *state, read_putter_t putter);
123 struct read_state_tag {
127 i_img_dim pixels_read;
128 int allow_incomplete;
130 uint32 width, height;
131 uint16 bits_per_sample;
134 /* the total number of channels (samples per pixel) */
135 int samples_per_pixel;
137 /* if non-zero, which channel is the alpha channel, typically 3 for rgb */
140 /* whether or not to scale the color channels based on the alpha
141 channel. TIFF has 2 types of alpha channel, if the alpha channel
142 we use is EXTRASAMPLE_ASSOCALPHA then the color data will need to
143 be scaled to match Imager's conventions */
146 /* number of color samples (not including alpha) */
149 /* SampleFormat is 2 */
155 static int tile_contig_getter(read_state_t *state, read_putter_t putter);
156 static int strip_contig_getter(read_state_t *state, read_putter_t putter);
158 static int setup_paletted(read_state_t *state);
159 static int paletted_putter8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
160 static int paletted_putter4(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
162 static int setup_16_rgb(read_state_t *state);
163 static int setup_16_grey(read_state_t *state);
164 static int putter_16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
166 static int setup_8_rgb(read_state_t *state);
167 static int setup_8_grey(read_state_t *state);
168 static int putter_8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
170 static int setup_32_rgb(read_state_t *state);
171 static int setup_32_grey(read_state_t *state);
172 static int putter_32(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
174 static int setup_bilevel(read_state_t *state);
175 static int putter_bilevel(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
177 static int setup_cmyk8(read_state_t *state);
178 static int putter_cmyk8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
180 static int setup_cmyk16(read_state_t *state);
181 static int putter_cmyk16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
183 rgb_channels(read_state_t *state, int *out_channels);
185 grey_channels(read_state_t *state, int *out_channels);
187 cmyk_channels(read_state_t *state, int *out_channels);
189 fallback_rgb_channels(TIFF *tif, i_img_dim width, i_img_dim height, int *channels, int *alpha_chan);
191 static const int text_tag_count =
192 sizeof(text_tag_names) / sizeof(*text_tag_names);
194 #if TIFFLIB_VERSION >= 20051230
195 #define USE_EXT_WARN_HANDLER
198 #define TIFFIO_MAGIC 0xC6A340CC
200 static void error_handler(char const *module, char const *fmt, va_list ap) {
201 mm_log((1, "tiff error fmt %s\n", fmt));
202 i_push_errorvf(0, fmt, ap);
208 #ifdef USE_EXT_WARN_HANDLER
215 tiffio_context_init(tiffio_context_t *c, io_glue *ig);
217 tiffio_context_final(tiffio_context_t *c);
219 #define WARN_BUFFER_LIMIT 10000
221 #ifdef USE_EXT_WARN_HANDLER
224 warn_handler_ex(thandle_t h, const char *module, const char *fmt, va_list ap) {
225 tiffio_context_t *c = (tiffio_context_t *)h;
228 if (c->magic != TIFFIO_MAGIC)
232 #ifdef IMAGER_VSNPRINTF
233 vsnprintf(buf, sizeof(buf), fmt, ap);
235 vsprintf(buf, fmt, ap);
237 mm_log((1, "tiff warning %s\n", buf));
239 if (!c->warn_buffer || strlen(c->warn_buffer)+strlen(buf)+2 > c->warn_size) {
240 size_t new_size = c->warn_size + strlen(buf) + 2;
241 char *old_buffer = c->warn_buffer;
242 if (new_size > WARN_BUFFER_LIMIT) {
243 new_size = WARN_BUFFER_LIMIT;
245 c->warn_buffer = myrealloc(c->warn_buffer, new_size);
246 if (!old_buffer) c->warn_buffer[0] = '\0';
247 c->warn_size = new_size;
249 if (strlen(c->warn_buffer)+strlen(buf)+2 <= c->warn_size) {
250 strcat(c->warn_buffer, buf);
251 strcat(c->warn_buffer, "\n");
257 static char *warn_buffer = NULL;
258 static int warn_buffer_size = 0;
260 static void warn_handler(char const *module, char const *fmt, va_list ap) {
264 #ifdef IMAGER_VSNPRINTF
265 vsnprintf(buf, sizeof(buf), fmt, ap);
267 vsprintf(buf, fmt, ap);
269 mm_log((1, "tiff warning %s\n", buf));
271 if (!warn_buffer || strlen(warn_buffer)+strlen(buf)+2 > warn_buffer_size) {
272 int new_size = warn_buffer_size + strlen(buf) + 2;
273 char *old_buffer = warn_buffer;
274 if (new_size > WARN_BUFFER_LIMIT) {
275 new_size = WARN_BUFFER_LIMIT;
277 warn_buffer = myrealloc(warn_buffer, new_size);
278 if (!old_buffer) *warn_buffer = '\0';
279 warn_buffer_size = new_size;
281 if (strlen(warn_buffer)+strlen(buf)+2 <= warn_buffer_size) {
282 strcat(warn_buffer, buf);
283 strcat(warn_buffer, "\n");
289 static i_mutex_t mutex;
293 mutex = i_mutex_new();
296 static int save_tiff_tags(TIFF *tif, i_img *im);
299 pack_4bit_to(unsigned char *dest, const unsigned char *src, i_img_dim count);
302 static toff_t sizeproc(thandle_t x) {
308 =item comp_seek(h, o, w)
310 Compatability for 64 bit systems like latest freebsd (internal)
312 h - tiff handle, cast an io_glue object
321 comp_seek(thandle_t h, toff_t o, int w) {
322 io_glue *ig = ((tiffio_context_t *)h)->ig;
323 return (toff_t) i_io_seek(ig, o, w);
327 =item comp_mmap(thandle_t, tdata_t*, toff_t*)
331 This shouldn't ever be called but newer tifflibs want it anyway.
338 comp_mmap(thandle_t h, tdata_t*p, toff_t*off) {
343 =item comp_munmap(thandle_t h, tdata_t p, toff_t off)
347 This shouldn't ever be called but newer tifflibs want it anyway.
353 comp_munmap(thandle_t h, tdata_t p, toff_t off) {
358 comp_read(thandle_t h, tdata_t p, tsize_t size) {
359 return i_io_read(((tiffio_context_t *)h)->ig, p, size);
363 comp_write(thandle_t h, tdata_t p, tsize_t size) {
364 return i_io_write(((tiffio_context_t *)h)->ig, p, size);
368 comp_close(thandle_t h) {
369 return i_io_close(((tiffio_context_t *)h)->ig);
372 static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
374 uint32 width, height;
375 uint16 samples_per_pixel;
379 int gotXres, gotYres;
381 uint16 bits_per_sample;
382 uint16 planar_config;
385 uint16 sample_format;
388 read_setup_t setupf = NULL;
389 read_getter_t getterf = NULL;
390 read_putter_t putterf = NULL;
391 int channels = MAXCHANNELS;
392 size_t sample_size = ~0; /* force failure if some code doesn't set it */
393 i_img_dim total_pixels;
394 int samples_integral;
396 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
397 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
398 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
399 tiled = TIFFIsTiled(tif);
400 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
401 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
402 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
403 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
405 if (samples_per_pixel == 0) {
406 i_push_error(0, "invalid image: SamplesPerPixel is 0");
410 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &sample_format);
412 mm_log((1, "i_readtiff_wiol: width=%d, height=%d, channels=%d\n", width, height, samples_per_pixel));
413 mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
414 mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
416 total_pixels = width * height;
417 memset(&state, 0, sizeof(state));
419 state.allow_incomplete = allow_incomplete;
421 state.height = height;
422 state.bits_per_sample = bits_per_sample;
423 state.samples_per_pixel = samples_per_pixel;
424 state.photometric = photometric;
425 state.sample_signed = sample_format == SAMPLEFORMAT_INT;
426 state.sample_format = sample_format;
428 samples_integral = sample_format == SAMPLEFORMAT_UINT
429 || sample_format == SAMPLEFORMAT_INT
430 || sample_format == SAMPLEFORMAT_VOID; /* sample as UINT */
432 /* yes, this if() is horrible */
433 if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8
434 && samples_integral) {
435 setupf = setup_paletted;
436 if (bits_per_sample == 8)
437 putterf = paletted_putter8;
438 else if (bits_per_sample == 4)
439 putterf = paletted_putter4;
441 mm_log((1, "unsupported paletted bits_per_sample %d\n", bits_per_sample));
443 sample_size = sizeof(i_sample_t);
446 else if (bits_per_sample == 16
447 && photometric == PHOTOMETRIC_RGB
448 && samples_per_pixel >= 3
449 && samples_integral) {
450 setupf = setup_16_rgb;
453 rgb_channels(&state, &channels);
455 else if (bits_per_sample == 16
456 && photometric == PHOTOMETRIC_MINISBLACK
457 && samples_integral) {
458 setupf = setup_16_grey;
461 grey_channels(&state, &channels);
463 else if (bits_per_sample == 8
464 && photometric == PHOTOMETRIC_MINISBLACK
465 && samples_integral) {
466 setupf = setup_8_grey;
469 grey_channels(&state, &channels);
471 else if (bits_per_sample == 8
472 && photometric == PHOTOMETRIC_RGB
473 && samples_integral) {
474 setupf = setup_8_rgb;
477 rgb_channels(&state, &channels);
479 else if (bits_per_sample == 32
480 && photometric == PHOTOMETRIC_RGB
481 && samples_per_pixel >= 3) {
482 setupf = setup_32_rgb;
484 sample_size = sizeof(i_fsample_t);
485 rgb_channels(&state, &channels);
487 else if (bits_per_sample == 32
488 && photometric == PHOTOMETRIC_MINISBLACK) {
489 setupf = setup_32_grey;
491 sample_size = sizeof(i_fsample_t);
492 grey_channels(&state, &channels);
494 else if (bits_per_sample == 1
495 && (photometric == PHOTOMETRIC_MINISBLACK
496 || photometric == PHOTOMETRIC_MINISWHITE)
497 && samples_per_pixel == 1) {
498 setupf = setup_bilevel;
499 putterf = putter_bilevel;
500 sample_size = sizeof(i_palidx);
503 else if (bits_per_sample == 8
504 && photometric == PHOTOMETRIC_SEPARATED
505 && inkset == INKSET_CMYK
506 && samples_per_pixel >= 4
507 && samples_integral) {
508 setupf = setup_cmyk8;
509 putterf = putter_cmyk8;
511 cmyk_channels(&state, &channels);
513 else if (bits_per_sample == 16
514 && photometric == PHOTOMETRIC_SEPARATED
515 && inkset == INKSET_CMYK
516 && samples_per_pixel >= 4
517 && samples_integral) {
518 setupf = setup_cmyk16;
519 putterf = putter_cmyk16;
521 cmyk_channels(&state, &channels);
525 fallback_rgb_channels(tif, width, height, &channels, &alpha);
529 if (!i_int_check_image_file_limits(width, height, channels, sample_size)) {
534 if (planar_config == PLANARCONFIG_CONTIG)
535 getterf = tile_contig_getter;
538 if (planar_config == PLANARCONFIG_CONTIG)
539 getterf = strip_contig_getter;
541 if (setupf && getterf && putterf) {
545 if (!getterf(&state, putterf) || !state.pixels_read) {
547 i_img_destroy(state.img);
549 _TIFFfree(state.raster);
551 myfree(state.line_buf);
556 if (allow_incomplete && state.pixels_read < total_pixels) {
557 i_tags_setn(&(state.img->tags), "i_incomplete", 1);
558 i_tags_setn(&(state.img->tags), "i_lines_read",
559 state.pixels_read / width);
564 _TIFFfree(state.raster);
566 myfree(state.line_buf);
570 im = read_one_rgb_tiled(tif, width, height, allow_incomplete);
573 im = read_one_rgb_lines(tif, width, height, allow_incomplete);
580 /* general metadata */
581 i_tags_setn(&im->tags, "tiff_bitspersample", bits_per_sample);
582 i_tags_setn(&im->tags, "tiff_photometric", photometric);
583 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
585 /* resolution tags */
586 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
587 gotXres = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
588 gotYres = TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
589 if (gotXres || gotYres) {
594 i_tags_setn(&im->tags, "tiff_resolutionunit", resunit);
595 if (resunit == RESUNIT_CENTIMETER) {
596 /* from dots per cm to dpi */
599 i_tags_set(&im->tags, "tiff_resolutionunit_name", "centimeter", -1);
601 else if (resunit == RESUNIT_NONE) {
602 i_tags_setn(&im->tags, "i_aspect_only", 1);
603 i_tags_set(&im->tags, "tiff_resolutionunit_name", "none", -1);
605 else if (resunit == RESUNIT_INCH) {
606 i_tags_set(&im->tags, "tiff_resolutionunit_name", "inch", -1);
609 i_tags_set(&im->tags, "tiff_resolutionunit_name", "unknown", -1);
611 /* tifflib doesn't seem to provide a way to get to the original rational
612 value of these, which would let me provide a more reasonable
613 precision. So make up a number. */
614 i_tags_set_float2(&im->tags, "i_xres", 0, xres, 6);
615 i_tags_set_float2(&im->tags, "i_yres", 0, yres, 6);
619 for (i = 0; i < text_tag_count; ++i) {
621 if (TIFFGetField(tif, text_tag_names[i].tag, &data)) {
622 mm_log((1, "i_readtiff_wiol: tag %d has value %s\n",
623 text_tag_names[i].tag, data));
624 i_tags_set(&im->tags, text_tag_names[i].name, data, -1);
628 i_tags_set(&im->tags, "i_format", "tiff", 4);
629 #ifdef USE_EXT_WARN_HANDLER
631 tiffio_context_t *ctx = TIFFClientdata(tif);
632 if (ctx->warn_buffer && ctx->warn_buffer[0]) {
633 i_tags_set(&im->tags, "i_warning", ctx->warn_buffer, -1);
634 ctx->warn_buffer[0] = '\0';
638 if (warn_buffer && *warn_buffer) {
639 i_tags_set(&im->tags, "i_warning", warn_buffer, -1);
644 for (i = 0; i < compress_value_count; ++i) {
645 if (compress_values[i].tag == compress) {
646 i_tags_set(&im->tags, "tiff_compression", compress_values[i].name, -1);
651 if (TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sample_format)) {
652 /* only set the tag if the the TIFF tag is present */
653 i_tags_setn(&im->tags, "tiff_sample_format", sample_format);
655 for (i = 0; i < sample_format_value_count; ++i) {
656 if (sample_format_values[i].tag == sample_format) {
657 i_tags_set(&im->tags, "tiff_sample_format_name",
658 sample_format_values[i].name, -1);
668 =item i_readtiff_wiol(ig, allow_incomplete, page)
673 i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
675 TIFFErrorHandler old_handler;
676 TIFFErrorHandler old_warn_handler;
677 #ifdef USE_EXT_WARN_HANDLER
678 TIFFErrorHandlerExt old_ext_warn_handler;
682 tiffio_context_t ctx;
687 old_handler = TIFFSetErrorHandler(error_handler);
688 #ifdef USE_EXT_WARN_HANDLER
689 old_warn_handler = TIFFSetWarningHandler(NULL);
690 old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex);
692 old_warn_handler = TIFFSetWarningHandler(warn_handler);
697 /* Add code to get the filename info from the iolayer */
698 /* Also add code to check for mmapped code */
700 mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
702 tiffio_context_init(&ctx, ig);
703 tif = TIFFClientOpen("(Iolayer)",
715 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
716 i_push_error(0, "Error opening file");
717 TIFFSetErrorHandler(old_handler);
718 TIFFSetWarningHandler(old_warn_handler);
719 #ifdef USE_EXT_WARN_HANDLER
720 TIFFSetWarningHandlerExt(old_ext_warn_handler);
722 tiffio_context_final(&ctx);
723 i_mutex_unlock(mutex);
727 for (current_page = 0; current_page < page; ++current_page) {
728 if (!TIFFReadDirectory(tif)) {
729 mm_log((1, "i_readtiff_wiol: Unable to switch to directory %d\n", page));
730 i_push_errorf(0, "could not switch to page %d", page);
731 TIFFSetErrorHandler(old_handler);
732 TIFFSetWarningHandler(old_warn_handler);
733 #ifdef USE_EXT_WARN_HANDLER
734 TIFFSetWarningHandlerExt(old_ext_warn_handler);
737 tiffio_context_final(&ctx);
738 i_mutex_unlock(mutex);
743 im = read_one_tiff(tif, allow_incomplete);
745 if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
746 TIFFSetErrorHandler(old_handler);
747 TIFFSetWarningHandler(old_warn_handler);
748 #ifdef USE_EXT_WARN_HANDLER
749 TIFFSetWarningHandlerExt(old_ext_warn_handler);
752 tiffio_context_final(&ctx);
753 i_mutex_unlock(mutex);
759 =item i_readtiff_multi_wiol(ig, *count)
761 Reads multiple images from a TIFF.
766 i_readtiff_multi_wiol(io_glue *ig, int *count) {
768 TIFFErrorHandler old_handler;
769 TIFFErrorHandler old_warn_handler;
770 #ifdef USE_EXT_WARN_HANDLER
771 TIFFErrorHandlerExt old_ext_warn_handler;
773 i_img **results = NULL;
774 int result_alloc = 0;
775 tiffio_context_t ctx;
780 old_handler = TIFFSetErrorHandler(error_handler);
781 #ifdef USE_EXT_WARN_HANDLER
782 old_warn_handler = TIFFSetWarningHandler(NULL);
783 old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex);
785 old_warn_handler = TIFFSetWarningHandler(warn_handler);
790 tiffio_context_init(&ctx, ig);
792 /* Add code to get the filename info from the iolayer */
793 /* Also add code to check for mmapped code */
795 mm_log((1, "i_readtiff_wiol(ig %p)\n", ig));
797 tif = TIFFClientOpen("(Iolayer)",
809 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
810 i_push_error(0, "Error opening file");
811 TIFFSetErrorHandler(old_handler);
812 TIFFSetWarningHandler(old_warn_handler);
813 #ifdef USE_EXT_WARN_HANDLER
814 TIFFSetWarningHandlerExt(old_ext_warn_handler);
816 tiffio_context_final(&ctx);
817 i_mutex_unlock(mutex);
823 i_img *im = read_one_tiff(tif, 0);
826 if (++*count > result_alloc) {
827 if (result_alloc == 0) {
829 results = mymalloc(result_alloc * sizeof(i_img *));
834 newresults = myrealloc(results, result_alloc * sizeof(i_img *));
836 i_img_destroy(im); /* don't leak it */
839 results = newresults;
842 results[*count-1] = im;
843 } while (TIFFReadDirectory(tif));
845 TIFFSetWarningHandler(old_warn_handler);
846 TIFFSetErrorHandler(old_handler);
847 #ifdef USE_EXT_WARN_HANDLER
848 TIFFSetWarningHandlerExt(old_ext_warn_handler);
851 tiffio_context_final(&ctx);
852 i_mutex_unlock(mutex);
858 i_writetiff_low_faxable(TIFF *tif, i_img *im, int fine) {
859 uint32 width, height;
860 unsigned char *linebuf = NULL;
865 float vres = fine ? 196 : 98;
871 if (width != im->xsize || height != im->ysize) {
872 i_push_error(0, "image too large for TIFF");
876 switch (im->channels) {
886 /* This means a colorspace we don't handle yet */
887 mm_log((1, "i_writetiff_wiol_faxable: don't handle %d channel images.\n", im->channels));
891 /* Add code to get the filename info from the iolayer */
892 /* Also add code to check for mmapped code */
895 mm_log((1, "i_writetiff_wiol_faxable: width=%d, height=%d, channels=%d\n", width, height, im->channels));
897 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width) )
898 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField width=%d failed\n", width)); return 0; }
899 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height) )
900 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField length=%d failed\n", height)); return 0; }
901 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
902 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField samplesperpixel=1 failed\n")); return 0; }
903 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT))
904 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Orientation=topleft\n")); return 0; }
905 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1) )
906 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField bitpersample=1\n")); return 0; }
907 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG))
908 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField planarconfig\n")); return 0; }
909 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
910 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField photometric=%d\n", PHOTOMETRIC_MINISBLACK)); return 0; }
911 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, 3))
912 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField compression=3\n")); return 0; }
914 linebuf = (unsigned char *)_TIFFmalloc( TIFFScanlineSize(tif) );
916 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
917 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField rowsperstrip=-1\n")); return 0; }
919 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
920 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rc);
922 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField rowsperstrip=%d\n", rowsperstrip));
923 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField scanlinesize=%lu\n",
924 (unsigned long)TIFFScanlineSize(tif) ));
925 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField planarconfig=%d == %d\n", rc, PLANARCONFIG_CONTIG));
927 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)204))
928 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Xresolution=204\n")); return 0; }
929 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, vres))
930 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Yresolution=196\n")); return 0; }
931 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)) {
932 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField ResolutionUnit=%d\n", RESUNIT_INCH)); return 0;
935 if (!save_tiff_tags(tif, im)) {
939 for (y=0; y<height; y++) {
941 for(x=0; x<width; x+=8) {
946 linebuf[linebufpos]=0;
947 bits = width-x; if(bits>8) bits=8;
948 i_gsamp(im, x, x+8, y, luma, &luma_chan, 1);
949 for(bitpos=0;bitpos<bits;bitpos++) {
950 linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
955 if (TIFFWriteScanline(tif, linebuf, y, 0) < 0) {
956 mm_log((1, "i_writetiff_wiol_faxable: TIFFWriteScanline failed.\n"));
960 if (linebuf) _TIFFfree(linebuf);
966 find_compression(char const *name, uint16 *compress) {
969 for (i = 0; i < compress_value_count; ++i) {
970 if (strcmp(compress_values[i].name, name) == 0) {
971 *compress = (uint16)compress_values[i].tag;
975 *compress = COMPRESSION_NONE;
981 get_compression(i_img *im, uint16 def_compress) {
985 if (i_tags_find(&im->tags, "tiff_compression", 0, &entry)
986 && im->tags.tags[entry].data) {
988 if (find_compression(im->tags.tags[entry].data, &compress)
989 && myTIFFIsCODECConfigured(compress))
992 if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
993 if ((uint16)value == value
994 && myTIFFIsCODECConfigured((uint16)value))
995 return (uint16)value;
1002 i_tiff_has_compression(const char *name) {
1005 if (!find_compression(name, &compress))
1008 return myTIFFIsCODECConfigured(compress);
1012 set_base_tags(TIFF *tif, i_img *im, uint16 compress, uint16 photometric,
1013 uint16 bits_per_sample, uint16 samples_per_pixel) {
1016 int got_xres, got_yres;
1019 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->xsize)) {
1020 i_push_error(0, "write TIFF: setting width tag");
1023 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
1024 i_push_error(0, "write TIFF: setting length tag");
1027 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
1028 i_push_error(0, "write TIFF: setting orientation tag");
1031 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
1032 i_push_error(0, "write TIFF: setting planar configuration tag");
1035 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
1036 i_push_error(0, "write TIFF: setting photometric tag");
1039 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
1040 i_push_error(0, "write TIFF: setting compression tag");
1043 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
1044 i_push_error(0, "write TIFF: setting bits per sample tag");
1047 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
1048 i_push_error(0, "write TIFF: setting samples per pixel tag");
1052 got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
1053 got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
1054 if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
1056 if (!i_tags_get_int(&im->tags, "tiff_resolutionunit", 0, &resunit))
1057 resunit = RESUNIT_INCH;
1058 if (got_xres || got_yres) {
1064 resunit = RESUNIT_NONE;
1067 if (resunit == RESUNIT_CENTIMETER) {
1072 resunit = RESUNIT_INCH;
1075 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xres)) {
1076 i_push_error(0, "write TIFF: setting xresolution tag");
1079 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
1080 i_push_error(0, "write TIFF: setting yresolution tag");
1083 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
1084 i_push_error(0, "write TIFF: setting resolutionunit tag");
1093 write_one_bilevel(TIFF *tif, i_img *im, int zero_is_white) {
1094 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1096 unsigned char *in_row;
1097 unsigned char *out_row;
1102 mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n",
1103 tif, im, zero_is_white));
1105 /* ignore a silly choice */
1106 if (compress == COMPRESSION_JPEG)
1107 compress = COMPRESSION_PACKBITS;
1110 case COMPRESSION_CCITTRLE:
1111 case COMPRESSION_CCITTFAX3:
1112 case COMPRESSION_CCITTFAX4:
1113 /* natural fax photometric */
1114 photometric = PHOTOMETRIC_MINISWHITE;
1118 /* natural for most computer images */
1119 photometric = PHOTOMETRIC_MINISBLACK;
1123 if (!set_base_tags(tif, im, compress, photometric, 1, 1))
1126 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1127 i_push_error(0, "write TIFF: setting rows per strip tag");
1131 out_size = TIFFScanlineSize(tif);
1132 out_row = (unsigned char *)_TIFFmalloc( out_size );
1133 in_row = mymalloc(im->xsize);
1135 invert = (photometric == PHOTOMETRIC_MINISWHITE) != (zero_is_white != 0);
1137 for (y = 0; y < im->ysize; ++y) {
1139 unsigned char *outp = out_row;
1140 memset(out_row, 0, out_size);
1141 i_gpal(im, 0, im->xsize, y, in_row);
1142 for (x = 0; x < im->xsize; ++x) {
1143 if (invert ? !in_row[x] : in_row[x]) {
1152 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1155 i_push_error(0, "write TIFF: write scan line failed");
1167 set_palette(TIFF *tif, i_img *im, int size) {
1174 colors = (uint16 *)_TIFFmalloc(sizeof(uint16) * 3 * size);
1176 out[1] = colors + size;
1177 out[2] = colors + 2 * size;
1179 count = i_colorcount(im);
1180 for (i = 0; i < count; ++i) {
1181 i_getcolors(im, i, &c, 1);
1182 for (ch = 0; ch < 3; ++ch)
1183 out[ch][i] = c.channel[ch] * 257;
1185 for (; i < size; ++i) {
1186 for (ch = 0; ch < 3; ++ch)
1189 if (!TIFFSetField(tif, TIFFTAG_COLORMAP, out[0], out[1], out[2])) {
1191 i_push_error(0, "write TIFF: setting color map");
1200 write_one_paletted8(TIFF *tif, i_img *im) {
1201 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1202 unsigned char *out_row;
1206 mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
1208 /* ignore a silly choice */
1209 if (compress == COMPRESSION_JPEG ||
1210 compress == COMPRESSION_CCITTRLE ||
1211 compress == COMPRESSION_CCITTFAX3 ||
1212 compress == COMPRESSION_CCITTFAX4)
1213 compress = COMPRESSION_PACKBITS;
1215 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1216 i_push_error(0, "write TIFF: setting rows per strip tag");
1220 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
1223 if (!set_palette(tif, im, 256))
1226 out_size = TIFFScanlineSize(tif);
1227 out_row = (unsigned char *)_TIFFmalloc( out_size );
1229 for (y = 0; y < im->ysize; ++y) {
1230 i_gpal(im, 0, im->xsize, y, out_row);
1231 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1233 i_push_error(0, "write TIFF: write scan line failed");
1244 write_one_paletted4(TIFF *tif, i_img *im) {
1245 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1246 unsigned char *in_row;
1247 unsigned char *out_row;
1251 mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
1253 /* ignore a silly choice */
1254 if (compress == COMPRESSION_JPEG ||
1255 compress == COMPRESSION_CCITTRLE ||
1256 compress == COMPRESSION_CCITTFAX3 ||
1257 compress == COMPRESSION_CCITTFAX4)
1258 compress = COMPRESSION_PACKBITS;
1260 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 4, 1))
1263 if (!set_palette(tif, im, 16))
1266 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1267 i_push_error(0, "write TIFF: setting rows per strip tag");
1271 in_row = mymalloc(im->xsize);
1272 out_size = TIFFScanlineSize(tif);
1273 out_row = (unsigned char *)_TIFFmalloc( out_size );
1275 for (y = 0; y < im->ysize; ++y) {
1276 i_gpal(im, 0, im->xsize, y, in_row);
1277 memset(out_row, 0, out_size);
1278 pack_4bit_to(out_row, in_row, im->xsize);
1279 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1281 i_push_error(0, "write TIFF: write scan line failed");
1293 set_direct_tags(TIFF *tif, i_img *im, uint16 compress,
1294 uint16 bits_per_sample) {
1295 uint16 extras = EXTRASAMPLE_ASSOCALPHA;
1296 uint16 extra_count = im->channels == 2 || im->channels == 4;
1297 uint16 photometric = im->channels >= 3 ?
1298 PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
1300 if (!set_base_tags(tif, im, compress, photometric, bits_per_sample,
1306 if (!TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extra_count, &extras)) {
1307 i_push_error(0, "write TIFF: setting extra samples tag");
1312 if (compress == COMPRESSION_JPEG) {
1314 if (i_tags_get_int(&im->tags, "tiff_jpegquality", 0, &jpeg_quality)
1315 && jpeg_quality >= 0 && jpeg_quality <= 100) {
1316 if (!TIFFSetField(tif, TIFFTAG_JPEGQUALITY, jpeg_quality)) {
1317 i_push_error(0, "write TIFF: setting jpeg quality pseudo-tag");
1327 write_one_32(TIFF *tif, i_img *im) {
1328 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1333 size_t sample_count = im->xsize * im->channels;
1334 size_t sample_index;
1336 mm_log((1, "tiff - write_one_32(tif %p, im %p)\n", tif, im));
1338 /* only 8 and 12 bit samples are supported by jpeg compression */
1339 if (compress == COMPRESSION_JPEG)
1340 compress = COMPRESSION_PACKBITS;
1342 if (!set_direct_tags(tif, im, compress, 32))
1345 in_row = mymalloc(sample_count * sizeof(unsigned));
1346 out_size = TIFFScanlineSize(tif);
1347 out_row = (uint32 *)_TIFFmalloc( out_size );
1349 for (y = 0; y < im->ysize; ++y) {
1350 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 32) <= 0) {
1351 i_push_error(0, "Cannot read 32-bit samples");
1354 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1355 out_row[sample_index] = in_row[sample_index];
1356 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1359 i_push_error(0, "write TIFF: write scan line failed");
1371 write_one_16(TIFF *tif, i_img *im) {
1372 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1377 size_t sample_count = im->xsize * im->channels;
1378 size_t sample_index;
1380 mm_log((1, "tiff - write_one_16(tif %p, im %p)\n", tif, im));
1382 /* only 8 and 12 bit samples are supported by jpeg compression */
1383 if (compress == COMPRESSION_JPEG)
1384 compress = COMPRESSION_PACKBITS;
1386 if (!set_direct_tags(tif, im, compress, 16))
1389 in_row = mymalloc(sample_count * sizeof(unsigned));
1390 out_size = TIFFScanlineSize(tif);
1391 out_row = (uint16 *)_TIFFmalloc( out_size );
1393 for (y = 0; y < im->ysize; ++y) {
1394 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 16) <= 0) {
1395 i_push_error(0, "Cannot read 16-bit samples");
1398 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1399 out_row[sample_index] = in_row[sample_index];
1400 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1403 i_push_error(0, "write TIFF: write scan line failed");
1415 write_one_8(TIFF *tif, i_img *im) {
1416 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1418 unsigned char *out_row;
1420 size_t sample_count = im->xsize * im->channels;
1422 mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
1424 if (!set_direct_tags(tif, im, compress, 8))
1427 out_size = TIFFScanlineSize(tif);
1428 if (out_size < sample_count)
1429 out_size = sample_count;
1430 out_row = (unsigned char *)_TIFFmalloc( out_size );
1432 for (y = 0; y < im->ysize; ++y) {
1433 if (i_gsamp(im, 0, im->xsize, y, out_row, NULL, im->channels) <= 0) {
1434 i_push_error(0, "Cannot read 8-bit samples");
1437 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1439 i_push_error(0, "write TIFF: write scan line failed");
1449 i_writetiff_low(TIFF *tif, i_img *im) {
1450 uint32 width, height;
1456 channels = im->channels;
1458 if (width != im->xsize || height != im->ysize) {
1459 i_push_error(0, "image too large for TIFF");
1463 mm_log((1, "i_writetiff_low: width=%d, height=%d, channels=%d, bits=%d\n", width, height, channels, im->bits));
1464 if (im->type == i_palette_type) {
1465 mm_log((1, "i_writetiff_low: paletted, colors=%d\n", i_colorcount(im)));
1468 if (i_img_is_monochrome(im, &zero_is_white)) {
1469 if (!write_one_bilevel(tif, im, zero_is_white))
1472 else if (im->type == i_palette_type) {
1473 if (i_colorcount(im) <= 16) {
1474 if (!write_one_paletted4(tif, im))
1478 if (!write_one_paletted8(tif, im))
1482 else if (im->bits > 16) {
1483 if (!write_one_32(tif, im))
1486 else if (im->bits > 8) {
1487 if (!write_one_16(tif, im))
1491 if (!write_one_8(tif, im))
1495 if (!save_tiff_tags(tif, im))
1502 =item i_writetiff_multi_wiol(ig, imgs, count, fine_mode)
1504 Stores an image in the iolayer object.
1506 ig - io_object that defines source to write to
1507 imgs,count - the images to write
1513 i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1515 TIFFErrorHandler old_handler;
1517 tiffio_context_t ctx;
1519 i_mutex_lock(mutex);
1521 old_handler = TIFFSetErrorHandler(error_handler);
1524 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
1527 tiffio_context_init(&ctx, ig);
1529 tif = TIFFClientOpen("No name",
1543 mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n"));
1544 i_push_error(0, "Could not create TIFF object");
1545 TIFFSetErrorHandler(old_handler);
1546 tiffio_context_final(&ctx);
1547 i_mutex_unlock(mutex);
1551 for (i = 0; i < count; ++i) {
1552 if (!i_writetiff_low(tif, imgs[i])) {
1554 TIFFSetErrorHandler(old_handler);
1555 tiffio_context_final(&ctx);
1556 i_mutex_unlock(mutex);
1560 if (!TIFFWriteDirectory(tif)) {
1561 i_push_error(0, "Cannot write TIFF directory");
1563 TIFFSetErrorHandler(old_handler);
1564 tiffio_context_final(&ctx);
1565 i_mutex_unlock(mutex);
1570 TIFFSetErrorHandler(old_handler);
1571 (void) TIFFClose(tif);
1572 tiffio_context_final(&ctx);
1574 i_mutex_unlock(mutex);
1583 =item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1585 Stores an image in the iolayer object.
1587 ig - io_object that defines source to write to
1588 imgs,count - the images to write
1589 fine_mode - select fine or normal mode fax images
1596 i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1599 TIFFErrorHandler old_handler;
1600 tiffio_context_t ctx;
1602 i_mutex_lock(mutex);
1604 old_handler = TIFFSetErrorHandler(error_handler);
1607 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
1610 tiffio_context_init(&ctx, ig);
1612 tif = TIFFClientOpen("No name",
1626 mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
1627 i_push_error(0, "Could not create TIFF object");
1628 TIFFSetErrorHandler(old_handler);
1629 tiffio_context_final(&ctx);
1630 i_mutex_unlock(mutex);
1634 for (i = 0; i < count; ++i) {
1635 if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1637 TIFFSetErrorHandler(old_handler);
1638 tiffio_context_final(&ctx);
1639 i_mutex_unlock(mutex);
1643 if (!TIFFWriteDirectory(tif)) {
1644 i_push_error(0, "Cannot write TIFF directory");
1646 TIFFSetErrorHandler(old_handler);
1647 tiffio_context_final(&ctx);
1648 i_mutex_unlock(mutex);
1653 (void) TIFFClose(tif);
1654 TIFFSetErrorHandler(old_handler);
1655 tiffio_context_final(&ctx);
1657 i_mutex_unlock(mutex);
1666 =item i_writetiff_wiol(im, ig)
1668 Stores an image in the iolayer object.
1670 im - image object to write out
1671 ig - io_object that defines source to write to
1676 i_writetiff_wiol(i_img *img, io_glue *ig) {
1678 TIFFErrorHandler old_handler;
1679 tiffio_context_t ctx;
1681 i_mutex_lock(mutex);
1683 old_handler = TIFFSetErrorHandler(error_handler);
1686 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", img, ig));
1688 tiffio_context_init(&ctx, ig);
1690 tif = TIFFClientOpen("No name",
1704 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1705 i_push_error(0, "Could not create TIFF object");
1706 tiffio_context_final(&ctx);
1707 TIFFSetErrorHandler(old_handler);
1708 i_mutex_unlock(mutex);
1712 if (!i_writetiff_low(tif, img)) {
1714 tiffio_context_final(&ctx);
1715 TIFFSetErrorHandler(old_handler);
1716 i_mutex_unlock(mutex);
1720 (void) TIFFClose(tif);
1721 TIFFSetErrorHandler(old_handler);
1722 tiffio_context_final(&ctx);
1723 i_mutex_unlock(mutex);
1734 =item i_writetiff_wiol_faxable(i_img *, io_glue *)
1736 Stores an image in the iolayer object in faxable tiff format.
1738 im - image object to write out
1739 ig - io_object that defines source to write to
1741 Note, this may be rewritten to use to simply be a call to a
1742 lower-level function that gives more options for writing tiff at some
1749 i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1751 TIFFErrorHandler old_handler;
1752 tiffio_context_t ctx;
1754 i_mutex_lock(mutex);
1756 old_handler = TIFFSetErrorHandler(error_handler);
1759 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", im, ig));
1761 tiffio_context_init(&ctx, ig);
1763 tif = TIFFClientOpen("No name",
1777 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1778 i_push_error(0, "Could not create TIFF object");
1779 TIFFSetErrorHandler(old_handler);
1780 tiffio_context_final(&ctx);
1781 i_mutex_unlock(mutex);
1785 if (!i_writetiff_low_faxable(tif, im, fine)) {
1787 TIFFSetErrorHandler(old_handler);
1788 tiffio_context_final(&ctx);
1789 i_mutex_unlock(mutex);
1793 (void) TIFFClose(tif);
1794 TIFFSetErrorHandler(old_handler);
1795 tiffio_context_final(&ctx);
1796 i_mutex_unlock(mutex);
1804 static int save_tiff_tags(TIFF *tif, i_img *im) {
1807 for (i = 0; i < text_tag_count; ++i) {
1809 if (i_tags_find(&im->tags, text_tag_names[i].name, 0, &entry)) {
1810 if (!TIFFSetField(tif, text_tag_names[i].tag,
1811 im->tags.tags[entry].data)) {
1812 i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1823 unpack_4bit_to(unsigned char *dest, const unsigned char *src,
1824 size_t src_byte_count) {
1825 while (src_byte_count > 0) {
1826 *dest++ = *src >> 4;
1827 *dest++ = *src++ & 0xf;
1832 static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
1833 i_img_dim pixel_count) {
1835 while (i < pixel_count) {
1837 *dest = *src++ << 4;
1847 =item fallback_rgb_channels
1849 Calculate the number of output channels when we fallback to the RGBA
1850 family of functions.
1856 fallback_rgb_channels(TIFF *tif, i_img_dim width, i_img_dim height, int *channels, int *alpha_chan) {
1862 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1863 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1865 switch (photometric) {
1866 case PHOTOMETRIC_SEPARATED:
1870 case PHOTOMETRIC_MINISWHITE:
1871 case PHOTOMETRIC_MINISBLACK:
1872 /* the TIFF RGBA functions expand single channel grey into RGB,
1873 so reduce it, we move the alpha channel into the right place
1882 /* TIFF images can have more than one alpha channel, but Imager can't
1883 this ignores the possibility of 2 channel images with 2 alpha,
1884 but there's not much I can do about that */
1886 if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)
1888 *alpha_chan = (*channels)++;
1893 make_rgb(TIFF *tif, i_img_dim width, i_img_dim height, int *alpha_chan) {
1896 fallback_rgb_channels(tif, width, height, &channels, alpha_chan);
1898 return i_img_8_new(width, height, channels);
1902 read_one_rgb_lines(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
1904 uint32* raster = NULL;
1905 uint32 rowsperstrip, row;
1910 im = make_rgb(tif, width, height, &alpha_chan);
1914 rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1915 mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
1917 if (rc != 1 || rowsperstrip==-1) {
1918 rowsperstrip = height;
1921 raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
1924 i_push_error(0, "No space for raster buffer");
1928 line_buf = mymalloc(sizeof(i_color) * width);
1930 for( row = 0; row < height; row += rowsperstrip ) {
1931 uint32 newrows, i_row;
1933 if (!TIFFReadRGBAStrip(tif, row, raster)) {
1934 if (allow_incomplete) {
1935 i_tags_setn(&im->tags, "i_lines_read", row);
1936 i_tags_setn(&im->tags, "i_incomplete", 1);
1940 i_push_error(0, "could not read TIFF image strip");
1947 newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
1948 mm_log((1, "newrows=%d\n", newrows));
1950 for( i_row = 0; i_row < newrows; i_row++ ) {
1952 i_color *outp = line_buf;
1954 for(x = 0; x<width; x++) {
1955 uint32 temp = raster[x+width*(newrows-i_row-1)];
1956 outp->rgba.r = TIFFGetR(temp);
1957 outp->rgba.g = TIFFGetG(temp);
1958 outp->rgba.b = TIFFGetB(temp);
1961 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1962 alpha in the right place and scale it */
1964 outp->channel[alpha_chan] = TIFFGetA(temp);
1965 if (outp->channel[alpha_chan]) {
1966 for (ch = 0; ch < alpha_chan; ++ch) {
1967 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1974 i_plin(im, 0, width, i_row+row, line_buf);
1984 /* adapted from libtiff
1986 libtiff's TIFFReadRGBATile succeeds even when asked to read an
1987 invalid tile, which means we have no way of knowing whether the data
1988 we received from it is valid or not.
1990 So the caller here has set stoponerror to 1 so that
1991 TIFFRGBAImageGet() will fail.
1993 read_one_rgb_tiled() then takes that into account for i_incomplete
1997 myTIFFReadRGBATile(TIFFRGBAImage *img, uint32 col, uint32 row, uint32 * raster)
2001 uint32 tile_xsize, tile_ysize;
2002 uint32 read_xsize, read_ysize;
2006 * Verify that our request is legal - on a tile file, and on a
2010 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILEWIDTH, &tile_xsize);
2011 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILELENGTH, &tile_ysize);
2012 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
2014 i_push_errorf(0, "Row/col passed to myTIFFReadRGBATile() must be top"
2015 "left corner of a tile.");
2020 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2021 * edge of the image, even to fill an otherwise valid tile. So we
2022 * figure out how much we can read, and fix up the tile buffer to
2023 * a full tile configuration afterwards.
2026 if( row + tile_ysize > img->height )
2027 read_ysize = img->height - row;
2029 read_ysize = tile_ysize;
2031 if( col + tile_xsize > img->width )
2032 read_xsize = img->width - col;
2034 read_xsize = tile_xsize;
2037 * Read the chunk of imagery.
2040 img->row_offset = row;
2041 img->col_offset = col;
2043 ok = TIFFRGBAImageGet(img, raster, read_xsize, read_ysize );
2046 * If our read was incomplete we will need to fix up the tile by
2047 * shifting the data around as if a full tile of data is being returned.
2049 * This is all the more complicated because the image is organized in
2050 * bottom to top format.
2053 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
2056 for( i_row = 0; i_row < read_ysize; i_row++ ) {
2057 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
2058 raster + (read_ysize - i_row - 1) * read_xsize,
2059 read_xsize * sizeof(uint32) );
2060 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
2061 0, sizeof(uint32) * (tile_xsize - read_xsize) );
2064 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
2065 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
2066 0, sizeof(uint32) * tile_xsize );
2073 read_one_rgb_tiled(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
2075 uint32* raster = NULL;
2078 uint32 tile_width, tile_height;
2079 unsigned long pixels = 0;
2080 char emsg[1024] = "";
2085 im = make_rgb(tif, width, height, &alpha_chan);
2089 if (!TIFFRGBAImageOK(tif, emsg)
2090 || !TIFFRGBAImageBegin(&img, tif, 1, emsg)) {
2091 i_push_error(0, emsg);
2096 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
2097 TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
2098 mm_log((1, "i_readtiff_wiol: tile_width=%d, tile_height=%d\n", tile_width, tile_height));
2100 raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
2103 i_push_error(0, "No space for raster buffer");
2104 TIFFRGBAImageEnd(&img);
2107 line = mymalloc(tile_width * sizeof(i_color));
2109 for( row = 0; row < height; row += tile_height ) {
2110 for( col = 0; col < width; col += tile_width ) {
2112 /* Read the tile into an RGBA array */
2113 if (myTIFFReadRGBATile(&img, col, row, raster)) {
2115 uint32 newrows = (row+tile_height > height) ? height-row : tile_height;
2116 uint32 newcols = (col+tile_width > width ) ? width-col : tile_width;
2118 mm_log((1, "i_readtiff_wiol: tile(%d, %d) newcols=%d newrows=%d\n", col, row, newcols, newrows));
2119 for( i_row = 0; i_row < newrows; i_row++ ) {
2120 i_color *outp = line;
2121 for(x = 0; x < newcols; x++) {
2122 uint32 temp = raster[x+tile_width*(tile_height-i_row-1)];
2123 outp->rgba.r = TIFFGetR(temp);
2124 outp->rgba.g = TIFFGetG(temp);
2125 outp->rgba.b = TIFFGetB(temp);
2126 outp->rgba.a = TIFFGetA(temp);
2129 /* the libtiff RGBA code expands greyscale into RGBA, so put the
2130 alpha in the right place and scale it */
2132 outp->channel[alpha_chan] = TIFFGetA(temp);
2134 if (outp->channel[alpha_chan]) {
2135 for (ch = 0; ch < alpha_chan; ++ch) {
2136 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
2143 i_plin(im, col, col+newcols, row+i_row, line);
2145 pixels += newrows * newcols;
2148 if (allow_incomplete) {
2160 i_push_error(0, "TIFF: No image data could be read from the image");
2164 /* incomplete image */
2165 i_tags_setn(&im->tags, "i_incomplete", 1);
2166 i_tags_setn(&im->tags, "i_lines_read", pixels / width);
2170 TIFFRGBAImageEnd(&img);
2178 TIFFRGBAImageEnd(&img);
2184 i_tiff_libversion(void) {
2185 return TIFFGetVersion();
2189 setup_paletted(read_state_t *state) {
2192 int color_count = 1 << state->bits_per_sample;
2194 state->img = i_img_pal_new(state->width, state->height, 3, 256);
2198 /* setup the color map */
2199 if (!TIFFGetField(state->tif, TIFFTAG_COLORMAP, maps+0, maps+1, maps+2)) {
2200 i_push_error(0, "Cannot get colormap for paletted image");
2201 i_img_destroy(state->img);
2204 for (i = 0; i < color_count; ++i) {
2206 for (ch = 0; ch < 3; ++ch) {
2207 c.channel[ch] = Sample16To8(maps[ch][i]);
2209 i_addcolors(state->img, &c, 1);
2216 tile_contig_getter(read_state_t *state, read_putter_t putter) {
2217 uint32 tile_width, tile_height;
2218 uint32 this_tile_height, this_tile_width;
2219 uint32 rows_left, cols_left;
2222 state->raster = _TIFFmalloc(TIFFTileSize(state->tif));
2223 if (!state->raster) {
2224 i_push_error(0, "tiff: Out of memory allocating tile buffer");
2228 TIFFGetField(state->tif, TIFFTAG_TILEWIDTH, &tile_width);
2229 TIFFGetField(state->tif, TIFFTAG_TILELENGTH, &tile_height);
2230 rows_left = state->height;
2231 for (y = 0; y < state->height; y += this_tile_height) {
2232 this_tile_height = rows_left > tile_height ? tile_height : rows_left;
2234 cols_left = state->width;
2235 for (x = 0; x < state->width; x += this_tile_width) {
2236 this_tile_width = cols_left > tile_width ? tile_width : cols_left;
2238 if (TIFFReadTile(state->tif,
2241 if (!state->allow_incomplete) {
2246 putter(state, x, y, this_tile_width, this_tile_height, tile_width - this_tile_width);
2249 cols_left -= this_tile_width;
2252 rows_left -= this_tile_height;
2259 strip_contig_getter(read_state_t *state, read_putter_t putter) {
2260 uint32 rows_per_strip;
2261 tsize_t strip_size = TIFFStripSize(state->tif);
2262 uint32 y, strip_rows, rows_left;
2264 state->raster = _TIFFmalloc(strip_size);
2265 if (!state->raster) {
2266 i_push_error(0, "tiff: Out of memory allocating strip buffer");
2270 TIFFGetFieldDefaulted(state->tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
2271 rows_left = state->height;
2272 for (y = 0; y < state->height; y += strip_rows) {
2273 strip_rows = rows_left > rows_per_strip ? rows_per_strip : rows_left;
2274 if (TIFFReadEncodedStrip(state->tif,
2275 TIFFComputeStrip(state->tif, y, 0),
2278 if (!state->allow_incomplete)
2282 putter(state, 0, y, state->width, strip_rows, 0);
2284 rows_left -= strip_rows;
2291 paletted_putter8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
2292 unsigned char *p = state->raster;
2294 state->pixels_read += width * height;
2295 while (height > 0) {
2296 i_ppal(state->img, x, x + width, y, p);
2297 p += width + extras;
2306 paletted_putter4(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
2307 uint32 img_line_size = (width + 1) / 2;
2308 uint32 skip_line_size = (width + extras + 1) / 2;
2309 unsigned char *p = state->raster;
2311 if (!state->line_buf)
2312 state->line_buf = mymalloc(state->width);
2314 state->pixels_read += width * height;
2315 while (height > 0) {
2316 unpack_4bit_to(state->line_buf, p, img_line_size);
2317 i_ppal(state->img, x, x + width, y, state->line_buf);
2318 p += skip_line_size;
2327 rgb_channels(read_state_t *state, int *out_channels) {
2333 state->alpha_chan = 0;
2334 state->scale_alpha = 0;
2335 state->color_channels = 3;
2338 if (state->samples_per_pixel == 3)
2341 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2342 mm_log((1, "tiff: samples != 3 but no extra samples tag\n"));
2347 mm_log((1, "tiff: samples != 3 but no extra samples listed"));
2352 state->alpha_chan = 3;
2354 case EXTRASAMPLE_UNSPECIFIED:
2355 case EXTRASAMPLE_ASSOCALPHA:
2356 state->scale_alpha = 1;
2359 case EXTRASAMPLE_UNASSALPHA:
2360 state->scale_alpha = 0;
2364 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2366 state->scale_alpha = 1;
2369 mm_log((1, "tiff alpha channel %d scale %d\n", state->alpha_chan, state->scale_alpha));
2373 grey_channels(read_state_t *state, int *out_channels) {
2379 state->alpha_chan = 0;
2380 state->scale_alpha = 0;
2381 state->color_channels = 1;
2384 if (state->samples_per_pixel == 1)
2387 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2388 mm_log((1, "tiff: samples != 1 but no extra samples tag\n"));
2393 mm_log((1, "tiff: samples != 1 but no extra samples listed"));
2398 state->alpha_chan = 1;
2400 case EXTRASAMPLE_UNSPECIFIED:
2401 case EXTRASAMPLE_ASSOCALPHA:
2402 state->scale_alpha = 1;
2405 case EXTRASAMPLE_UNASSALPHA:
2406 state->scale_alpha = 0;
2410 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2412 state->scale_alpha = 1;
2418 setup_16_rgb(read_state_t *state) {
2421 rgb_channels(state, &out_channels);
2423 state->img = i_img_16_new(state->width, state->height, out_channels);
2426 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2432 setup_16_grey(read_state_t *state) {
2435 grey_channels(state, &out_channels);
2437 state->img = i_img_16_new(state->width, state->height, out_channels);
2440 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2446 putter_16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2448 uint16 *p = state->raster;
2449 int out_chan = state->img->channels;
2451 state->pixels_read += width * height;
2452 while (height > 0) {
2455 unsigned *outp = state->line_buf;
2457 for (i = 0; i < width; ++i) {
2458 for (ch = 0; ch < out_chan; ++ch) {
2461 if (state->sample_signed) {
2462 for (ch = 0; ch < state->color_channels; ++ch)
2465 if (state->alpha_chan && state->scale_alpha && outp[state->alpha_chan]) {
2466 for (ch = 0; ch < state->alpha_chan; ++ch) {
2467 int result = 0.5 + (outp[ch] * 65535.0 / outp[state->alpha_chan]);
2468 outp[ch] = CLAMP16(result);
2471 p += state->samples_per_pixel;
2475 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2477 p += row_extras * state->samples_per_pixel;
2486 setup_8_rgb(read_state_t *state) {
2489 rgb_channels(state, &out_channels);
2491 state->img = i_img_8_new(state->width, state->height, out_channels);
2494 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2500 setup_8_grey(read_state_t *state) {
2503 grey_channels(state, &out_channels);
2505 state->img = i_img_8_new(state->width, state->height, out_channels);
2508 state->line_buf = mymalloc(sizeof(i_color) * state->width * out_channels);
2514 putter_8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2516 unsigned char *p = state->raster;
2517 int out_chan = state->img->channels;
2519 state->pixels_read += width * height;
2520 while (height > 0) {
2523 i_color *outp = state->line_buf;
2525 for (i = 0; i < width; ++i) {
2526 for (ch = 0; ch < out_chan; ++ch) {
2527 outp->channel[ch] = p[ch];
2529 if (state->sample_signed) {
2530 for (ch = 0; ch < state->color_channels; ++ch)
2531 outp->channel[ch] ^= 0x80;
2533 if (state->alpha_chan && state->scale_alpha
2534 && outp->channel[state->alpha_chan]) {
2535 for (ch = 0; ch < state->alpha_chan; ++ch) {
2536 int result = (outp->channel[ch] * 255 + 127) / outp->channel[state->alpha_chan];
2538 outp->channel[ch] = CLAMP8(result);
2541 p += state->samples_per_pixel;
2545 i_plin(state->img, x, x + width, y, state->line_buf);
2547 p += row_extras * state->samples_per_pixel;
2556 setup_32_rgb(read_state_t *state) {
2559 rgb_channels(state, &out_channels);
2561 state->img = i_img_double_new(state->width, state->height, out_channels);
2564 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2570 setup_32_grey(read_state_t *state) {
2573 grey_channels(state, &out_channels);
2575 state->img = i_img_double_new(state->width, state->height, out_channels);
2578 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2584 putter_32(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2586 uint32 *p = state->raster;
2587 int out_chan = state->img->channels;
2589 state->pixels_read += width * height;
2590 while (height > 0) {
2593 i_fcolor *outp = state->line_buf;
2595 for (i = 0; i < width; ++i) {
2597 if (state->sample_format == SAMPLEFORMAT_IEEEFP) {
2598 const float *pv = (const float *)p;
2599 for (ch = 0; ch < out_chan; ++ch) {
2600 outp->channel[ch] = pv[ch];
2605 for (ch = 0; ch < out_chan; ++ch) {
2606 if (state->sample_signed && ch < state->color_channels)
2607 outp->channel[ch] = (p[ch] ^ 0x80000000UL) / 4294967295.0;
2609 outp->channel[ch] = p[ch] / 4294967295.0;
2615 if (state->alpha_chan && state->scale_alpha && outp->channel[state->alpha_chan]) {
2616 for (ch = 0; ch < state->alpha_chan; ++ch)
2617 outp->channel[ch] /= outp->channel[state->alpha_chan];
2619 p += state->samples_per_pixel;
2623 i_plinf(state->img, x, x + width, y, state->line_buf);
2625 p += row_extras * state->samples_per_pixel;
2634 setup_bilevel(read_state_t *state) {
2635 i_color black, white;
2636 state->img = i_img_pal_new(state->width, state->height, 1, 256);
2639 black.channel[0] = black.channel[1] = black.channel[2] =
2640 black.channel[3] = 0;
2641 white.channel[0] = white.channel[1] = white.channel[2] =
2642 white.channel[3] = 255;
2643 if (state->photometric == PHOTOMETRIC_MINISBLACK) {
2644 i_addcolors(state->img, &black, 1);
2645 i_addcolors(state->img, &white, 1);
2648 i_addcolors(state->img, &white, 1);
2649 i_addcolors(state->img, &black, 1);
2651 state->line_buf = mymalloc(state->width);
2657 putter_bilevel(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2659 unsigned char *line_in = state->raster;
2660 size_t line_size = (width + row_extras + 7) / 8;
2662 /* tifflib returns the bits in MSB2LSB order even when the file is
2663 in LSB2MSB, so we only need to handle MSB2LSB */
2664 state->pixels_read += width * height;
2665 while (height > 0) {
2667 unsigned char *outp = state->line_buf;
2668 unsigned char *inp = line_in;
2669 unsigned mask = 0x80;
2671 for (i = 0; i < width; ++i) {
2672 *outp++ = *inp & mask ? 1 : 0;
2680 i_ppal(state->img, x, x + width, y, state->line_buf);
2682 line_in += line_size;
2691 cmyk_channels(read_state_t *state, int *out_channels) {
2697 state->alpha_chan = 0;
2698 state->scale_alpha = 0;
2699 state->color_channels = 3;
2702 if (state->samples_per_pixel == 4)
2705 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2706 mm_log((1, "tiff: CMYK samples != 4 but no extra samples tag\n"));
2711 mm_log((1, "tiff: CMYK samples != 4 but no extra samples listed"));
2716 state->alpha_chan = 4;
2718 case EXTRASAMPLE_UNSPECIFIED:
2719 case EXTRASAMPLE_ASSOCALPHA:
2720 state->scale_alpha = 1;
2723 case EXTRASAMPLE_UNASSALPHA:
2724 state->scale_alpha = 0;
2728 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2730 state->scale_alpha = 1;
2736 setup_cmyk8(read_state_t *state) {
2739 cmyk_channels(state, &channels);
2740 state->img = i_img_8_new(state->width, state->height, channels);
2742 state->line_buf = mymalloc(sizeof(i_color) * state->width);
2748 putter_cmyk8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2750 unsigned char *p = state->raster;
2752 state->pixels_read += width * height;
2753 while (height > 0) {
2756 i_color *outp = state->line_buf;
2758 for (i = 0; i < width; ++i) {
2759 unsigned char c, m, y, k;
2764 if (state->sample_signed) {
2770 outp->rgba.r = (k * (255 - c)) / 255;
2771 outp->rgba.g = (k * (255 - m)) / 255;
2772 outp->rgba.b = (k * (255 - y)) / 255;
2773 if (state->alpha_chan) {
2774 outp->rgba.a = p[state->alpha_chan];
2775 if (state->scale_alpha
2777 for (ch = 0; ch < 3; ++ch) {
2778 int result = (outp->channel[ch] * 255 + 127) / outp->rgba.a;
2779 outp->channel[ch] = CLAMP8(result);
2783 p += state->samples_per_pixel;
2787 i_plin(state->img, x, x + width, y, state->line_buf);
2789 p += row_extras * state->samples_per_pixel;
2798 setup_cmyk16(read_state_t *state) {
2801 cmyk_channels(state, &channels);
2802 state->img = i_img_16_new(state->width, state->height, channels);
2804 state->line_buf = mymalloc(sizeof(unsigned) * state->width * channels);
2810 putter_cmyk16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2812 uint16 *p = state->raster;
2813 int out_chan = state->img->channels;
2815 mm_log((4, "putter_cmyk16(%p, %" i_DF ", %" i_DF ", %" i_DF
2816 ", %" i_DF ", %d)\n", state, i_DFcp(x, y), i_DFcp(width, height),
2819 state->pixels_read += width * height;
2820 while (height > 0) {
2823 unsigned *outp = state->line_buf;
2825 for (i = 0; i < width; ++i) {
2826 unsigned c, m, y, k;
2831 if (state->sample_signed) {
2837 outp[0] = (k * (65535U - c)) / 65535U;
2838 outp[1] = (k * (65535U - m)) / 65535U;
2839 outp[2] = (k * (65535U - y)) / 65535U;
2840 if (state->alpha_chan) {
2841 outp[3] = p[state->alpha_chan];
2842 if (state->scale_alpha
2844 for (ch = 0; ch < 3; ++ch) {
2845 int result = (outp[ch] * 65535 + 32767) / outp[3];
2846 outp[3] = CLAMP16(result);
2850 p += state->samples_per_pixel;
2854 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2856 p += row_extras * state->samples_per_pixel;
2866 Older versions of tifflib we support don't define this, so define it
2869 If you want this detection to do anything useful, use a newer
2873 #if TIFFLIB_VERSION < 20031121
2876 TIFFIsCODECConfigured(uint16 scheme) {
2878 /* these schemes are all shipped with tifflib */
2879 case COMPRESSION_NONE:
2880 case COMPRESSION_PACKBITS:
2881 case COMPRESSION_CCITTRLE:
2882 case COMPRESSION_CCITTRLEW:
2883 case COMPRESSION_CCITTFAX3:
2884 case COMPRESSION_CCITTFAX4:
2887 /* these require external library support */
2889 case COMPRESSION_JPEG:
2890 case COMPRESSION_LZW:
2891 case COMPRESSION_DEFLATE:
2892 case COMPRESSION_ADOBE_DEFLATE:
2900 myTIFFIsCODECConfigured(uint16 scheme) {
2901 #if TIFFLIB_VERSION < 20040724
2902 if (scheme == COMPRESSION_LZW)
2906 return TIFFIsCODECConfigured(scheme);
2910 tiffio_context_init(tiffio_context_t *c, io_glue *ig) {
2911 c->magic = TIFFIO_MAGIC;
2913 #ifdef USE_EXT_WARN_HANDLER
2914 c->warn_buffer = NULL;
2920 tiffio_context_final(tiffio_context_t *c) {
2921 c->magic = TIFFIO_MAGIC;
2922 #ifdef USE_EXT_WARN_HANDLER
2924 myfree(c->warn_buffer);
2933 Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tonyc@cpan.org>