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 static const int text_tag_count =
164 sizeof(text_tag_names) / sizeof(*text_tag_names);
166 static void error_handler(char const *module, char const *fmt, va_list ap) {
167 mm_log((1, "tiff error fmt %s\n", fmt));
168 i_push_errorvf(0, fmt, ap);
171 #define WARN_BUFFER_LIMIT 10000
172 static char *warn_buffer = NULL;
173 static int warn_buffer_size = 0;
175 static void warn_handler(char const *module, char const *fmt, va_list ap) {
180 vsnprintf(buf, sizeof(buf), fmt, ap);
182 vsprintf(buf, fmt, ap);
184 mm_log((1, "tiff warning %s\n", buf));
186 if (!warn_buffer || strlen(warn_buffer)+strlen(buf)+2 > warn_buffer_size) {
187 int new_size = warn_buffer_size + strlen(buf) + 2;
188 char *old_buffer = warn_buffer;
189 if (new_size > WARN_BUFFER_LIMIT) {
190 new_size = WARN_BUFFER_LIMIT;
192 warn_buffer = myrealloc(warn_buffer, new_size);
193 if (!old_buffer) *warn_buffer = '\0';
194 warn_buffer_size = new_size;
196 if (strlen(warn_buffer)+strlen(buf)+2 <= warn_buffer_size) {
197 strcat(warn_buffer, buf);
198 strcat(warn_buffer, "\n");
202 static int save_tiff_tags(TIFF *tif, i_img *im);
205 pack_4bit_to(unsigned char *dest, const unsigned char *src, i_img_dim count);
208 static toff_t sizeproc(thandle_t x) {
214 =item comp_seek(h, o, w)
216 Compatability for 64 bit systems like latest freebsd (internal)
218 h - tiff handle, cast an io_glue object
227 comp_seek(thandle_t h, toff_t o, int w) {
228 io_glue *ig = (io_glue*)h;
229 return (toff_t) ig->seekcb(ig, o, w);
233 =item comp_mmap(thandle_t, tdata_t*, toff_t*)
237 This shouldn't ever be called but newer tifflibs want it anyway.
244 comp_mmap(thandle_t h, tdata_t*p, toff_t*off) {
249 =item comp_munmap(thandle_t h, tdata_t p, toff_t off)
253 This shouldn't ever be called but newer tifflibs want it anyway.
259 comp_munmap(thandle_t h, tdata_t p, toff_t off) {
263 static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
265 uint32 width, height;
266 uint16 samples_per_pixel;
270 int gotXres, gotYres;
272 uint16 bits_per_sample;
273 uint16 planar_config;
278 read_setup_t setupf = NULL;
279 read_getter_t getterf = NULL;
280 read_putter_t putterf = NULL;
284 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
285 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
286 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
287 tiled = TIFFIsTiled(tif);
288 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
289 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
290 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
291 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
293 mm_log((1, "i_readtiff_wiol: width=%d, height=%d, channels=%d\n", width, height, samples_per_pixel));
294 mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
295 mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
297 /* yes, this if() is horrible */
298 if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8) {
299 setupf = setup_paletted;
300 if (bits_per_sample == 8)
301 putterf = paletted_putter8;
302 else if (bits_per_sample == 4)
303 putterf = paletted_putter4;
305 mm_log((1, "unsupported paletted bits_per_sample %d\n", bits_per_sample));
307 else if (bits_per_sample == 16
308 && photometric == PHOTOMETRIC_RGB
309 && samples_per_pixel >= 3) {
310 setupf = setup_16_rgb;
313 else if (bits_per_sample == 16
314 && photometric == PHOTOMETRIC_MINISBLACK) {
315 setupf = setup_16_grey;
318 else if (bits_per_sample == 8
319 && photometric == PHOTOMETRIC_MINISBLACK) {
320 setupf = setup_8_grey;
323 else if (bits_per_sample == 8
324 && photometric == PHOTOMETRIC_RGB) {
325 setupf = setup_8_rgb;
328 else if (bits_per_sample == 32
329 && photometric == PHOTOMETRIC_RGB
330 && samples_per_pixel >= 3) {
331 setupf = setup_32_rgb;
334 else if (bits_per_sample == 32
335 && photometric == PHOTOMETRIC_MINISBLACK) {
336 setupf = setup_32_grey;
339 else if (bits_per_sample == 1
340 && (photometric == PHOTOMETRIC_MINISBLACK
341 || photometric == PHOTOMETRIC_MINISWHITE)
342 && samples_per_pixel == 1) {
343 setupf = setup_bilevel;
344 putterf = putter_bilevel;
346 else if (bits_per_sample == 8
347 && photometric == PHOTOMETRIC_SEPARATED
348 && inkset == INKSET_CMYK
349 && samples_per_pixel >= 4) {
350 setupf = setup_cmyk8;
351 putterf = putter_cmyk8;
353 else if (bits_per_sample == 16
354 && photometric == PHOTOMETRIC_SEPARATED
355 && inkset == INKSET_CMYK
356 && samples_per_pixel >= 4) {
357 setupf = setup_cmyk16;
358 putterf = putter_cmyk16;
361 if (planar_config == PLANARCONFIG_CONTIG)
362 getterf = tile_contig_getter;
365 if (planar_config == PLANARCONFIG_CONTIG)
366 getterf = strip_contig_getter;
368 if (setupf && getterf && putterf) {
369 i_img_dim total_pixels = width * height;
370 memset(&state, 0, sizeof(state));
372 state.allow_incomplete = allow_incomplete;
374 state.height = height;
375 state.bits_per_sample = bits_per_sample;
376 state.samples_per_pixel = samples_per_pixel;
377 state.photometric = photometric;
381 if (!getterf(&state, putterf) || !state.pixels_read) {
383 i_img_destroy(state.img);
385 _TIFFfree(state.raster);
387 myfree(state.line_buf);
392 if (allow_incomplete && state.pixels_read < total_pixels) {
393 i_tags_setn(&(state.img->tags), "i_incomplete", 1);
394 i_tags_setn(&(state.img->tags), "i_lines_read",
395 state.pixels_read / width);
400 _TIFFfree(state.raster);
402 myfree(state.line_buf);
406 im = read_one_rgb_tiled(tif, width, height, allow_incomplete);
409 im = read_one_rgb_lines(tif, width, height, allow_incomplete);
416 /* general metadata */
417 i_tags_setn(&im->tags, "tiff_bitspersample", bits_per_sample);
418 i_tags_setn(&im->tags, "tiff_photometric", photometric);
419 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
421 /* resolution tags */
422 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
423 gotXres = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
424 gotYres = TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
425 if (gotXres || gotYres) {
430 i_tags_setn(&im->tags, "tiff_resolutionunit", resunit);
431 if (resunit == RESUNIT_CENTIMETER) {
432 /* from dots per cm to dpi */
435 i_tags_set(&im->tags, "tiff_resolutionunit_name", "centimeter", -1);
437 else if (resunit == RESUNIT_NONE) {
438 i_tags_setn(&im->tags, "i_aspect_only", 1);
439 i_tags_set(&im->tags, "tiff_resolutionunit_name", "none", -1);
441 else if (resunit == RESUNIT_INCH) {
442 i_tags_set(&im->tags, "tiff_resolutionunit_name", "inch", -1);
445 i_tags_set(&im->tags, "tiff_resolutionunit_name", "unknown", -1);
447 /* tifflib doesn't seem to provide a way to get to the original rational
448 value of these, which would let me provide a more reasonable
449 precision. So make up a number. */
450 i_tags_set_float2(&im->tags, "i_xres", 0, xres, 6);
451 i_tags_set_float2(&im->tags, "i_yres", 0, yres, 6);
455 for (i = 0; i < text_tag_count; ++i) {
457 if (TIFFGetField(tif, text_tag_names[i].tag, &data)) {
458 mm_log((1, "i_readtiff_wiol: tag %d has value %s\n",
459 text_tag_names[i].tag, data));
460 i_tags_set(&im->tags, text_tag_names[i].name, data, -1);
464 i_tags_set(&im->tags, "i_format", "tiff", 4);
465 if (warn_buffer && *warn_buffer) {
466 i_tags_set(&im->tags, "i_warning", warn_buffer, -1);
470 for (i = 0; i < compress_value_count; ++i) {
471 if (compress_values[i].tag == compress) {
472 i_tags_set(&im->tags, "tiff_compression", compress_values[i].name, -1);
481 =item i_readtiff_wiol(im, ig)
486 i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
488 TIFFErrorHandler old_handler;
489 TIFFErrorHandler old_warn_handler;
493 old_handler = TIFFSetErrorHandler(error_handler);
494 old_warn_handler = TIFFSetWarningHandler(warn_handler);
498 /* Add code to get the filename info from the iolayer */
499 /* Also add code to check for mmapped code */
501 mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
503 tif = TIFFClientOpen("(Iolayer)",
506 (TIFFReadWriteProc) ig->readcb,
507 (TIFFReadWriteProc) ig->writecb,
508 (TIFFSeekProc) comp_seek,
509 (TIFFCloseProc) ig->closecb,
510 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
511 (TIFFMapFileProc) comp_mmap,
512 (TIFFUnmapFileProc) comp_munmap);
515 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
516 i_push_error(0, "Error opening file");
517 TIFFSetErrorHandler(old_handler);
518 TIFFSetWarningHandler(old_warn_handler);
523 if (!TIFFSetDirectory(tif, page)) {
524 mm_log((1, "i_readtiff_wiol: Unable to switch to directory %d\n", page));
525 i_push_errorf(0, "could not switch to page %d", page);
526 TIFFSetErrorHandler(old_handler);
527 TIFFSetWarningHandler(old_warn_handler);
533 im = read_one_tiff(tif, allow_incomplete);
535 if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
536 TIFFSetErrorHandler(old_handler);
537 TIFFSetWarningHandler(old_warn_handler);
543 =item i_readtiff_multi_wiol(ig, *count)
545 Reads multiple images from a TIFF.
550 i_readtiff_multi_wiol(io_glue *ig, int *count) {
552 TIFFErrorHandler old_handler;
553 TIFFErrorHandler old_warn_handler;
554 i_img **results = NULL;
555 int result_alloc = 0;
559 old_handler = TIFFSetErrorHandler(error_handler);
560 old_warn_handler = TIFFSetWarningHandler(warn_handler);
564 /* Add code to get the filename info from the iolayer */
565 /* Also add code to check for mmapped code */
567 mm_log((1, "i_readtiff_wiol(ig %p, length %d)\n", ig));
569 tif = TIFFClientOpen("(Iolayer)",
572 (TIFFReadWriteProc) ig->readcb,
573 (TIFFReadWriteProc) ig->writecb,
574 (TIFFSeekProc) comp_seek,
575 (TIFFCloseProc) ig->closecb,
576 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
577 (TIFFMapFileProc) comp_mmap,
578 (TIFFUnmapFileProc) comp_munmap);
581 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
582 i_push_error(0, "Error opening file");
583 TIFFSetErrorHandler(old_handler);
584 TIFFSetWarningHandler(old_warn_handler);
590 i_img *im = read_one_tiff(tif, 0);
593 if (++*count > result_alloc) {
594 if (result_alloc == 0) {
596 results = mymalloc(result_alloc * sizeof(i_img *));
601 newresults = myrealloc(results, result_alloc * sizeof(i_img *));
603 i_img_destroy(im); /* don't leak it */
606 results = newresults;
609 results[*count-1] = im;
610 } while (TIFFSetDirectory(tif, ++dirnum));
612 TIFFSetWarningHandler(old_warn_handler);
613 TIFFSetErrorHandler(old_handler);
619 i_writetiff_low_faxable(TIFF *tif, i_img *im, int fine) {
620 uint32 width, height;
621 unsigned char *linebuf = NULL;
626 float vres = fine ? 196 : 98;
632 if (width != im->xsize || height != im->ysize) {
633 i_push_error(0, "image too large for TIFF");
637 switch (im->channels) {
647 /* This means a colorspace we don't handle yet */
648 mm_log((1, "i_writetiff_wiol_faxable: don't handle %d channel images.\n", im->channels));
652 /* Add code to get the filename info from the iolayer */
653 /* Also add code to check for mmapped code */
656 mm_log((1, "i_writetiff_wiol_faxable: width=%d, height=%d, channels=%d\n", width, height, im->channels));
658 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width) )
659 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField width=%d failed\n", width)); return 0; }
660 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height) )
661 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField length=%d failed\n", height)); return 0; }
662 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
663 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField samplesperpixel=1 failed\n")); return 0; }
664 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT))
665 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Orientation=topleft\n")); return 0; }
666 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1) )
667 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField bitpersample=1\n")); return 0; }
668 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG))
669 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField planarconfig\n")); return 0; }
670 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
671 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField photometric=%d\n", PHOTOMETRIC_MINISBLACK)); return 0; }
672 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, 3))
673 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField compression=3\n")); return 0; }
675 linebuf = (unsigned char *)_TIFFmalloc( TIFFScanlineSize(tif) );
677 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
678 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField rowsperstrip=-1\n")); return 0; }
680 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
681 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rc);
683 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField rowsperstrip=%d\n", rowsperstrip));
684 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField scanlinesize=%d\n", TIFFScanlineSize(tif) ));
685 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField planarconfig=%d == %d\n", rc, PLANARCONFIG_CONTIG));
687 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)204))
688 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Xresolution=204\n")); return 0; }
689 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, vres))
690 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Yresolution=196\n")); return 0; }
691 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)) {
692 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField ResolutionUnit=%d\n", RESUNIT_INCH)); return 0;
695 if (!save_tiff_tags(tif, im)) {
699 for (y=0; y<height; y++) {
701 for(x=0; x<width; x+=8) {
706 linebuf[linebufpos]=0;
707 bits = width-x; if(bits>8) bits=8;
708 i_gsamp(im, x, x+8, y, luma, &luma_chan, 1);
709 for(bitpos=0;bitpos<bits;bitpos++) {
710 linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
715 if (TIFFWriteScanline(tif, linebuf, y, 0) < 0) {
716 mm_log((1, "i_writetiff_wiol_faxable: TIFFWriteScanline failed.\n"));
720 if (linebuf) _TIFFfree(linebuf);
726 find_compression(char const *name, uint16 *compress) {
729 for (i = 0; i < compress_value_count; ++i) {
730 if (strcmp(compress_values[i].name, name) == 0) {
731 *compress = (uint16)compress_values[i].tag;
735 *compress = COMPRESSION_NONE;
741 get_compression(i_img *im, uint16 def_compress) {
745 if (i_tags_find(&im->tags, "tiff_compression", 0, &entry)
746 && im->tags.tags[entry].data) {
748 if (find_compression(im->tags.tags[entry].data, &compress)
749 && myTIFFIsCODECConfigured(compress))
752 if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
753 if ((uint16)value == value
754 && myTIFFIsCODECConfigured((uint16)value))
755 return (uint16)value;
762 i_tiff_has_compression(const char *name) {
765 if (!find_compression(name, &compress))
768 return myTIFFIsCODECConfigured(compress);
772 set_base_tags(TIFF *tif, i_img *im, uint16 compress, uint16 photometric,
773 uint16 bits_per_sample, uint16 samples_per_pixel) {
776 int got_xres, got_yres;
779 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->xsize)) {
780 i_push_error(0, "write TIFF: setting width tag");
783 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
784 i_push_error(0, "write TIFF: setting length tag");
787 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
788 i_push_error(0, "write TIFF: setting orientation tag");
791 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
792 i_push_error(0, "write TIFF: setting planar configuration tag");
795 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
796 i_push_error(0, "write TIFF: setting photometric tag");
799 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
800 i_push_error(0, "write TIFF: setting compression tag");
803 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
804 i_push_error(0, "write TIFF: setting bits per sample tag");
807 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
808 i_push_error(0, "write TIFF: setting samples per pixel tag");
812 got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
813 got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
814 if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
816 if (!i_tags_get_int(&im->tags, "tiff_resolutionunit", 0, &resunit))
817 resunit = RESUNIT_INCH;
818 if (got_xres || got_yres) {
824 resunit = RESUNIT_NONE;
827 if (resunit == RESUNIT_CENTIMETER) {
832 resunit = RESUNIT_INCH;
835 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xres)) {
836 i_push_error(0, "write TIFF: setting xresolution tag");
839 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
840 i_push_error(0, "write TIFF: setting yresolution tag");
843 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
844 i_push_error(0, "write TIFF: setting resolutionunit tag");
853 write_one_bilevel(TIFF *tif, i_img *im, int zero_is_white) {
854 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
856 unsigned char *in_row;
857 unsigned char *out_row;
862 mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n",
863 tif, im, zero_is_white));
865 /* ignore a silly choice */
866 if (compress == COMPRESSION_JPEG)
867 compress = COMPRESSION_PACKBITS;
870 case COMPRESSION_CCITTRLE:
871 case COMPRESSION_CCITTFAX3:
872 case COMPRESSION_CCITTFAX4:
873 /* natural fax photometric */
874 photometric = PHOTOMETRIC_MINISWHITE;
878 /* natural for most computer images */
879 photometric = PHOTOMETRIC_MINISBLACK;
883 if (!set_base_tags(tif, im, compress, photometric, 1, 1))
886 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
887 i_push_error(0, "write TIFF: setting rows per strip tag");
891 out_size = TIFFScanlineSize(tif);
892 out_row = (unsigned char *)_TIFFmalloc( out_size );
893 in_row = mymalloc(im->xsize);
895 invert = (photometric == PHOTOMETRIC_MINISWHITE) != (zero_is_white != 0);
897 for (y = 0; y < im->ysize; ++y) {
899 unsigned char *outp = out_row;
900 memset(out_row, 0, out_size);
901 i_gpal(im, 0, im->xsize, y, in_row);
902 for (x = 0; x < im->xsize; ++x) {
903 if (invert ? !in_row[x] : in_row[x]) {
912 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
915 i_push_error(0, "write TIFF: write scan line failed");
927 set_palette(TIFF *tif, i_img *im, int size) {
934 colors = (uint16 *)_TIFFmalloc(sizeof(uint16) * 3 * size);
936 out[1] = colors + size;
937 out[2] = colors + 2 * size;
939 count = i_colorcount(im);
940 for (i = 0; i < count; ++i) {
941 i_getcolors(im, i, &c, 1);
942 for (ch = 0; ch < 3; ++ch)
943 out[ch][i] = c.channel[ch] * 257;
945 for (; i < size; ++i) {
946 for (ch = 0; ch < 3; ++ch)
949 if (!TIFFSetField(tif, TIFFTAG_COLORMAP, out[0], out[1], out[2])) {
951 i_push_error(0, "write TIFF: setting color map");
960 write_one_paletted8(TIFF *tif, i_img *im) {
961 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
962 unsigned char *out_row;
966 mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
968 /* ignore a silly choice */
969 if (compress == COMPRESSION_JPEG ||
970 compress == COMPRESSION_CCITTRLE ||
971 compress == COMPRESSION_CCITTFAX3 ||
972 compress == COMPRESSION_CCITTFAX4)
973 compress = COMPRESSION_PACKBITS;
975 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
976 i_push_error(0, "write TIFF: setting rows per strip tag");
980 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
983 if (!set_palette(tif, im, 256))
986 out_size = TIFFScanlineSize(tif);
987 out_row = (unsigned char *)_TIFFmalloc( out_size );
989 for (y = 0; y < im->ysize; ++y) {
990 i_gpal(im, 0, im->xsize, y, out_row);
991 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
993 i_push_error(0, "write TIFF: write scan line failed");
1004 write_one_paletted4(TIFF *tif, i_img *im) {
1005 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1006 unsigned char *in_row;
1007 unsigned char *out_row;
1011 mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
1013 /* ignore a silly choice */
1014 if (compress == COMPRESSION_JPEG ||
1015 compress == COMPRESSION_CCITTRLE ||
1016 compress == COMPRESSION_CCITTFAX3 ||
1017 compress == COMPRESSION_CCITTFAX4)
1018 compress = COMPRESSION_PACKBITS;
1020 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 4, 1))
1023 if (!set_palette(tif, im, 16))
1026 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1027 i_push_error(0, "write TIFF: setting rows per strip tag");
1031 in_row = mymalloc(im->xsize);
1032 out_size = TIFFScanlineSize(tif);
1033 out_row = (unsigned char *)_TIFFmalloc( out_size );
1035 for (y = 0; y < im->ysize; ++y) {
1036 i_gpal(im, 0, im->xsize, y, in_row);
1037 memset(out_row, 0, out_size);
1038 pack_4bit_to(out_row, in_row, im->xsize);
1039 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1041 i_push_error(0, "write TIFF: write scan line failed");
1053 set_direct_tags(TIFF *tif, i_img *im, uint16 compress,
1054 uint16 bits_per_sample) {
1055 uint16 extras = EXTRASAMPLE_ASSOCALPHA;
1056 uint16 extra_count = im->channels == 2 || im->channels == 4;
1057 uint16 photometric = im->channels >= 3 ?
1058 PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
1060 if (!set_base_tags(tif, im, compress, photometric, bits_per_sample,
1066 if (!TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extra_count, &extras)) {
1067 i_push_error(0, "write TIFF: setting extra samples tag");
1072 if (compress == COMPRESSION_JPEG) {
1074 if (i_tags_get_int(&im->tags, "tiff_jpegquality", 0, &jpeg_quality)
1075 && jpeg_quality >= 0 && jpeg_quality <= 100) {
1076 if (!TIFFSetField(tif, TIFFTAG_JPEGQUALITY, jpeg_quality)) {
1077 i_push_error(0, "write TIFF: setting jpeg quality pseudo-tag");
1087 write_one_32(TIFF *tif, i_img *im) {
1088 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1093 size_t sample_count = im->xsize * im->channels;
1094 size_t sample_index;
1096 mm_log((1, "tiff - write_one_32(tif %p, im %p)\n", tif, im));
1098 /* only 8 and 12 bit samples are supported by jpeg compression */
1099 if (compress == COMPRESSION_JPEG)
1100 compress = COMPRESSION_PACKBITS;
1102 if (!set_direct_tags(tif, im, compress, 32))
1105 in_row = mymalloc(sample_count * sizeof(unsigned));
1106 out_size = TIFFScanlineSize(tif);
1107 out_row = (uint32 *)_TIFFmalloc( out_size );
1109 for (y = 0; y < im->ysize; ++y) {
1110 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 32) <= 0) {
1111 i_push_error(0, "Cannot read 32-bit samples");
1114 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1115 out_row[sample_index] = in_row[sample_index];
1116 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1119 i_push_error(0, "write TIFF: write scan line failed");
1131 write_one_16(TIFF *tif, i_img *im) {
1132 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1137 size_t sample_count = im->xsize * im->channels;
1138 size_t sample_index;
1140 mm_log((1, "tiff - write_one_16(tif %p, im %p)\n", tif, im));
1142 /* only 8 and 12 bit samples are supported by jpeg compression */
1143 if (compress == COMPRESSION_JPEG)
1144 compress = COMPRESSION_PACKBITS;
1146 if (!set_direct_tags(tif, im, compress, 16))
1149 in_row = mymalloc(sample_count * sizeof(unsigned));
1150 out_size = TIFFScanlineSize(tif);
1151 out_row = (uint16 *)_TIFFmalloc( out_size );
1153 for (y = 0; y < im->ysize; ++y) {
1154 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 16) <= 0) {
1155 i_push_error(0, "Cannot read 16-bit samples");
1158 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1159 out_row[sample_index] = in_row[sample_index];
1160 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1163 i_push_error(0, "write TIFF: write scan line failed");
1175 write_one_8(TIFF *tif, i_img *im) {
1176 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1178 unsigned char *out_row;
1180 size_t sample_count = im->xsize * im->channels;
1182 mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
1184 if (!set_direct_tags(tif, im, compress, 8))
1187 out_size = TIFFScanlineSize(tif);
1188 if (out_size < sample_count)
1189 out_size = sample_count;
1190 out_row = (unsigned char *)_TIFFmalloc( out_size );
1192 for (y = 0; y < im->ysize; ++y) {
1193 if (i_gsamp(im, 0, im->xsize, y, out_row, NULL, im->channels) <= 0) {
1194 i_push_error(0, "Cannot read 8-bit samples");
1197 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1199 i_push_error(0, "write TIFF: write scan line failed");
1209 i_writetiff_low(TIFF *tif, i_img *im) {
1210 uint32 width, height;
1216 channels = im->channels;
1218 if (width != im->xsize || height != im->ysize) {
1219 i_push_error(0, "image too large for TIFF");
1223 mm_log((1, "i_writetiff_low: width=%d, height=%d, channels=%d, bits=%d\n", width, height, channels, im->bits));
1224 if (im->type == i_palette_type) {
1225 mm_log((1, "i_writetiff_low: paletted, colors=%d\n", i_colorcount(im)));
1228 if (i_img_is_monochrome(im, &zero_is_white)) {
1229 if (!write_one_bilevel(tif, im, zero_is_white))
1232 else if (im->type == i_palette_type) {
1233 if (i_colorcount(im) <= 16) {
1234 if (!write_one_paletted4(tif, im))
1238 if (!write_one_paletted8(tif, im))
1242 else if (im->bits > 16) {
1243 if (!write_one_32(tif, im))
1246 else if (im->bits > 8) {
1247 if (!write_one_16(tif, im))
1251 if (!write_one_8(tif, im))
1255 if (!save_tiff_tags(tif, im))
1262 =item i_writetiff_multi_wiol(ig, imgs, count, fine_mode)
1264 Stores an image in the iolayer object.
1266 ig - io_object that defines source to write to
1267 imgs,count - the images to write
1273 i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1275 TIFFErrorHandler old_handler;
1278 old_handler = TIFFSetErrorHandler(error_handler);
1281 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
1284 /* FIXME: Enable the mmap interface */
1286 tif = TIFFClientOpen("No name",
1289 (TIFFReadWriteProc) ig->readcb,
1290 (TIFFReadWriteProc) ig->writecb,
1291 (TIFFSeekProc) comp_seek,
1292 (TIFFCloseProc) ig->closecb,
1293 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1294 (TIFFMapFileProc) comp_mmap,
1295 (TIFFUnmapFileProc) comp_munmap);
1300 mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n"));
1301 i_push_error(0, "Could not create TIFF object");
1302 TIFFSetErrorHandler(old_handler);
1306 for (i = 0; i < count; ++i) {
1307 if (!i_writetiff_low(tif, imgs[i])) {
1309 TIFFSetErrorHandler(old_handler);
1313 if (!TIFFWriteDirectory(tif)) {
1314 i_push_error(0, "Cannot write TIFF directory");
1316 TIFFSetErrorHandler(old_handler);
1321 TIFFSetErrorHandler(old_handler);
1322 (void) TIFFClose(tif);
1328 =item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1330 Stores an image in the iolayer object.
1332 ig - io_object that defines source to write to
1333 imgs,count - the images to write
1334 fine_mode - select fine or normal mode fax images
1341 i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1344 TIFFErrorHandler old_handler;
1346 old_handler = TIFFSetErrorHandler(error_handler);
1349 mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n",
1352 /* FIXME: Enable the mmap interface */
1354 tif = TIFFClientOpen("No name",
1357 (TIFFReadWriteProc) ig->readcb,
1358 (TIFFReadWriteProc) ig->writecb,
1359 (TIFFSeekProc) comp_seek,
1360 (TIFFCloseProc) ig->closecb,
1361 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1362 (TIFFMapFileProc) comp_mmap,
1363 (TIFFUnmapFileProc) comp_munmap);
1368 mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
1369 i_push_error(0, "Could not create TIFF object");
1370 TIFFSetErrorHandler(old_handler);
1374 for (i = 0; i < count; ++i) {
1375 if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1377 TIFFSetErrorHandler(old_handler);
1381 if (!TIFFWriteDirectory(tif)) {
1382 i_push_error(0, "Cannot write TIFF directory");
1384 TIFFSetErrorHandler(old_handler);
1389 (void) TIFFClose(tif);
1390 TIFFSetErrorHandler(old_handler);
1396 =item i_writetiff_wiol(im, ig)
1398 Stores an image in the iolayer object.
1400 im - image object to write out
1401 ig - io_object that defines source to write to
1406 i_writetiff_wiol(i_img *img, io_glue *ig) {
1408 TIFFErrorHandler old_handler;
1410 old_handler = TIFFSetErrorHandler(error_handler);
1413 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", img, ig));
1415 /* FIXME: Enable the mmap interface */
1417 tif = TIFFClientOpen("No name",
1420 (TIFFReadWriteProc) ig->readcb,
1421 (TIFFReadWriteProc) ig->writecb,
1422 (TIFFSeekProc) comp_seek,
1423 (TIFFCloseProc) ig->closecb,
1424 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1425 (TIFFMapFileProc) comp_mmap,
1426 (TIFFUnmapFileProc) comp_munmap);
1431 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1432 i_push_error(0, "Could not create TIFF object");
1433 TIFFSetErrorHandler(old_handler);
1437 if (!i_writetiff_low(tif, img)) {
1439 TIFFSetErrorHandler(old_handler);
1443 (void) TIFFClose(tif);
1444 TIFFSetErrorHandler(old_handler);
1452 =item i_writetiff_wiol_faxable(i_img *, io_glue *)
1454 Stores an image in the iolayer object in faxable tiff format.
1456 im - image object to write out
1457 ig - io_object that defines source to write to
1459 Note, this may be rewritten to use to simply be a call to a
1460 lower-level function that gives more options for writing tiff at some
1467 i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1469 TIFFErrorHandler old_handler;
1471 old_handler = TIFFSetErrorHandler(error_handler);
1474 mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", im, ig));
1476 /* FIXME: Enable the mmap interface */
1478 tif = TIFFClientOpen("No name",
1481 (TIFFReadWriteProc) ig->readcb,
1482 (TIFFReadWriteProc) ig->writecb,
1483 (TIFFSeekProc) comp_seek,
1484 (TIFFCloseProc) ig->closecb,
1485 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1486 (TIFFMapFileProc) comp_mmap,
1487 (TIFFUnmapFileProc) comp_munmap);
1492 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1493 i_push_error(0, "Could not create TIFF object");
1494 TIFFSetErrorHandler(old_handler);
1498 if (!i_writetiff_low_faxable(tif, im, fine)) {
1500 TIFFSetErrorHandler(old_handler);
1504 (void) TIFFClose(tif);
1505 TIFFSetErrorHandler(old_handler);
1510 static int save_tiff_tags(TIFF *tif, i_img *im) {
1513 for (i = 0; i < text_tag_count; ++i) {
1515 if (i_tags_find(&im->tags, text_tag_names[i].name, 0, &entry)) {
1516 if (!TIFFSetField(tif, text_tag_names[i].tag,
1517 im->tags.tags[entry].data)) {
1518 i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1529 unpack_4bit_to(unsigned char *dest, const unsigned char *src,
1530 size_t src_byte_count) {
1531 while (src_byte_count > 0) {
1532 *dest++ = *src >> 4;
1533 *dest++ = *src++ & 0xf;
1538 static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
1539 i_img_dim pixel_count) {
1541 while (i < pixel_count) {
1543 *dest = *src++ << 4;
1553 make_rgb(TIFF *tif, i_img_dim width, i_img_dim height, int *alpha_chan) {
1555 uint16 channels, in_channels;
1559 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1560 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1562 switch (photometric) {
1563 case PHOTOMETRIC_SEPARATED:
1567 case PHOTOMETRIC_MINISWHITE:
1568 case PHOTOMETRIC_MINISBLACK:
1569 /* the TIFF RGBA functions expand single channel grey into RGB,
1570 so reduce it, we move the alpha channel into the right place
1579 /* TIFF images can have more than one alpha channel, but Imager can't
1580 this ignores the possibility of 2 channel images with 2 alpha,
1581 but there's not much I can do about that */
1583 if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)
1585 *alpha_chan = channels++;
1588 return i_img_8_new(width, height, channels);
1592 read_one_rgb_lines(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
1594 uint32* raster = NULL;
1595 uint32 rowsperstrip, row;
1600 im = make_rgb(tif, width, height, &alpha_chan);
1604 rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1605 mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
1607 if (rc != 1 || rowsperstrip==-1) {
1608 rowsperstrip = height;
1611 raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
1614 i_push_error(0, "No space for raster buffer");
1618 line_buf = mymalloc(sizeof(i_color) * width);
1620 for( row = 0; row < height; row += rowsperstrip ) {
1621 uint32 newrows, i_row;
1623 if (!TIFFReadRGBAStrip(tif, row, raster)) {
1624 if (allow_incomplete) {
1625 i_tags_setn(&im->tags, "i_lines_read", row);
1626 i_tags_setn(&im->tags, "i_incomplete", 1);
1630 i_push_error(0, "could not read TIFF image strip");
1637 newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
1638 mm_log((1, "newrows=%d\n", newrows));
1640 for( i_row = 0; i_row < newrows; i_row++ ) {
1642 i_color *outp = line_buf;
1644 for(x = 0; x<width; x++) {
1645 uint32 temp = raster[x+width*(newrows-i_row-1)];
1646 outp->rgba.r = TIFFGetR(temp);
1647 outp->rgba.g = TIFFGetG(temp);
1648 outp->rgba.b = TIFFGetB(temp);
1651 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1652 alpha in the right place and scale it */
1654 outp->channel[alpha_chan] = TIFFGetA(temp);
1655 if (outp->channel[alpha_chan]) {
1656 for (ch = 0; ch < alpha_chan; ++ch) {
1657 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1664 i_plin(im, 0, width, i_row+row, line_buf);
1674 /* adapted from libtiff
1676 libtiff's TIFFReadRGBATile succeeds even when asked to read an
1677 invalid tile, which means we have no way of knowing whether the data
1678 we received from it is valid or not.
1680 So the caller here has set stoponerror to 1 so that
1681 TIFFRGBAImageGet() will fail.
1683 read_one_rgb_tiled() then takes that into account for i_incomplete
1687 myTIFFReadRGBATile(TIFFRGBAImage *img, uint32 col, uint32 row, uint32 * raster)
1691 uint32 tile_xsize, tile_ysize;
1692 uint32 read_xsize, read_ysize;
1696 * Verify that our request is legal - on a tile file, and on a
1700 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILEWIDTH, &tile_xsize);
1701 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILELENGTH, &tile_ysize);
1702 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
1704 i_push_errorf(0, "Row/col passed to myTIFFReadRGBATile() must be top"
1705 "left corner of a tile.");
1710 * The TIFFRGBAImageGet() function doesn't allow us to get off the
1711 * edge of the image, even to fill an otherwise valid tile. So we
1712 * figure out how much we can read, and fix up the tile buffer to
1713 * a full tile configuration afterwards.
1716 if( row + tile_ysize > img->height )
1717 read_ysize = img->height - row;
1719 read_ysize = tile_ysize;
1721 if( col + tile_xsize > img->width )
1722 read_xsize = img->width - col;
1724 read_xsize = tile_xsize;
1727 * Read the chunk of imagery.
1730 img->row_offset = row;
1731 img->col_offset = col;
1733 ok = TIFFRGBAImageGet(img, raster, read_xsize, read_ysize );
1736 * If our read was incomplete we will need to fix up the tile by
1737 * shifting the data around as if a full tile of data is being returned.
1739 * This is all the more complicated because the image is organized in
1740 * bottom to top format.
1743 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
1746 for( i_row = 0; i_row < read_ysize; i_row++ ) {
1747 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
1748 raster + (read_ysize - i_row - 1) * read_xsize,
1749 read_xsize * sizeof(uint32) );
1750 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
1751 0, sizeof(uint32) * (tile_xsize - read_xsize) );
1754 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
1755 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
1756 0, sizeof(uint32) * tile_xsize );
1763 read_one_rgb_tiled(TIFF *tif, i_img_dim width, i_img_dim height, int allow_incomplete) {
1765 uint32* raster = NULL;
1768 uint32 tile_width, tile_height;
1769 unsigned long pixels = 0;
1770 char emsg[1024] = "";
1775 im = make_rgb(tif, width, height, &alpha_chan);
1779 if (!TIFFRGBAImageOK(tif, emsg)
1780 || !TIFFRGBAImageBegin(&img, tif, 1, emsg)) {
1781 i_push_error(0, emsg);
1786 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
1787 TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
1788 mm_log((1, "i_readtiff_wiol: tile_width=%d, tile_height=%d\n", tile_width, tile_height));
1790 raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
1793 i_push_error(0, "No space for raster buffer");
1794 TIFFRGBAImageEnd(&img);
1797 line = mymalloc(tile_width * sizeof(i_color));
1799 for( row = 0; row < height; row += tile_height ) {
1800 for( col = 0; col < width; col += tile_width ) {
1802 /* Read the tile into an RGBA array */
1803 if (myTIFFReadRGBATile(&img, col, row, raster)) {
1805 uint32 newrows = (row+tile_height > height) ? height-row : tile_height;
1806 uint32 newcols = (col+tile_width > width ) ? width-col : tile_width;
1808 mm_log((1, "i_readtiff_wiol: tile(%d, %d) newcols=%d newrows=%d\n", col, row, newcols, newrows));
1809 for( i_row = 0; i_row < newrows; i_row++ ) {
1810 i_color *outp = line;
1811 for(x = 0; x < newcols; x++) {
1812 uint32 temp = raster[x+tile_width*(tile_height-i_row-1)];
1813 outp->rgba.r = TIFFGetR(temp);
1814 outp->rgba.g = TIFFGetG(temp);
1815 outp->rgba.b = TIFFGetB(temp);
1816 outp->rgba.a = TIFFGetA(temp);
1819 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1820 alpha in the right place and scale it */
1822 outp->channel[alpha_chan] = TIFFGetA(temp);
1824 if (outp->channel[alpha_chan]) {
1825 for (ch = 0; ch < alpha_chan; ++ch) {
1826 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1833 i_plin(im, col, col+newcols, row+i_row, line);
1835 pixels += newrows * newcols;
1838 if (allow_incomplete) {
1850 i_push_error(0, "TIFF: No image data could be read from the image");
1854 /* incomplete image */
1855 i_tags_setn(&im->tags, "i_incomplete", 1);
1856 i_tags_setn(&im->tags, "i_lines_read", pixels / width);
1860 TIFFRGBAImageEnd(&img);
1868 TIFFRGBAImageEnd(&img);
1874 i_tiff_libversion(void) {
1875 return TIFFGetVersion();
1879 setup_paletted(read_state_t *state) {
1882 int color_count = 1 << state->bits_per_sample;
1884 state->img = i_img_pal_new(state->width, state->height, 3, 256);
1888 /* setup the color map */
1889 if (!TIFFGetField(state->tif, TIFFTAG_COLORMAP, maps+0, maps+1, maps+2)) {
1890 i_push_error(0, "Cannot get colormap for paletted image");
1891 i_img_destroy(state->img);
1894 for (i = 0; i < color_count; ++i) {
1896 for (ch = 0; ch < 3; ++ch) {
1897 c.channel[ch] = Sample16To8(maps[ch][i]);
1899 i_addcolors(state->img, &c, 1);
1906 tile_contig_getter(read_state_t *state, read_putter_t putter) {
1907 uint32 tile_width, tile_height;
1908 uint32 this_tile_height, this_tile_width;
1909 uint32 rows_left, cols_left;
1912 state->raster = _TIFFmalloc(TIFFTileSize(state->tif));
1913 if (!state->raster) {
1914 i_push_error(0, "tiff: Out of memory allocating tile buffer");
1918 TIFFGetField(state->tif, TIFFTAG_TILEWIDTH, &tile_width);
1919 TIFFGetField(state->tif, TIFFTAG_TILELENGTH, &tile_height);
1920 rows_left = state->height;
1921 for (y = 0; y < state->height; y += this_tile_height) {
1922 this_tile_height = rows_left > tile_height ? tile_height : rows_left;
1924 cols_left = state->width;
1925 for (x = 0; x < state->width; x += this_tile_width) {
1926 this_tile_width = cols_left > tile_width ? tile_width : cols_left;
1928 if (TIFFReadTile(state->tif,
1931 if (!state->allow_incomplete) {
1936 putter(state, x, y, this_tile_width, this_tile_height, tile_width - this_tile_width);
1939 cols_left -= this_tile_width;
1942 rows_left -= this_tile_height;
1949 strip_contig_getter(read_state_t *state, read_putter_t putter) {
1950 uint32 rows_per_strip;
1951 tsize_t strip_size = TIFFStripSize(state->tif);
1952 uint32 y, strip_rows, rows_left;
1954 state->raster = _TIFFmalloc(strip_size);
1955 if (!state->raster) {
1956 i_push_error(0, "tiff: Out of memory allocating strip buffer");
1960 TIFFGetFieldDefaulted(state->tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
1961 rows_left = state->height;
1962 for (y = 0; y < state->height; y += strip_rows) {
1963 strip_rows = rows_left > rows_per_strip ? rows_per_strip : rows_left;
1964 if (TIFFReadEncodedStrip(state->tif,
1965 TIFFComputeStrip(state->tif, y, 0),
1968 if (!state->allow_incomplete)
1972 putter(state, 0, y, state->width, strip_rows, 0);
1974 rows_left -= strip_rows;
1981 paletted_putter8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
1982 unsigned char *p = state->raster;
1984 state->pixels_read += width * height;
1985 while (height > 0) {
1986 i_ppal(state->img, x, x + width, y, p);
1987 p += width + extras;
1996 paletted_putter4(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height, int extras) {
1997 uint32 img_line_size = (width + 1) / 2;
1998 uint32 skip_line_size = (width + extras + 1) / 2;
1999 unsigned char *p = state->raster;
2001 if (!state->line_buf)
2002 state->line_buf = mymalloc(state->width);
2004 state->pixels_read += width * height;
2005 while (height > 0) {
2006 unpack_4bit_to(state->line_buf, p, img_line_size);
2007 i_ppal(state->img, x, x + width, y, state->line_buf);
2008 p += skip_line_size;
2017 rgb_channels(read_state_t *state, int *out_channels) {
2023 state->alpha_chan = 0;
2024 state->scale_alpha = 0;
2027 if (state->samples_per_pixel == 3)
2030 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2031 mm_log((1, "tiff: samples != 3 but no extra samples tag\n"));
2036 mm_log((1, "tiff: samples != 3 but no extra samples listed"));
2041 state->alpha_chan = 3;
2043 case EXTRASAMPLE_UNSPECIFIED:
2044 case EXTRASAMPLE_ASSOCALPHA:
2045 state->scale_alpha = 1;
2048 case EXTRASAMPLE_UNASSALPHA:
2049 state->scale_alpha = 0;
2053 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2055 state->scale_alpha = 1;
2058 mm_log((1, "tiff alpha channel %d scale %d\n", state->alpha_chan, state->scale_alpha));
2062 grey_channels(read_state_t *state, int *out_channels) {
2068 state->alpha_chan = 0;
2069 state->scale_alpha = 0;
2072 if (state->samples_per_pixel == 1)
2075 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2076 mm_log((1, "tiff: samples != 1 but no extra samples tag\n"));
2081 mm_log((1, "tiff: samples != 1 but no extra samples listed"));
2086 state->alpha_chan = 1;
2088 case EXTRASAMPLE_UNSPECIFIED:
2089 case EXTRASAMPLE_ASSOCALPHA:
2090 state->scale_alpha = 1;
2093 case EXTRASAMPLE_UNASSALPHA:
2094 state->scale_alpha = 0;
2098 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2100 state->scale_alpha = 1;
2106 setup_16_rgb(read_state_t *state) {
2109 rgb_channels(state, &out_channels);
2111 state->img = i_img_16_new(state->width, state->height, out_channels);
2114 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2120 setup_16_grey(read_state_t *state) {
2123 grey_channels(state, &out_channels);
2125 state->img = i_img_16_new(state->width, state->height, out_channels);
2128 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2134 putter_16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2136 uint16 *p = state->raster;
2137 int out_chan = state->img->channels;
2139 state->pixels_read += width * height;
2140 while (height > 0) {
2143 unsigned *outp = state->line_buf;
2145 for (i = 0; i < width; ++i) {
2146 for (ch = 0; ch < out_chan; ++ch) {
2149 if (state->alpha_chan && state->scale_alpha && outp[state->alpha_chan]) {
2150 for (ch = 0; ch < state->alpha_chan; ++ch) {
2151 int result = 0.5 + (outp[ch] * 65535.0 / outp[state->alpha_chan]);
2152 outp[ch] = CLAMP16(result);
2155 p += state->samples_per_pixel;
2159 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2161 p += row_extras * state->samples_per_pixel;
2170 setup_8_rgb(read_state_t *state) {
2173 rgb_channels(state, &out_channels);
2175 state->img = i_img_8_new(state->width, state->height, out_channels);
2178 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2184 setup_8_grey(read_state_t *state) {
2187 grey_channels(state, &out_channels);
2189 state->img = i_img_8_new(state->width, state->height, out_channels);
2192 state->line_buf = mymalloc(sizeof(i_color) * state->width * out_channels);
2198 putter_8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2200 unsigned char *p = state->raster;
2201 int out_chan = state->img->channels;
2203 state->pixels_read += width * height;
2204 while (height > 0) {
2207 i_color *outp = state->line_buf;
2209 for (i = 0; i < width; ++i) {
2210 for (ch = 0; ch < out_chan; ++ch) {
2211 outp->channel[ch] = p[ch];
2213 if (state->alpha_chan && state->scale_alpha
2214 && outp->channel[state->alpha_chan]) {
2215 for (ch = 0; ch < state->alpha_chan; ++ch) {
2216 int result = (outp->channel[ch] * 255 + 127) / outp->channel[state->alpha_chan];
2218 outp->channel[ch] = CLAMP8(result);
2221 p += state->samples_per_pixel;
2225 i_plin(state->img, x, x + width, y, state->line_buf);
2227 p += row_extras * state->samples_per_pixel;
2236 setup_32_rgb(read_state_t *state) {
2239 rgb_channels(state, &out_channels);
2241 state->img = i_img_double_new(state->width, state->height, out_channels);
2244 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2250 setup_32_grey(read_state_t *state) {
2253 grey_channels(state, &out_channels);
2255 state->img = i_img_double_new(state->width, state->height, out_channels);
2258 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2264 putter_32(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2266 uint32 *p = state->raster;
2267 int out_chan = state->img->channels;
2269 state->pixels_read += width * height;
2270 while (height > 0) {
2273 i_fcolor *outp = state->line_buf;
2275 for (i = 0; i < width; ++i) {
2276 for (ch = 0; ch < out_chan; ++ch) {
2277 outp->channel[ch] = p[ch] / 4294967295.0;
2279 if (state->alpha_chan && state->scale_alpha && outp->channel[state->alpha_chan]) {
2280 for (ch = 0; ch < state->alpha_chan; ++ch)
2281 outp->channel[ch] /= outp->channel[state->alpha_chan];
2283 p += state->samples_per_pixel;
2287 i_plinf(state->img, x, x + width, y, state->line_buf);
2289 p += row_extras * state->samples_per_pixel;
2298 setup_bilevel(read_state_t *state) {
2299 i_color black, white;
2300 state->img = i_img_pal_new(state->width, state->height, 1, 256);
2303 black.channel[0] = black.channel[1] = black.channel[2] =
2304 black.channel[3] = 0;
2305 white.channel[0] = white.channel[1] = white.channel[2] =
2306 white.channel[3] = 255;
2307 if (state->photometric == PHOTOMETRIC_MINISBLACK) {
2308 i_addcolors(state->img, &black, 1);
2309 i_addcolors(state->img, &white, 1);
2312 i_addcolors(state->img, &white, 1);
2313 i_addcolors(state->img, &black, 1);
2315 state->line_buf = mymalloc(state->width);
2321 putter_bilevel(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2323 unsigned char *line_in = state->raster;
2324 size_t line_size = (width + row_extras + 7) / 8;
2326 /* tifflib returns the bits in MSB2LSB order even when the file is
2327 in LSB2MSB, so we only need to handle MSB2LSB */
2328 state->pixels_read += width * height;
2329 while (height > 0) {
2331 unsigned char *outp = state->line_buf;
2332 unsigned char *inp = line_in;
2333 unsigned mask = 0x80;
2335 for (i = 0; i < width; ++i) {
2336 *outp++ = *inp & mask ? 1 : 0;
2344 i_ppal(state->img, x, x + width, y, state->line_buf);
2346 line_in += line_size;
2355 cmyk_channels(read_state_t *state, int *out_channels) {
2361 state->alpha_chan = 0;
2362 state->scale_alpha = 0;
2365 if (state->samples_per_pixel == 4)
2368 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2369 mm_log((1, "tiff: CMYK samples != 4 but no extra samples tag\n"));
2374 mm_log((1, "tiff: CMYK samples != 4 but no extra samples listed"));
2379 state->alpha_chan = 4;
2381 case EXTRASAMPLE_UNSPECIFIED:
2382 case EXTRASAMPLE_ASSOCALPHA:
2383 state->scale_alpha = 1;
2386 case EXTRASAMPLE_UNASSALPHA:
2387 state->scale_alpha = 0;
2391 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2393 state->scale_alpha = 1;
2399 setup_cmyk8(read_state_t *state) {
2402 cmyk_channels(state, &channels);
2403 state->img = i_img_8_new(state->width, state->height, channels);
2405 state->line_buf = mymalloc(sizeof(i_color) * state->width);
2411 putter_cmyk8(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2413 unsigned char *p = state->raster;
2415 state->pixels_read += width * height;
2416 while (height > 0) {
2419 i_color *outp = state->line_buf;
2421 for (i = 0; i < width; ++i) {
2422 unsigned char c, m, y, k;
2427 outp->rgba.r = (k * (255 - c)) / 255;
2428 outp->rgba.g = (k * (255 - m)) / 255;
2429 outp->rgba.b = (k * (255 - y)) / 255;
2430 if (state->alpha_chan) {
2431 outp->rgba.a = p[state->alpha_chan];
2432 if (state->scale_alpha
2434 for (ch = 0; ch < 3; ++ch) {
2435 int result = (outp->channel[ch] * 255 + 127) / outp->rgba.a;
2436 outp->channel[ch] = CLAMP8(result);
2440 p += state->samples_per_pixel;
2444 i_plin(state->img, x, x + width, y, state->line_buf);
2446 p += row_extras * state->samples_per_pixel;
2455 setup_cmyk16(read_state_t *state) {
2458 cmyk_channels(state, &channels);
2459 state->img = i_img_16_new(state->width, state->height, channels);
2461 state->line_buf = mymalloc(sizeof(unsigned) * state->width * channels);
2467 putter_cmyk16(read_state_t *state, i_img_dim x, i_img_dim y, i_img_dim width, i_img_dim height,
2469 uint16 *p = state->raster;
2470 int out_chan = state->img->channels;
2472 mm_log((4, "putter_cmyk16(%p, %d, %d, %d, %d, %d)\n", x, y, width, height, row_extras));
2474 state->pixels_read += width * height;
2475 while (height > 0) {
2478 unsigned *outp = state->line_buf;
2480 for (i = 0; i < width; ++i) {
2481 unsigned c, m, y, k;
2486 outp[0] = (k * (65535U - c)) / 65535U;
2487 outp[1] = (k * (65535U - m)) / 65535U;
2488 outp[2] = (k * (65535U - y)) / 65535U;
2489 if (state->alpha_chan) {
2490 outp[3] = p[state->alpha_chan];
2491 if (state->scale_alpha
2493 for (ch = 0; ch < 3; ++ch) {
2494 int result = (outp[ch] * 65535 + 32767) / outp[3];
2495 outp[3] = CLAMP16(result);
2499 p += state->samples_per_pixel;
2503 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2505 p += row_extras * state->samples_per_pixel;
2515 Older versions of tifflib we support don't define this, so define it
2518 If you want this detection to do anything useful, use a newer
2522 #if TIFFLIB_VERSION < 20031121
2525 TIFFIsCODECConfigured(uint16 scheme) {
2527 /* these schemes are all shipped with tifflib */
2528 case COMPRESSION_NONE:
2529 case COMPRESSION_PACKBITS:
2530 case COMPRESSION_CCITTRLE:
2531 case COMPRESSION_CCITTRLEW:
2532 case COMPRESSION_CCITTFAX3:
2533 case COMPRESSION_CCITTFAX4:
2536 /* these require external library support */
2538 case COMPRESSION_JPEG:
2539 case COMPRESSION_LZW:
2540 case COMPRESSION_DEFLATE:
2541 case COMPRESSION_ADOBE_DEFLATE:
2549 myTIFFIsCODECConfigured(uint16 scheme) {
2550 #if TIFFLIB_VERSION < 20040724
2551 if (scheme == COMPRESSION_LZW)
2555 return TIFFIsCODECConfigured(scheme);
2563 Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tonyc@cpan.org>