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);
91 myTIFFIsCODECConfigured(uint16 scheme);
93 typedef struct read_state_tag read_state_t;
94 /* the setup function creates the image object, allocates the line buffer */
95 typedef int (*read_setup_t)(read_state_t *state);
97 /* the putter writes the image data provided by the getter to the
98 image, x, y, width, height describe the target area of the image,
99 extras is the extra number of pixels stored for each scanline in
100 the raster buffer, (for tiles against the right side of the
103 typedef int (*read_putter_t)(read_state_t *state, i_img_dim x, i_img_dim y,
104 i_img_dim width, i_img_dim height, int extras);
106 /* reads from a tiled or strip image and calls the putter.
107 This may need a second type for handling non-contiguous images
109 typedef int (*read_getter_t)(read_state_t *state, read_putter_t putter);
111 struct read_state_tag {
115 i_img_dim pixels_read;
116 int allow_incomplete;
118 uint32 width, height;
119 uint16 bits_per_sample;
122 /* the total number of channels (samples per pixel) */
123 int samples_per_pixel;
125 /* if non-zero, which channel is the alpha channel, typically 3 for rgb */
128 /* whether or not to scale the color channels based on the alpha
129 channel. TIFF has 2 types of alpha channel, if the alpha channel
130 we use is EXTRASAMPLE_ASSOCALPHA then the color data will need to
131 be scaled to match Imager's conventions */
135 static int tile_contig_getter(read_state_t *state, read_putter_t putter);
136 static int strip_contig_getter(read_state_t *state, read_putter_t putter);
138 static int setup_paletted(read_state_t *state);
139 static int paletted_putter8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
140 static int paletted_putter4(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
142 static int setup_16_rgb(read_state_t *state);
143 static int setup_16_grey(read_state_t *state);
144 static int putter_16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
146 static int setup_8_rgb(read_state_t *state);
147 static int setup_8_grey(read_state_t *state);
148 static int putter_8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
150 static int setup_32_rgb(read_state_t *state);
151 static int setup_32_grey(read_state_t *state);
152 static int putter_32(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
154 static int setup_bilevel(read_state_t *state);
155 static int putter_bilevel(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
157 static int setup_cmyk8(read_state_t *state);
158 static int putter_cmyk8(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
160 static int setup_cmyk16(read_state_t *state);
161 static int putter_cmyk16(read_state_t *, i_img_dim, i_img_dim, i_img_dim, i_img_dim, int);
163 rgb_channels(read_state_t *state, int *out_channels);
165 grey_channels(read_state_t *state, int *out_channels);
167 cmyk_channels(read_state_t *state, int *out_channels);
169 fallback_rgb_channels(TIFF *tif, i_img_dim width, i_img_dim height, int *channels, int *alpha_chan);
171 static const int text_tag_count =
172 sizeof(text_tag_names) / sizeof(*text_tag_names);
174 #if TIFFLIB_VERSION >= 20051230
175 #define USE_EXT_WARN_HANDLER
178 #define TIFFIO_MAGIC 0xC6A340CC
180 static void error_handler(char const *module, char const *fmt, va_list ap) {
181 mm_log((1, "tiff error fmt %s\n", fmt));
182 i_push_errorvf(0, fmt, ap);
188 #ifdef USE_EXT_WARN_HANDLER
195 tiffio_context_init(tiffio_context_t *c, io_glue *ig);
197 tiffio_context_final(tiffio_context_t *c);
199 #define WARN_BUFFER_LIMIT 10000
201 #ifdef USE_EXT_WARN_HANDLER
204 warn_handler_ex(thandle_t h, const char *module, const char *fmt, va_list ap) {
205 tiffio_context_t *c = (tiffio_context_t *)h;
208 if (c->magic != TIFFIO_MAGIC)
212 #ifdef IMAGER_VSNPRINTF
213 vsnprintf(buf, sizeof(buf), fmt, ap);
215 vsprintf(buf, fmt, ap);
217 mm_log((1, "tiff warning %s\n", buf));
219 if (!c->warn_buffer || strlen(c->warn_buffer)+strlen(buf)+2 > c->warn_size) {
220 size_t new_size = c->warn_size + strlen(buf) + 2;
221 char *old_buffer = c->warn_buffer;
222 if (new_size > WARN_BUFFER_LIMIT) {
223 new_size = WARN_BUFFER_LIMIT;
225 c->warn_buffer = myrealloc(c->warn_buffer, new_size);
226 if (!old_buffer) c->warn_buffer[0] = '\0';
227 c->warn_size = new_size;
229 if (strlen(c->warn_buffer)+strlen(buf)+2 <= c->warn_size) {
230 strcat(c->warn_buffer, buf);
231 strcat(c->warn_buffer, "\n");
237 static char *warn_buffer = NULL;
238 static int warn_buffer_size = 0;
240 static void warn_handler(char const *module, char const *fmt, va_list ap) {
244 #ifdef IMAGER_VSNPRINTF
245 vsnprintf(buf, sizeof(buf), fmt, ap);
247 vsprintf(buf, fmt, ap);
249 mm_log((1, "tiff warning %s\n", buf));
251 if (!warn_buffer || strlen(warn_buffer)+strlen(buf)+2 > warn_buffer_size) {
252 int new_size = warn_buffer_size + strlen(buf) + 2;
253 char *old_buffer = warn_buffer;
254 if (new_size > WARN_BUFFER_LIMIT) {
255 new_size = WARN_BUFFER_LIMIT;
257 warn_buffer = myrealloc(warn_buffer, new_size);
258 if (!old_buffer) *warn_buffer = '\0';
259 warn_buffer_size = new_size;
261 if (strlen(warn_buffer)+strlen(buf)+2 <= warn_buffer_size) {
262 strcat(warn_buffer, buf);
263 strcat(warn_buffer, "\n");
269 static int save_tiff_tags(TIFF *tif, i_img *im);
272 pack_4bit_to(unsigned char *dest, const unsigned char *src, i_img_dim count);
275 static toff_t sizeproc(thandle_t x) {
281 =item comp_seek(h, o, w)
283 Compatability for 64 bit systems like latest freebsd (internal)
285 h - tiff handle, cast an io_glue object
294 comp_seek(thandle_t h, toff_t o, int w) {
295 io_glue *ig = ((tiffio_context_t *)h)->ig;
296 return (toff_t) i_io_seek(ig, o, w);
300 =item comp_mmap(thandle_t, tdata_t*, toff_t*)
304 This shouldn't ever be called but newer tifflibs want it anyway.
311 comp_mmap(thandle_t h, tdata_t*p, toff_t*off) {
316 =item comp_munmap(thandle_t h, tdata_t p, toff_t off)
320 This shouldn't ever be called but newer tifflibs want it anyway.
326 comp_munmap(thandle_t h, tdata_t p, toff_t off) {
331 comp_read(thandle_t h, tdata_t p, tsize_t size) {
332 return i_io_read(((tiffio_context_t *)h)->ig, p, size);
336 comp_write(thandle_t h, tdata_t p, tsize_t size) {
337 return i_io_write(((tiffio_context_t *)h)->ig, p, size);
341 comp_close(thandle_t h) {
342 return i_io_close(((tiffio_context_t *)h)->ig);
345 static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
347 uint32 width, height;
348 uint16 samples_per_pixel;
352 int gotXres, gotYres;
354 uint16 bits_per_sample;
355 uint16 planar_config;
360 read_setup_t setupf = NULL;
361 read_getter_t getterf = NULL;
362 read_putter_t putterf = NULL;
363 int channels = MAXCHANNELS;
364 size_t sample_size = ~0; /* force failure if some code doesn't set it */
365 i_img_dim total_pixels;
369 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
370 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
371 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
372 tiled = TIFFIsTiled(tif);
373 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
374 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
375 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
376 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
378 mm_log((1, "i_readtiff_wiol: width=%d, height=%d, channels=%d\n", width, height, samples_per_pixel));
379 mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
380 mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
382 total_pixels = width * height;
383 memset(&state, 0, sizeof(state));
385 state.allow_incomplete = allow_incomplete;
387 state.height = height;
388 state.bits_per_sample = bits_per_sample;
389 state.samples_per_pixel = samples_per_pixel;
390 state.photometric = photometric;
392 /* yes, this if() is horrible */
393 if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8) {
394 setupf = setup_paletted;
395 if (bits_per_sample == 8)
396 putterf = paletted_putter8;
397 else if (bits_per_sample == 4)
398 putterf = paletted_putter4;
400 mm_log((1, "unsupported paletted bits_per_sample %d\n", bits_per_sample));
402 sample_size = sizeof(i_sample_t);
405 else if (bits_per_sample == 16
406 && photometric == PHOTOMETRIC_RGB
407 && samples_per_pixel >= 3) {
408 setupf = setup_16_rgb;
411 rgb_channels(&state, &channels);
413 else if (bits_per_sample == 16
414 && photometric == PHOTOMETRIC_MINISBLACK) {
415 setupf = setup_16_grey;
418 grey_channels(&state, &channels);
420 else if (bits_per_sample == 8
421 && photometric == PHOTOMETRIC_MINISBLACK) {
422 setupf = setup_8_grey;
425 grey_channels(&state, &channels);
427 else if (bits_per_sample == 8
428 && photometric == PHOTOMETRIC_RGB) {
429 setupf = setup_8_rgb;
432 rgb_channels(&state, &channels);
434 else if (bits_per_sample == 32
435 && photometric == PHOTOMETRIC_RGB
436 && samples_per_pixel >= 3) {
437 setupf = setup_32_rgb;
439 sample_size = sizeof(i_fsample_t);
440 rgb_channels(&state, &channels);
442 else if (bits_per_sample == 32
443 && photometric == PHOTOMETRIC_MINISBLACK) {
444 setupf = setup_32_grey;
446 sample_size = sizeof(i_fsample_t);
447 grey_channels(&state, &channels);
449 else if (bits_per_sample == 1
450 && (photometric == PHOTOMETRIC_MINISBLACK
451 || photometric == PHOTOMETRIC_MINISWHITE)
452 && samples_per_pixel == 1) {
453 setupf = setup_bilevel;
454 putterf = putter_bilevel;
455 sample_size = sizeof(i_palidx);
458 else if (bits_per_sample == 8
459 && photometric == PHOTOMETRIC_SEPARATED
460 && inkset == INKSET_CMYK
461 && samples_per_pixel >= 4) {
462 setupf = setup_cmyk8;
463 putterf = putter_cmyk8;
465 cmyk_channels(&state, &channels);
467 else if (bits_per_sample == 16
468 && photometric == PHOTOMETRIC_SEPARATED
469 && inkset == INKSET_CMYK
470 && samples_per_pixel >= 4) {
471 setupf = setup_cmyk16;
472 putterf = putter_cmyk16;
474 cmyk_channels(&state, &channels);
478 fallback_rgb_channels(tif, width, height, &channels, &alpha);
482 if (!i_int_check_image_file_limits(width, height, channels, sample_size)) {
487 if (planar_config == PLANARCONFIG_CONTIG)
488 getterf = tile_contig_getter;
491 if (planar_config == PLANARCONFIG_CONTIG)
492 getterf = strip_contig_getter;
494 if (setupf && getterf && putterf) {
498 if (!getterf(&state, putterf) || !state.pixels_read) {
500 i_img_destroy(state.img);
502 _TIFFfree(state.raster);
504 myfree(state.line_buf);
509 if (allow_incomplete && state.pixels_read < total_pixels) {
510 i_tags_setn(&(state.img->tags), "i_incomplete", 1);
511 i_tags_setn(&(state.img->tags), "i_lines_read",
512 state.pixels_read / width);
517 _TIFFfree(state.raster);
519 myfree(state.line_buf);
523 im = read_one_rgb_tiled(tif, width, height, allow_incomplete);
526 im = read_one_rgb_lines(tif, width, height, allow_incomplete);
533 /* general metadata */
534 i_tags_setn(&im->tags, "tiff_bitspersample", bits_per_sample);
535 i_tags_setn(&im->tags, "tiff_photometric", photometric);
536 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
538 /* resolution tags */
539 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
540 gotXres = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
541 gotYres = TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
542 if (gotXres || gotYres) {
547 i_tags_setn(&im->tags, "tiff_resolutionunit", resunit);
548 if (resunit == RESUNIT_CENTIMETER) {
549 /* from dots per cm to dpi */
552 i_tags_set(&im->tags, "tiff_resolutionunit_name", "centimeter", -1);
554 else if (resunit == RESUNIT_NONE) {
555 i_tags_setn(&im->tags, "i_aspect_only", 1);
556 i_tags_set(&im->tags, "tiff_resolutionunit_name", "none", -1);
558 else if (resunit == RESUNIT_INCH) {
559 i_tags_set(&im->tags, "tiff_resolutionunit_name", "inch", -1);
562 i_tags_set(&im->tags, "tiff_resolutionunit_name", "unknown", -1);
564 /* tifflib doesn't seem to provide a way to get to the original rational
565 value of these, which would let me provide a more reasonable
566 precision. So make up a number. */
567 i_tags_set_float2(&im->tags, "i_xres", 0, xres, 6);
568 i_tags_set_float2(&im->tags, "i_yres", 0, yres, 6);
572 for (i = 0; i < text_tag_count; ++i) {
574 if (TIFFGetField(tif, text_tag_names[i].tag, &data)) {
575 mm_log((1, "i_readtiff_wiol: tag %d has value %s\n",
576 text_tag_names[i].tag, data));
577 i_tags_set(&im->tags, text_tag_names[i].name, data, -1);
581 i_tags_set(&im->tags, "i_format", "tiff", 4);
582 #ifdef USE_EXT_WARN_HANDLER
584 tiffio_context_t *ctx = TIFFClientdata(tif);
585 if (ctx->warn_buffer && ctx->warn_buffer[0]) {
586 i_tags_set(&im->tags, "i_warning", ctx->warn_buffer, -1);
587 ctx->warn_buffer[0] = '\0';
591 if (warn_buffer && *warn_buffer) {
592 i_tags_set(&im->tags, "i_warning", warn_buffer, -1);
597 for (i = 0; i < compress_value_count; ++i) {
598 if (compress_values[i].tag == compress) {
599 i_tags_set(&im->tags, "tiff_compression", compress_values[i].name, -1);
608 =item i_readtiff_wiol(im, ig)
613 i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
615 TIFFErrorHandler old_handler;
616 TIFFErrorHandler old_warn_handler;
617 #ifdef USE_EXT_WARN_HANDLER
618 TIFFErrorHandlerExt old_ext_warn_handler;
622 tiffio_context_t ctx;
625 old_handler = TIFFSetErrorHandler(error_handler);
626 #ifdef USE_EXT_WARN_HANDLER
627 old_warn_handler = TIFFSetWarningHandler(NULL);
628 old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex);
630 old_warn_handler = TIFFSetWarningHandler(warn_handler);
635 /* Add code to get the filename info from the iolayer */
636 /* Also add code to check for mmapped code */
638 mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
640 tiffio_context_init(&ctx, ig);
641 tif = TIFFClientOpen("(Iolayer)",
653 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
654 i_push_error(0, "Error opening file");
655 TIFFSetErrorHandler(old_handler);
656 TIFFSetWarningHandler(old_warn_handler);
657 #ifdef USE_EXT_WARN_HANDLER
658 TIFFSetWarningHandlerExt(old_ext_warn_handler);
660 tiffio_context_final(&ctx);
664 for (current_page = 0; current_page < page; ++current_page) {
665 if (!TIFFReadDirectory(tif)) {
666 mm_log((1, "i_readtiff_wiol: Unable to switch to directory %d\n", page));
667 i_push_errorf(0, "could not switch to page %d", page);
668 TIFFSetErrorHandler(old_handler);
669 TIFFSetWarningHandler(old_warn_handler);
670 #ifdef USE_EXT_WARN_HANDLER
671 TIFFSetWarningHandlerExt(old_ext_warn_handler);
674 tiffio_context_final(&ctx);
679 im = read_one_tiff(tif, allow_incomplete);
681 if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
682 TIFFSetErrorHandler(old_handler);
683 TIFFSetWarningHandler(old_warn_handler);
684 #ifdef USE_EXT_WARN_HANDLER
685 TIFFSetWarningHandlerExt(old_ext_warn_handler);
688 tiffio_context_final(&ctx);
694 =item i_readtiff_multi_wiol(ig, *count)
696 Reads multiple images from a TIFF.
701 i_readtiff_multi_wiol(io_glue *ig, int *count) {
703 TIFFErrorHandler old_handler;
704 TIFFErrorHandler old_warn_handler;
705 #ifdef USE_EXT_WARN_HANDLER
706 TIFFErrorHandlerExt old_ext_warn_handler;
708 i_img **results = NULL;
709 int result_alloc = 0;
710 tiffio_context_t ctx;
713 old_handler = TIFFSetErrorHandler(error_handler);
714 #ifdef USE_EXT_WARN_HANDLER
715 old_warn_handler = TIFFSetWarningHandler(NULL);
716 old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex);
718 old_warn_handler = TIFFSetWarningHandler(warn_handler);
723 tiffio_context_init(&ctx, ig);
725 /* Add code to get the filename info from the iolayer */
726 /* Also add code to check for mmapped code */
728 mm_log((1, "i_readtiff_wiol(ig %p, length %d)\n", ig));
730 tif = TIFFClientOpen("(Iolayer)",
742 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
743 i_push_error(0, "Error opening file");
744 TIFFSetErrorHandler(old_handler);
745 TIFFSetWarningHandler(old_warn_handler);
746 #ifdef USE_EXT_WARN_HANDLER
747 TIFFSetWarningHandlerExt(old_ext_warn_handler);
749 tiffio_context_final(&ctx);
755 i_img *im = read_one_tiff(tif, 0);
758 if (++*count > result_alloc) {
759 if (result_alloc == 0) {
761 results = mymalloc(result_alloc * sizeof(i_img *));
766 newresults = myrealloc(results, result_alloc * sizeof(i_img *));
768 i_img_destroy(im); /* don't leak it */
771 results = newresults;
774 results[*count-1] = im;
775 } while (TIFFReadDirectory(tif));
777 TIFFSetWarningHandler(old_warn_handler);
778 TIFFSetErrorHandler(old_handler);
779 #ifdef USE_EXT_WARN_HANDLER
780 TIFFSetWarningHandlerExt(old_ext_warn_handler);
783 tiffio_context_final(&ctx);
789 i_writetiff_low_faxable(TIFF *tif, i_img *im, int fine) {
790 uint32 width, height;
791 unsigned char *linebuf = NULL;
796 float vres = fine ? 196 : 98;
802 if (width != im->xsize || height != im->ysize) {
803 i_push_error(0, "image too large for TIFF");
807 switch (im->channels) {
817 /* This means a colorspace we don't handle yet */
818 mm_log((1, "i_writetiff_wiol_faxable: don't handle %d channel images.\n", im->channels));
822 /* Add code to get the filename info from the iolayer */
823 /* Also add code to check for mmapped code */
826 mm_log((1, "i_writetiff_wiol_faxable: width=%d, height=%d, channels=%d\n", width, height, im->channels));
828 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width) )
829 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField width=%d failed\n", width)); return 0; }
830 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height) )
831 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField length=%d failed\n", height)); return 0; }
832 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
833 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField samplesperpixel=1 failed\n")); return 0; }
834 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT))
835 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Orientation=topleft\n")); return 0; }
836 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1) )
837 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField bitpersample=1\n")); return 0; }
838 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG))
839 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField planarconfig\n")); return 0; }
840 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
841 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField photometric=%d\n", PHOTOMETRIC_MINISBLACK)); return 0; }
842 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, 3))
843 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField compression=3\n")); return 0; }
845 linebuf = (unsigned char *)_TIFFmalloc( TIFFScanlineSize(tif) );
847 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
848 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField rowsperstrip=-1\n")); return 0; }
850 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
851 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rc);
853 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField rowsperstrip=%d\n", rowsperstrip));
854 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField scanlinesize=%d\n", TIFFScanlineSize(tif) ));
855 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField planarconfig=%d == %d\n", rc, PLANARCONFIG_CONTIG));
857 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)204))
858 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Xresolution=204\n")); return 0; }
859 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, vres))
860 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Yresolution=196\n")); return 0; }
861 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)) {
862 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField ResolutionUnit=%d\n", RESUNIT_INCH)); return 0;
865 if (!save_tiff_tags(tif, im)) {
869 for (y=0; y<height; y++) {
871 for(x=0; x<width; x+=8) {
876 linebuf[linebufpos]=0;
877 bits = width-x; if(bits>8) bits=8;
878 i_gsamp(im, x, x+8, y, luma, &luma_chan, 1);
879 for(bitpos=0;bitpos<bits;bitpos++) {
880 linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
885 if (TIFFWriteScanline(tif, linebuf, y, 0) < 0) {
886 mm_log((1, "i_writetiff_wiol_faxable: TIFFWriteScanline failed.\n"));
890 if (linebuf) _TIFFfree(linebuf);
896 find_compression(char const *name, uint16 *compress) {
899 for (i = 0; i < compress_value_count; ++i) {
900 if (strcmp(compress_values[i].name, name) == 0) {
901 *compress = (uint16)compress_values[i].tag;
905 *compress = COMPRESSION_NONE;
911 get_compression(i_img *im, uint16 def_compress) {
915 if (i_tags_find(&im->tags, "tiff_compression", 0, &entry)
916 && im->tags.tags[entry].data) {
918 if (find_compression(im->tags.tags[entry].data, &compress)
919 && myTIFFIsCODECConfigured(compress))
922 if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
923 if ((uint16)value == value
924 && myTIFFIsCODECConfigured((uint16)value))
925 return (uint16)value;
932 i_tiff_has_compression(const char *name) {
935 if (!find_compression(name, &compress))
938 return myTIFFIsCODECConfigured(compress);
942 set_base_tags(TIFF *tif, i_img *im, uint16 compress, uint16 photometric,
943 uint16 bits_per_sample, uint16 samples_per_pixel) {
946 int got_xres, got_yres;
949 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->xsize)) {
950 i_push_error(0, "write TIFF: setting width tag");
953 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
954 i_push_error(0, "write TIFF: setting length tag");
957 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
958 i_push_error(0, "write TIFF: setting orientation tag");
961 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
962 i_push_error(0, "write TIFF: setting planar configuration tag");
965 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
966 i_push_error(0, "write TIFF: setting photometric tag");
969 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
970 i_push_error(0, "write TIFF: setting compression tag");
973 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
974 i_push_error(0, "write TIFF: setting bits per sample tag");
977 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
978 i_push_error(0, "write TIFF: setting samples per pixel tag");
982 got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
983 got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
984 if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
986 if (!i_tags_get_int(&im->tags, "tiff_resolutionunit", 0, &resunit))
987 resunit = RESUNIT_INCH;
988 if (got_xres || got_yres) {
994 resunit = RESUNIT_NONE;
997 if (resunit == RESUNIT_CENTIMETER) {
1002 resunit = RESUNIT_INCH;
1005 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xres)) {
1006 i_push_error(0, "write TIFF: setting xresolution tag");
1009 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
1010 i_push_error(0, "write TIFF: setting yresolution tag");
1013 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
1014 i_push_error(0, "write TIFF: setting resolutionunit tag");
1023 write_one_bilevel(TIFF *tif, i_img *im, int zero_is_white) {
1024 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1026 unsigned char *in_row;
1027 unsigned char *out_row;
1032 mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n",
1033 tif, im, zero_is_white));
1035 /* ignore a silly choice */
1036 if (compress == COMPRESSION_JPEG)
1037 compress = COMPRESSION_PACKBITS;
1040 case COMPRESSION_CCITTRLE:
1041 case COMPRESSION_CCITTFAX3:
1042 case COMPRESSION_CCITTFAX4:
1043 /* natural fax photometric */
1044 photometric = PHOTOMETRIC_MINISWHITE;
1048 /* natural for most computer images */
1049 photometric = PHOTOMETRIC_MINISBLACK;
1053 if (!set_base_tags(tif, im, compress, photometric, 1, 1))
1056 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1057 i_push_error(0, "write TIFF: setting rows per strip tag");
1061 out_size = TIFFScanlineSize(tif);
1062 out_row = (unsigned char *)_TIFFmalloc( out_size );
1063 in_row = mymalloc(im->xsize);
1065 invert = (photometric == PHOTOMETRIC_MINISWHITE) != (zero_is_white != 0);
1067 for (y = 0; y < im->ysize; ++y) {
1069 unsigned char *outp = out_row;
1070 memset(out_row, 0, out_size);
1071 i_gpal(im, 0, im->xsize, y, in_row);
1072 for (x = 0; x < im->xsize; ++x) {
1073 if (invert ? !in_row[x] : in_row[x]) {
1082 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1085 i_push_error(0, "write TIFF: write scan line failed");
1097 set_palette(TIFF *tif, i_img *im, int size) {
1104 colors = (uint16 *)_TIFFmalloc(sizeof(uint16) * 3 * size);
1106 out[1] = colors + size;
1107 out[2] = colors + 2 * size;
1109 count = i_colorcount(im);
1110 for (i = 0; i < count; ++i) {
1111 i_getcolors(im, i, &c, 1);
1112 for (ch = 0; ch < 3; ++ch)
1113 out[ch][i] = c.channel[ch] * 257;
1115 for (; i < size; ++i) {
1116 for (ch = 0; ch < 3; ++ch)
1119 if (!TIFFSetField(tif, TIFFTAG_COLORMAP, out[0], out[1], out[2])) {
1121 i_push_error(0, "write TIFF: setting color map");
1130 write_one_paletted8(TIFF *tif, i_img *im) {
1131 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1132 unsigned char *out_row;
1136 mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
1138 /* ignore a silly choice */
1139 if (compress == COMPRESSION_JPEG ||
1140 compress == COMPRESSION_CCITTRLE ||
1141 compress == COMPRESSION_CCITTFAX3 ||
1142 compress == COMPRESSION_CCITTFAX4)
1143 compress = COMPRESSION_PACKBITS;
1145 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1146 i_push_error(0, "write TIFF: setting rows per strip tag");
1150 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
1153 if (!set_palette(tif, im, 256))
1156 out_size = TIFFScanlineSize(tif);
1157 out_row = (unsigned char *)_TIFFmalloc( out_size );
1159 for (y = 0; y < im->ysize; ++y) {
1160 i_gpal(im, 0, im->xsize, y, out_row);
1161 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1163 i_push_error(0, "write TIFF: write scan line failed");
1174 write_one_paletted4(TIFF *tif, i_img *im) {
1175 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1176 unsigned char *in_row;
1177 unsigned char *out_row;
1181 mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
1183 /* ignore a silly choice */
1184 if (compress == COMPRESSION_JPEG ||
1185 compress == COMPRESSION_CCITTRLE ||
1186 compress == COMPRESSION_CCITTFAX3 ||
1187 compress == COMPRESSION_CCITTFAX4)
1188 compress = COMPRESSION_PACKBITS;
1190 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 4, 1))
1193 if (!set_palette(tif, im, 16))
1196 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1197 i_push_error(0, "write TIFF: setting rows per strip tag");
1201 in_row = mymalloc(im->xsize);
1202 out_size = TIFFScanlineSize(tif);
1203 out_row = (unsigned char *)_TIFFmalloc( out_size );
1205 for (y = 0; y < im->ysize; ++y) {
1206 i_gpal(im, 0, im->xsize, y, in_row);
1207 memset(out_row, 0, out_size);
1208 pack_4bit_to(out_row, in_row, im->xsize);
1209 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1211 i_push_error(0, "write TIFF: write scan line failed");
1223 set_direct_tags(TIFF *tif, i_img *im, uint16 compress,
1224 uint16 bits_per_sample) {
1225 uint16 extras = EXTRASAMPLE_ASSOCALPHA;
1226 uint16 extra_count = im->channels == 2 || im->channels == 4;
1227 uint16 photometric = im->channels >= 3 ?
1228 PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
1230 if (!set_base_tags(tif, im, compress, photometric, bits_per_sample,
1236 if (!TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extra_count, &extras)) {
1237 i_push_error(0, "write TIFF: setting extra samples tag");
1242 if (compress == COMPRESSION_JPEG) {
1244 if (i_tags_get_int(&im->tags, "tiff_jpegquality", 0, &jpeg_quality)
1245 && jpeg_quality >= 0 && jpeg_quality <= 100) {
1246 if (!TIFFSetField(tif, TIFFTAG_JPEGQUALITY, jpeg_quality)) {
1247 i_push_error(0, "write TIFF: setting jpeg quality pseudo-tag");
1257 write_one_32(TIFF *tif, i_img *im) {
1258 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1263 size_t sample_count = im->xsize * im->channels;
1264 size_t sample_index;
1266 mm_log((1, "tiff - write_one_32(tif %p, im %p)\n", tif, im));
1268 /* only 8 and 12 bit samples are supported by jpeg compression */
1269 if (compress == COMPRESSION_JPEG)
1270 compress = COMPRESSION_PACKBITS;
1272 if (!set_direct_tags(tif, im, compress, 32))
1275 in_row = mymalloc(sample_count * sizeof(unsigned));
1276 out_size = TIFFScanlineSize(tif);
1277 out_row = (uint32 *)_TIFFmalloc( out_size );
1279 for (y = 0; y < im->ysize; ++y) {
1280 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 32) <= 0) {
1281 i_push_error(0, "Cannot read 32-bit samples");
1284 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1285 out_row[sample_index] = in_row[sample_index];
1286 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1289 i_push_error(0, "write TIFF: write scan line failed");
1301 write_one_16(TIFF *tif, i_img *im) {
1302 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1307 size_t sample_count = im->xsize * im->channels;
1308 size_t sample_index;
1310 mm_log((1, "tiff - write_one_16(tif %p, im %p)\n", tif, im));
1312 /* only 8 and 12 bit samples are supported by jpeg compression */
1313 if (compress == COMPRESSION_JPEG)
1314 compress = COMPRESSION_PACKBITS;
1316 if (!set_direct_tags(tif, im, compress, 16))
1319 in_row = mymalloc(sample_count * sizeof(unsigned));
1320 out_size = TIFFScanlineSize(tif);
1321 out_row = (uint16 *)_TIFFmalloc( out_size );
1323 for (y = 0; y < im->ysize; ++y) {
1324 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 16) <= 0) {
1325 i_push_error(0, "Cannot read 16-bit samples");
1328 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1329 out_row[sample_index] = in_row[sample_index];
1330 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1333 i_push_error(0, "write TIFF: write scan line failed");
1345 write_one_8(TIFF *tif, i_img *im) {
1346 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1348 unsigned char *out_row;
1350 size_t sample_count = im->xsize * im->channels;
1352 mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
1354 if (!set_direct_tags(tif, im, compress, 8))
1357 out_size = TIFFScanlineSize(tif);
1358 if (out_size < sample_count)
1359 out_size = sample_count;
1360 out_row = (unsigned char *)_TIFFmalloc( out_size );
1362 for (y = 0; y < im->ysize; ++y) {
1363 if (i_gsamp(im, 0, im->xsize, y, out_row, NULL, im->channels) <= 0) {
1364 i_push_error(0, "Cannot read 8-bit samples");
1367 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1369 i_push_error(0, "write TIFF: write scan line failed");
1379 i_writetiff_low(TIFF *tif, i_img *im) {
1380 uint32 width, height;
1386 channels = im->channels;
1388 if (width != im->xsize || height != im->ysize) {
1389 i_push_error(0, "image too large for TIFF");
1393 mm_log((1, "i_writetiff_low: width=%d, height=%d, channels=%d, bits=%d\n", width, height, channels, im->bits));
1394 if (im->type == i_palette_type) {
1395 mm_log((1, "i_writetiff_low: paletted, colors=%d\n", i_colorcount(im)));
1398 if (i_img_is_monochrome(im, &zero_is_white)) {
1399 if (!write_one_bilevel(tif, im, zero_is_white))
1402 else if (im->type == i_palette_type) {
1403 if (i_colorcount(im) <= 16) {
1404 if (!write_one_paletted4(tif, im))
1408 if (!write_one_paletted8(tif, im))
1412 else if (im->bits > 16) {
1413 if (!write_one_32(tif, im))
1416 else if (im->bits > 8) {
1417 if (!write_one_16(tif, im))
1421 if (!write_one_8(tif, im))
1425 if (!save_tiff_tags(tif, im))
1432 =item i_writetiff_multi_wiol(ig, imgs, count, fine_mode)
1434 Stores an image in the iolayer object.
1436 ig - io_object that defines source to write to
1437 imgs,count - the images to write
1443 i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1445 TIFFErrorHandler old_handler;
1447 tiffio_context_t ctx;
1449 old_handler = TIFFSetErrorHandler(error_handler);
1452 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
1455 tiffio_context_init(&ctx, ig);
1457 tif = TIFFClientOpen("No name",
1471 mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n"));
1472 i_push_error(0, "Could not create TIFF object");
1473 TIFFSetErrorHandler(old_handler);
1474 tiffio_context_final(&ctx);
1478 for (i = 0; i < count; ++i) {
1479 if (!i_writetiff_low(tif, imgs[i])) {
1481 TIFFSetErrorHandler(old_handler);
1482 tiffio_context_final(&ctx);
1486 if (!TIFFWriteDirectory(tif)) {
1487 i_push_error(0, "Cannot write TIFF directory");
1489 TIFFSetErrorHandler(old_handler);
1490 tiffio_context_final(&ctx);
1495 TIFFSetErrorHandler(old_handler);
1496 (void) TIFFClose(tif);
1497 tiffio_context_final(&ctx);
1506 =item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1508 Stores an image in the iolayer object.
1510 ig - io_object that defines source to write to
1511 imgs,count - the images to write
1512 fine_mode - select fine or normal mode fax images
1519 i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1522 TIFFErrorHandler old_handler;
1523 tiffio_context_t ctx;
1525 old_handler = TIFFSetErrorHandler(error_handler);
1528 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
1531 tiffio_context_init(&ctx, ig);
1533 tif = TIFFClientOpen("No name",
1547 mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
1548 i_push_error(0, "Could not create TIFF object");
1549 TIFFSetErrorHandler(old_handler);
1550 tiffio_context_final(&ctx);
1554 for (i = 0; i < count; ++i) {
1555 if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1557 TIFFSetErrorHandler(old_handler);
1558 tiffio_context_final(&ctx);
1562 if (!TIFFWriteDirectory(tif)) {
1563 i_push_error(0, "Cannot write TIFF directory");
1565 TIFFSetErrorHandler(old_handler);
1566 tiffio_context_final(&ctx);
1571 (void) TIFFClose(tif);
1572 TIFFSetErrorHandler(old_handler);
1573 tiffio_context_final(&ctx);
1582 =item i_writetiff_wiol(im, ig)
1584 Stores an image in the iolayer object.
1586 im - image object to write out
1587 ig - io_object that defines source to write to
1592 i_writetiff_wiol(i_img *img, io_glue *ig) {
1594 TIFFErrorHandler old_handler;
1595 tiffio_context_t ctx;
1597 old_handler = TIFFSetErrorHandler(error_handler);
1600 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", img, ig));
1602 tiffio_context_init(&ctx, ig);
1604 tif = TIFFClientOpen("No name",
1618 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1619 i_push_error(0, "Could not create TIFF object");
1620 tiffio_context_final(&ctx);
1621 TIFFSetErrorHandler(old_handler);
1625 if (!i_writetiff_low(tif, img)) {
1627 tiffio_context_final(&ctx);
1628 TIFFSetErrorHandler(old_handler);
1632 (void) TIFFClose(tif);
1633 TIFFSetErrorHandler(old_handler);
1634 tiffio_context_final(&ctx);
1645 =item i_writetiff_wiol_faxable(i_img *, io_glue *)
1647 Stores an image in the iolayer object in faxable tiff format.
1649 im - image object to write out
1650 ig - io_object that defines source to write to
1652 Note, this may be rewritten to use to simply be a call to a
1653 lower-level function that gives more options for writing tiff at some
1660 i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1662 TIFFErrorHandler old_handler;
1663 tiffio_context_t ctx;
1665 old_handler = TIFFSetErrorHandler(error_handler);
1668 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", im, ig));
1670 tiffio_context_init(&ctx, ig);
1672 tif = TIFFClientOpen("No name",
1686 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1687 i_push_error(0, "Could not create TIFF object");
1688 TIFFSetErrorHandler(old_handler);
1689 tiffio_context_final(&ctx);
1693 if (!i_writetiff_low_faxable(tif, im, fine)) {
1695 TIFFSetErrorHandler(old_handler);
1696 tiffio_context_final(&ctx);
1700 (void) TIFFClose(tif);
1701 TIFFSetErrorHandler(old_handler);
1702 tiffio_context_final(&ctx);
1710 static int save_tiff_tags(TIFF *tif, i_img *im) {
1713 for (i = 0; i < text_tag_count; ++i) {
1715 if (i_tags_find(&im->tags, text_tag_names[i].name, 0, &entry)) {
1716 if (!TIFFSetField(tif, text_tag_names[i].tag,
1717 im->tags.tags[entry].data)) {
1718 i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1729 unpack_4bit_to(unsigned char *dest, const unsigned char *src,
1730 size_t src_byte_count) {
1731 while (src_byte_count > 0) {
1732 *dest++ = *src >> 4;
1733 *dest++ = *src++ & 0xf;
1738 static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
1739 i_img_dim pixel_count) {
1741 while (i < pixel_count) {
1743 *dest = *src++ << 4;
1753 =item fallback_rgb_channels
1755 Calculate the number of output channels when we fallback to the RGBA
1756 family of functions.
1762 fallback_rgb_channels(TIFF *tif, i_img_dim width, i_img_dim height, int *channels, int *alpha_chan) {
1768 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1769 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1771 switch (photometric) {
1772 case PHOTOMETRIC_SEPARATED:
1776 case PHOTOMETRIC_MINISWHITE:
1777 case PHOTOMETRIC_MINISBLACK:
1778 /* the TIFF RGBA functions expand single channel grey into RGB,
1779 so reduce it, we move the alpha channel into the right place
1788 /* TIFF images can have more than one alpha channel, but Imager can't
1789 this ignores the possibility of 2 channel images with 2 alpha,
1790 but there's not much I can do about that */
1792 if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)
1794 *alpha_chan = (*channels)++;
1799 make_rgb(TIFF *tif, i_img_dim width, i_img_dim height, int *alpha_chan) {
1802 fallback_rgb_channels(tif, width, height, &channels, alpha_chan);
1804 return i_img_8_new(width, height, channels);
1808 read_one_rgb_lines(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
1810 uint32* raster = NULL;
1811 uint32 rowsperstrip, row;
1816 im = make_rgb(tif, width, height, &alpha_chan);
1820 rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1821 mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
1823 if (rc != 1 || rowsperstrip==-1) {
1824 rowsperstrip = height;
1827 raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
1830 i_push_error(0, "No space for raster buffer");
1834 line_buf = mymalloc(sizeof(i_color) * width);
1836 for( row = 0; row < height; row += rowsperstrip ) {
1837 uint32 newrows, i_row;
1839 if (!TIFFReadRGBAStrip(tif, row, raster)) {
1840 if (allow_incomplete) {
1841 i_tags_setn(&im->tags, "i_lines_read", row);
1842 i_tags_setn(&im->tags, "i_incomplete", 1);
1846 i_push_error(0, "could not read TIFF image strip");
1853 newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
1854 mm_log((1, "newrows=%d\n", newrows));
1856 for( i_row = 0; i_row < newrows; i_row++ ) {
1858 i_color *outp = line_buf;
1860 for(x = 0; x<width; x++) {
1861 uint32 temp = raster[x+width*(newrows-i_row-1)];
1862 outp->rgba.r = TIFFGetR(temp);
1863 outp->rgba.g = TIFFGetG(temp);
1864 outp->rgba.b = TIFFGetB(temp);
1867 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1868 alpha in the right place and scale it */
1870 outp->channel[alpha_chan] = TIFFGetA(temp);
1871 if (outp->channel[alpha_chan]) {
1872 for (ch = 0; ch < alpha_chan; ++ch) {
1873 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1880 i_plin(im, 0, width, i_row+row, line_buf);
1890 /* adapted from libtiff
1892 libtiff's TIFFReadRGBATile succeeds even when asked to read an
1893 invalid tile, which means we have no way of knowing whether the data
1894 we received from it is valid or not.
1896 So the caller here has set stoponerror to 1 so that
1897 TIFFRGBAImageGet() will fail.
1899 read_one_rgb_tiled() then takes that into account for i_incomplete
1903 myTIFFReadRGBATile(TIFFRGBAImage *img, uint32 col, uint32 row, uint32 * raster)
1907 uint32 tile_xsize, tile_ysize;
1908 uint32 read_xsize, read_ysize;
1912 * Verify that our request is legal - on a tile file, and on a
1916 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILEWIDTH, &tile_xsize);
1917 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILELENGTH, &tile_ysize);
1918 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
1920 i_push_errorf(0, "Row/col passed to myTIFFReadRGBATile() must be top"
1921 "left corner of a tile.");
1926 * The TIFFRGBAImageGet() function doesn't allow us to get off the
1927 * edge of the image, even to fill an otherwise valid tile. So we
1928 * figure out how much we can read, and fix up the tile buffer to
1929 * a full tile configuration afterwards.
1932 if( row + tile_ysize > img->height )
1933 read_ysize = img->height - row;
1935 read_ysize = tile_ysize;
1937 if( col + tile_xsize > img->width )
1938 read_xsize = img->width - col;
1940 read_xsize = tile_xsize;
1943 * Read the chunk of imagery.
1946 img->row_offset = row;
1947 img->col_offset = col;
1949 ok = TIFFRGBAImageGet(img, raster, read_xsize, read_ysize );
1952 * If our read was incomplete we will need to fix up the tile by
1953 * shifting the data around as if a full tile of data is being returned.
1955 * This is all the more complicated because the image is organized in
1956 * bottom to top format.
1959 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
1962 for( i_row = 0; i_row < read_ysize; i_row++ ) {
1963 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
1964 raster + (read_ysize - i_row - 1) * read_xsize,
1965 read_xsize * sizeof(uint32) );
1966 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
1967 0, sizeof(uint32) * (tile_xsize - read_xsize) );
1970 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
1971 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
1972 0, sizeof(uint32) * tile_xsize );
1979 read_one_rgb_tiled(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
1981 uint32* raster = NULL;
1984 uint32 tile_width, tile_height;
1985 unsigned long pixels = 0;
1986 char emsg[1024] = "";
1991 im = make_rgb(tif, width, height, &alpha_chan);
1995 if (!TIFFRGBAImageOK(tif, emsg)
1996 || !TIFFRGBAImageBegin(&img, tif, 1, emsg)) {
1997 i_push_error(0, emsg);
2002 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
2003 TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
2004 mm_log((1, "i_readtiff_wiol: tile_width=%d, tile_height=%d\n", tile_width, tile_height));
2006 raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
2009 i_push_error(0, "No space for raster buffer");
2010 TIFFRGBAImageEnd(&img);
2013 line = mymalloc(tile_width * sizeof(i_color));
2015 for( row = 0; row < height; row += tile_height ) {
2016 for( col = 0; col < width; col += tile_width ) {
2018 /* Read the tile into an RGBA array */
2019 if (myTIFFReadRGBATile(&img, col, row, raster)) {
2021 uint32 newrows = (row+tile_height > height) ? height-row : tile_height;
2022 uint32 newcols = (col+tile_width > width ) ? width-col : tile_width;
2024 mm_log((1, "i_readtiff_wiol: tile(%d, %d) newcols=%d newrows=%d\n", col, row, newcols, newrows));
2025 for( i_row = 0; i_row < newrows; i_row++ ) {
2026 i_color *outp = line;
2027 for(x = 0; x < newcols; x++) {
2028 uint32 temp = raster[x+tile_width*(tile_height-i_row-1)];
2029 outp->rgba.r = TIFFGetR(temp);
2030 outp->rgba.g = TIFFGetG(temp);
2031 outp->rgba.b = TIFFGetB(temp);
2032 outp->rgba.a = TIFFGetA(temp);
2035 /* the libtiff RGBA code expands greyscale into RGBA, so put the
2036 alpha in the right place and scale it */
2038 outp->channel[alpha_chan] = TIFFGetA(temp);
2040 if (outp->channel[alpha_chan]) {
2041 for (ch = 0; ch < alpha_chan; ++ch) {
2042 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
2049 i_plin(im, col, col+newcols, row+i_row, line);
2051 pixels += newrows * newcols;
2054 if (allow_incomplete) {
2066 i_push_error(0, "TIFF: No image data could be read from the image");
2070 /* incomplete image */
2071 i_tags_setn(&im->tags, "i_incomplete", 1);
2072 i_tags_setn(&im->tags, "i_lines_read", pixels / width);
2076 TIFFRGBAImageEnd(&img);
2084 TIFFRGBAImageEnd(&img);
2090 i_tiff_libversion(void) {
2091 return TIFFGetVersion();
2095 setup_paletted(read_state_t *state) {
2098 int color_count = 1 << state->bits_per_sample;
2100 state->img = i_img_pal_new(state->width, state->height, 3, 256);
2104 /* setup the color map */
2105 if (!TIFFGetField(state->tif, TIFFTAG_COLORMAP, maps+0, maps+1, maps+2)) {
2106 i_push_error(0, "Cannot get colormap for paletted image");
2107 i_img_destroy(state->img);
2110 for (i = 0; i < color_count; ++i) {
2112 for (ch = 0; ch < 3; ++ch) {
2113 c.channel[ch] = Sample16To8(maps[ch][i]);
2115 i_addcolors(state->img, &c, 1);
2122 tile_contig_getter(read_state_t *state, read_putter_t putter) {
2123 uint32 tile_width, tile_height;
2124 uint32 this_tile_height, this_tile_width;
2125 uint32 rows_left, cols_left;
2128 state->raster = _TIFFmalloc(TIFFTileSize(state->tif));
2129 if (!state->raster) {
2130 i_push_error(0, "tiff: Out of memory allocating tile buffer");
2134 TIFFGetField(state->tif, TIFFTAG_TILEWIDTH, &tile_width);
2135 TIFFGetField(state->tif, TIFFTAG_TILELENGTH, &tile_height);
2136 rows_left = state->height;
2137 for (y = 0; y < state->height; y += this_tile_height) {
2138 this_tile_height = rows_left > tile_height ? tile_height : rows_left;
2140 cols_left = state->width;
2141 for (x = 0; x < state->width; x += this_tile_width) {
2142 this_tile_width = cols_left > tile_width ? tile_width : cols_left;
2144 if (TIFFReadTile(state->tif,
2147 if (!state->allow_incomplete) {
2152 putter(state, x, y, this_tile_width, this_tile_height, tile_width - this_tile_width);
2155 cols_left -= this_tile_width;
2158 rows_left -= this_tile_height;
2165 strip_contig_getter(read_state_t *state, read_putter_t putter) {
2166 uint32 rows_per_strip;
2167 tsize_t strip_size = TIFFStripSize(state->tif);
2168 uint32 y, strip_rows, rows_left;
2170 state->raster = _TIFFmalloc(strip_size);
2171 if (!state->raster) {
2172 i_push_error(0, "tiff: Out of memory allocating strip buffer");
2176 TIFFGetFieldDefaulted(state->tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
2177 rows_left = state->height;
2178 for (y = 0; y < state->height; y += strip_rows) {
2179 strip_rows = rows_left > rows_per_strip ? rows_per_strip : rows_left;
2180 if (TIFFReadEncodedStrip(state->tif,
2181 TIFFComputeStrip(state->tif, y, 0),
2184 if (!state->allow_incomplete)
2188 putter(state, 0, y, state->width, strip_rows, 0);
2190 rows_left -= strip_rows;
2197 paletted_putter8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
2198 unsigned char *p = state->raster;
2200 state->pixels_read += width * height;
2201 while (height > 0) {
2202 i_ppal(state->img, x, x + width, y, p);
2203 p += width + extras;
2212 paletted_putter4(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
2213 uint32 img_line_size = (width + 1) / 2;
2214 uint32 skip_line_size = (width + extras + 1) / 2;
2215 unsigned char *p = state->raster;
2217 if (!state->line_buf)
2218 state->line_buf = mymalloc(state->width);
2220 state->pixels_read += width * height;
2221 while (height > 0) {
2222 unpack_4bit_to(state->line_buf, p, img_line_size);
2223 i_ppal(state->img, x, x + width, y, state->line_buf);
2224 p += skip_line_size;
2233 rgb_channels(read_state_t *state, int *out_channels) {
2239 state->alpha_chan = 0;
2240 state->scale_alpha = 0;
2243 if (state->samples_per_pixel == 3)
2246 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2247 mm_log((1, "tiff: samples != 3 but no extra samples tag\n"));
2252 mm_log((1, "tiff: samples != 3 but no extra samples listed"));
2257 state->alpha_chan = 3;
2259 case EXTRASAMPLE_UNSPECIFIED:
2260 case EXTRASAMPLE_ASSOCALPHA:
2261 state->scale_alpha = 1;
2264 case EXTRASAMPLE_UNASSALPHA:
2265 state->scale_alpha = 0;
2269 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2271 state->scale_alpha = 1;
2274 mm_log((1, "tiff alpha channel %d scale %d\n", state->alpha_chan, state->scale_alpha));
2278 grey_channels(read_state_t *state, int *out_channels) {
2284 state->alpha_chan = 0;
2285 state->scale_alpha = 0;
2288 if (state->samples_per_pixel == 1)
2291 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2292 mm_log((1, "tiff: samples != 1 but no extra samples tag\n"));
2297 mm_log((1, "tiff: samples != 1 but no extra samples listed"));
2302 state->alpha_chan = 1;
2304 case EXTRASAMPLE_UNSPECIFIED:
2305 case EXTRASAMPLE_ASSOCALPHA:
2306 state->scale_alpha = 1;
2309 case EXTRASAMPLE_UNASSALPHA:
2310 state->scale_alpha = 0;
2314 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2316 state->scale_alpha = 1;
2322 setup_16_rgb(read_state_t *state) {
2325 rgb_channels(state, &out_channels);
2327 state->img = i_img_16_new(state->width, state->height, out_channels);
2330 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2336 setup_16_grey(read_state_t *state) {
2339 grey_channels(state, &out_channels);
2341 state->img = i_img_16_new(state->width, state->height, out_channels);
2344 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2350 putter_16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2352 uint16 *p = state->raster;
2353 int out_chan = state->img->channels;
2355 state->pixels_read += width * height;
2356 while (height > 0) {
2359 unsigned *outp = state->line_buf;
2361 for (i = 0; i < width; ++i) {
2362 for (ch = 0; ch < out_chan; ++ch) {
2365 if (state->alpha_chan && state->scale_alpha && outp[state->alpha_chan]) {
2366 for (ch = 0; ch < state->alpha_chan; ++ch) {
2367 int result = 0.5 + (outp[ch] * 65535.0 / outp[state->alpha_chan]);
2368 outp[ch] = CLAMP16(result);
2371 p += state->samples_per_pixel;
2375 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2377 p += row_extras * state->samples_per_pixel;
2386 setup_8_rgb(read_state_t *state) {
2389 rgb_channels(state, &out_channels);
2391 state->img = i_img_8_new(state->width, state->height, out_channels);
2394 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2400 setup_8_grey(read_state_t *state) {
2403 grey_channels(state, &out_channels);
2405 state->img = i_img_8_new(state->width, state->height, out_channels);
2408 state->line_buf = mymalloc(sizeof(i_color) * state->width * out_channels);
2414 putter_8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2416 unsigned char *p = state->raster;
2417 int out_chan = state->img->channels;
2419 state->pixels_read += width * height;
2420 while (height > 0) {
2423 i_color *outp = state->line_buf;
2425 for (i = 0; i < width; ++i) {
2426 for (ch = 0; ch < out_chan; ++ch) {
2427 outp->channel[ch] = p[ch];
2429 if (state->alpha_chan && state->scale_alpha
2430 && outp->channel[state->alpha_chan]) {
2431 for (ch = 0; ch < state->alpha_chan; ++ch) {
2432 int result = (outp->channel[ch] * 255 + 127) / outp->channel[state->alpha_chan];
2434 outp->channel[ch] = CLAMP8(result);
2437 p += state->samples_per_pixel;
2441 i_plin(state->img, x, x + width, y, state->line_buf);
2443 p += row_extras * state->samples_per_pixel;
2452 setup_32_rgb(read_state_t *state) {
2455 rgb_channels(state, &out_channels);
2457 state->img = i_img_double_new(state->width, state->height, out_channels);
2460 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2466 setup_32_grey(read_state_t *state) {
2469 grey_channels(state, &out_channels);
2471 state->img = i_img_double_new(state->width, state->height, out_channels);
2474 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2480 putter_32(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2482 uint32 *p = state->raster;
2483 int out_chan = state->img->channels;
2485 state->pixels_read += width * height;
2486 while (height > 0) {
2489 i_fcolor *outp = state->line_buf;
2491 for (i = 0; i < width; ++i) {
2492 for (ch = 0; ch < out_chan; ++ch) {
2493 outp->channel[ch] = p[ch] / 4294967295.0;
2495 if (state->alpha_chan && state->scale_alpha && outp->channel[state->alpha_chan]) {
2496 for (ch = 0; ch < state->alpha_chan; ++ch)
2497 outp->channel[ch] /= outp->channel[state->alpha_chan];
2499 p += state->samples_per_pixel;
2503 i_plinf(state->img, x, x + width, y, state->line_buf);
2505 p += row_extras * state->samples_per_pixel;
2514 setup_bilevel(read_state_t *state) {
2515 i_color black, white;
2516 state->img = i_img_pal_new(state->width, state->height, 1, 256);
2519 black.channel[0] = black.channel[1] = black.channel[2] =
2520 black.channel[3] = 0;
2521 white.channel[0] = white.channel[1] = white.channel[2] =
2522 white.channel[3] = 255;
2523 if (state->photometric == PHOTOMETRIC_MINISBLACK) {
2524 i_addcolors(state->img, &black, 1);
2525 i_addcolors(state->img, &white, 1);
2528 i_addcolors(state->img, &white, 1);
2529 i_addcolors(state->img, &black, 1);
2531 state->line_buf = mymalloc(state->width);
2537 putter_bilevel(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2539 unsigned char *line_in = state->raster;
2540 size_t line_size = (width + row_extras + 7) / 8;
2542 /* tifflib returns the bits in MSB2LSB order even when the file is
2543 in LSB2MSB, so we only need to handle MSB2LSB */
2544 state->pixels_read += width * height;
2545 while (height > 0) {
2547 unsigned char *outp = state->line_buf;
2548 unsigned char *inp = line_in;
2549 unsigned mask = 0x80;
2551 for (i = 0; i < width; ++i) {
2552 *outp++ = *inp & mask ? 1 : 0;
2560 i_ppal(state->img, x, x + width, y, state->line_buf);
2562 line_in += line_size;
2571 cmyk_channels(read_state_t *state, int *out_channels) {
2577 state->alpha_chan = 0;
2578 state->scale_alpha = 0;
2581 if (state->samples_per_pixel == 4)
2584 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2585 mm_log((1, "tiff: CMYK samples != 4 but no extra samples tag\n"));
2590 mm_log((1, "tiff: CMYK samples != 4 but no extra samples listed"));
2595 state->alpha_chan = 4;
2597 case EXTRASAMPLE_UNSPECIFIED:
2598 case EXTRASAMPLE_ASSOCALPHA:
2599 state->scale_alpha = 1;
2602 case EXTRASAMPLE_UNASSALPHA:
2603 state->scale_alpha = 0;
2607 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2609 state->scale_alpha = 1;
2615 setup_cmyk8(read_state_t *state) {
2618 cmyk_channels(state, &channels);
2619 state->img = i_img_8_new(state->width, state->height, channels);
2621 state->line_buf = mymalloc(sizeof(i_color) * state->width);
2627 putter_cmyk8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2629 unsigned char *p = state->raster;
2631 state->pixels_read += width * height;
2632 while (height > 0) {
2635 i_color *outp = state->line_buf;
2637 for (i = 0; i < width; ++i) {
2638 unsigned char c, m, y, k;
2643 outp->rgba.r = (k * (255 - c)) / 255;
2644 outp->rgba.g = (k * (255 - m)) / 255;
2645 outp->rgba.b = (k * (255 - y)) / 255;
2646 if (state->alpha_chan) {
2647 outp->rgba.a = p[state->alpha_chan];
2648 if (state->scale_alpha
2650 for (ch = 0; ch < 3; ++ch) {
2651 int result = (outp->channel[ch] * 255 + 127) / outp->rgba.a;
2652 outp->channel[ch] = CLAMP8(result);
2656 p += state->samples_per_pixel;
2660 i_plin(state->img, x, x + width, y, state->line_buf);
2662 p += row_extras * state->samples_per_pixel;
2671 setup_cmyk16(read_state_t *state) {
2674 cmyk_channels(state, &channels);
2675 state->img = i_img_16_new(state->width, state->height, channels);
2677 state->line_buf = mymalloc(sizeof(unsigned) * state->width * channels);
2683 putter_cmyk16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2685 uint16 *p = state->raster;
2686 int out_chan = state->img->channels;
2688 mm_log((4, "putter_cmyk16(%p, %d, %d, %d, %d, %d)\n", x, y, width, height, row_extras));
2690 state->pixels_read += width * height;
2691 while (height > 0) {
2694 unsigned *outp = state->line_buf;
2696 for (i = 0; i < width; ++i) {
2697 unsigned c, m, y, k;
2702 outp[0] = (k * (65535U - c)) / 65535U;
2703 outp[1] = (k * (65535U - m)) / 65535U;
2704 outp[2] = (k * (65535U - y)) / 65535U;
2705 if (state->alpha_chan) {
2706 outp[3] = p[state->alpha_chan];
2707 if (state->scale_alpha
2709 for (ch = 0; ch < 3; ++ch) {
2710 int result = (outp[ch] * 65535 + 32767) / outp[3];
2711 outp[3] = CLAMP16(result);
2715 p += state->samples_per_pixel;
2719 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2721 p += row_extras * state->samples_per_pixel;
2731 Older versions of tifflib we support don't define this, so define it
2734 If you want this detection to do anything useful, use a newer
2738 #if TIFFLIB_VERSION < 20031121
2741 TIFFIsCODECConfigured(uint16 scheme) {
2743 /* these schemes are all shipped with tifflib */
2744 case COMPRESSION_NONE:
2745 case COMPRESSION_PACKBITS:
2746 case COMPRESSION_CCITTRLE:
2747 case COMPRESSION_CCITTRLEW:
2748 case COMPRESSION_CCITTFAX3:
2749 case COMPRESSION_CCITTFAX4:
2752 /* these require external library support */
2754 case COMPRESSION_JPEG:
2755 case COMPRESSION_LZW:
2756 case COMPRESSION_DEFLATE:
2757 case COMPRESSION_ADOBE_DEFLATE:
2765 myTIFFIsCODECConfigured(uint16 scheme) {
2766 #if TIFFLIB_VERSION < 20040724
2767 if (scheme == COMPRESSION_LZW)
2771 return TIFFIsCODECConfigured(scheme);
2775 tiffio_context_init(tiffio_context_t *c, io_glue *ig) {
2776 c->magic = TIFFIO_MAGIC;
2778 #ifdef USE_EXT_WARN_HANDLER
2779 c->warn_buffer = NULL;
2785 tiffio_context_final(tiffio_context_t *c) {
2786 c->magic = TIFFIO_MAGIC;
2787 #ifdef USE_EXT_WARN_HANDLER
2789 myfree(c->warn_buffer);
2798 Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tonyc@cpan.org>