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, int width, int height, int allow_incomplete);
54 static i_img *read_one_rgb_lines(TIFF *tif, int width, int 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, int x, int y, int width,
104 int 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 unsigned long 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 *, int, int, int, int, int);
140 static int paletted_putter4(read_state_t *, int, int, int, int, 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 *, int, int, int, int, 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 *, int, int, int, int, 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 *, int, int, int, int, int);
154 static int setup_bilevel(read_state_t *state);
155 static int putter_bilevel(read_state_t *, int, int, int, int, int);
157 static int setup_cmyk8(read_state_t *state);
158 static int putter_cmyk8(read_state_t *, int, int, int, int, int);
160 static int setup_cmyk16(read_state_t *state);
161 static int putter_cmyk16(read_state_t *, int, int, int, int, 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, int 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 unsigned long total_pixels = (unsigned long)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 switch (im->channels) {
642 /* This means a colorspace we don't handle yet */
643 mm_log((1, "i_writetiff_wiol_faxable: don't handle %d channel images.\n", im->channels));
647 /* Add code to get the filename info from the iolayer */
648 /* Also add code to check for mmapped code */
651 mm_log((1, "i_writetiff_wiol_faxable: width=%d, height=%d, channels=%d\n", width, height, im->channels));
653 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width) )
654 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField width=%d failed\n", width)); return 0; }
655 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height) )
656 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField length=%d failed\n", height)); return 0; }
657 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1))
658 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField samplesperpixel=1 failed\n")); return 0; }
659 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT))
660 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Orientation=topleft\n")); return 0; }
661 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1) )
662 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField bitpersample=1\n")); return 0; }
663 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG))
664 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField planarconfig\n")); return 0; }
665 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
666 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField photometric=%d\n", PHOTOMETRIC_MINISBLACK)); return 0; }
667 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, 3))
668 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField compression=3\n")); return 0; }
670 linebuf = (unsigned char *)_TIFFmalloc( TIFFScanlineSize(tif) );
672 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
673 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField rowsperstrip=-1\n")); return 0; }
675 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
676 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rc);
678 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField rowsperstrip=%d\n", rowsperstrip));
679 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField scanlinesize=%d\n", TIFFScanlineSize(tif) ));
680 mm_log((1, "i_writetiff_wiol_faxable: TIFFGetField planarconfig=%d == %d\n", rc, PLANARCONFIG_CONTIG));
682 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)204))
683 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Xresolution=204\n")); return 0; }
684 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, vres))
685 { mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField Yresolution=196\n")); return 0; }
686 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)) {
687 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField ResolutionUnit=%d\n", RESUNIT_INCH)); return 0;
690 if (!save_tiff_tags(tif, im)) {
694 for (y=0; y<height; y++) {
696 for(x=0; x<width; x+=8) {
701 linebuf[linebufpos]=0;
702 bits = width-x; if(bits>8) bits=8;
703 i_gsamp(im, x, x+8, y, luma, &luma_chan, 1);
704 for(bitpos=0;bitpos<bits;bitpos++) {
705 linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
710 if (TIFFWriteScanline(tif, linebuf, y, 0) < 0) {
711 mm_log((1, "i_writetiff_wiol_faxable: TIFFWriteScanline failed.\n"));
715 if (linebuf) _TIFFfree(linebuf);
721 find_compression(char const *name, uint16 *compress) {
724 for (i = 0; i < compress_value_count; ++i) {
725 if (strcmp(compress_values[i].name, name) == 0) {
726 *compress = (uint16)compress_values[i].tag;
730 *compress = COMPRESSION_NONE;
736 get_compression(i_img *im, uint16 def_compress) {
740 if (i_tags_find(&im->tags, "tiff_compression", 0, &entry)
741 && im->tags.tags[entry].data) {
743 if (find_compression(im->tags.tags[entry].data, &compress)
744 && myTIFFIsCODECConfigured(compress))
747 if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
748 if ((uint16)value == value
749 && myTIFFIsCODECConfigured((uint16)value))
750 return (uint16)value;
757 i_tiff_has_compression(const char *name) {
760 if (!find_compression(name, &compress))
763 return myTIFFIsCODECConfigured(compress);
767 set_base_tags(TIFF *tif, i_img *im, uint16 compress, uint16 photometric,
768 uint16 bits_per_sample, uint16 samples_per_pixel) {
771 int got_xres, got_yres;
774 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->xsize)) {
775 i_push_error(0, "write TIFF: setting width tag");
778 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
779 i_push_error(0, "write TIFF: setting length tag");
782 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
783 i_push_error(0, "write TIFF: setting orientation tag");
786 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
787 i_push_error(0, "write TIFF: setting planar configuration tag");
790 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
791 i_push_error(0, "write TIFF: setting photometric tag");
794 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
795 i_push_error(0, "write TIFF: setting compression tag");
798 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
799 i_push_error(0, "write TIFF: setting bits per sample tag");
802 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
803 i_push_error(0, "write TIFF: setting samples per pixel tag");
807 got_xres = i_tags_get_float(&im->tags, "i_xres", 0, &xres);
808 got_yres = i_tags_get_float(&im->tags, "i_yres", 0, &yres);
809 if (!i_tags_get_int(&im->tags, "i_aspect_only", 0,&aspect_only))
811 if (!i_tags_get_int(&im->tags, "tiff_resolutionunit", 0, &resunit))
812 resunit = RESUNIT_INCH;
813 if (got_xres || got_yres) {
819 resunit = RESUNIT_NONE;
822 if (resunit == RESUNIT_CENTIMETER) {
827 resunit = RESUNIT_INCH;
830 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xres)) {
831 i_push_error(0, "write TIFF: setting xresolution tag");
834 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
835 i_push_error(0, "write TIFF: setting yresolution tag");
838 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
839 i_push_error(0, "write TIFF: setting resolutionunit tag");
848 write_one_bilevel(TIFF *tif, i_img *im, int zero_is_white) {
849 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
851 unsigned char *in_row;
852 unsigned char *out_row;
857 mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n",
858 tif, im, zero_is_white));
860 /* ignore a silly choice */
861 if (compress == COMPRESSION_JPEG)
862 compress = COMPRESSION_PACKBITS;
865 case COMPRESSION_CCITTRLE:
866 case COMPRESSION_CCITTFAX3:
867 case COMPRESSION_CCITTFAX4:
868 /* natural fax photometric */
869 photometric = PHOTOMETRIC_MINISWHITE;
873 /* natural for most computer images */
874 photometric = PHOTOMETRIC_MINISBLACK;
878 if (!set_base_tags(tif, im, compress, photometric, 1, 1))
881 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
882 i_push_error(0, "write TIFF: setting rows per strip tag");
886 out_size = TIFFScanlineSize(tif);
887 out_row = (unsigned char *)_TIFFmalloc( out_size );
888 in_row = mymalloc(im->xsize);
890 invert = (photometric == PHOTOMETRIC_MINISWHITE) != (zero_is_white != 0);
892 for (y = 0; y < im->ysize; ++y) {
894 unsigned char *outp = out_row;
895 memset(out_row, 0, out_size);
896 i_gpal(im, 0, im->xsize, y, in_row);
897 for (x = 0; x < im->xsize; ++x) {
898 if (invert ? !in_row[x] : in_row[x]) {
907 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
910 i_push_error(0, "write TIFF: write scan line failed");
922 set_palette(TIFF *tif, i_img *im, int size) {
929 colors = (uint16 *)_TIFFmalloc(sizeof(uint16) * 3 * size);
931 out[1] = colors + size;
932 out[2] = colors + 2 * size;
934 count = i_colorcount(im);
935 for (i = 0; i < count; ++i) {
936 i_getcolors(im, i, &c, 1);
937 for (ch = 0; ch < 3; ++ch)
938 out[ch][i] = c.channel[ch] * 257;
940 for (; i < size; ++i) {
941 for (ch = 0; ch < 3; ++ch)
944 if (!TIFFSetField(tif, TIFFTAG_COLORMAP, out[0], out[1], out[2])) {
946 i_push_error(0, "write TIFF: setting color map");
955 write_one_paletted8(TIFF *tif, i_img *im) {
956 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
957 unsigned char *out_row;
961 mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
963 /* ignore a silly choice */
964 if (compress == COMPRESSION_JPEG ||
965 compress == COMPRESSION_CCITTRLE ||
966 compress == COMPRESSION_CCITTFAX3 ||
967 compress == COMPRESSION_CCITTFAX4)
968 compress = COMPRESSION_PACKBITS;
970 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
971 i_push_error(0, "write TIFF: setting rows per strip tag");
975 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
978 if (!set_palette(tif, im, 256))
981 out_size = TIFFScanlineSize(tif);
982 out_row = (unsigned char *)_TIFFmalloc( out_size );
984 for (y = 0; y < im->ysize; ++y) {
985 i_gpal(im, 0, im->xsize, y, out_row);
986 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
988 i_push_error(0, "write TIFF: write scan line failed");
999 write_one_paletted4(TIFF *tif, i_img *im) {
1000 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1001 unsigned char *in_row;
1002 unsigned char *out_row;
1006 mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
1008 /* ignore a silly choice */
1009 if (compress == COMPRESSION_JPEG ||
1010 compress == COMPRESSION_CCITTRLE ||
1011 compress == COMPRESSION_CCITTFAX3 ||
1012 compress == COMPRESSION_CCITTFAX4)
1013 compress = COMPRESSION_PACKBITS;
1015 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 4, 1))
1018 if (!set_palette(tif, im, 16))
1021 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1022 i_push_error(0, "write TIFF: setting rows per strip tag");
1026 in_row = mymalloc(im->xsize);
1027 out_size = TIFFScanlineSize(tif);
1028 out_row = (unsigned char *)_TIFFmalloc( out_size );
1030 for (y = 0; y < im->ysize; ++y) {
1031 i_gpal(im, 0, im->xsize, y, in_row);
1032 memset(out_row, 0, out_size);
1033 pack_4bit_to(out_row, in_row, im->xsize);
1034 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1036 i_push_error(0, "write TIFF: write scan line failed");
1048 set_direct_tags(TIFF *tif, i_img *im, uint16 compress,
1049 uint16 bits_per_sample) {
1050 uint16 extras = EXTRASAMPLE_ASSOCALPHA;
1051 uint16 extra_count = im->channels == 2 || im->channels == 4;
1052 uint16 photometric = im->channels >= 3 ?
1053 PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
1055 if (!set_base_tags(tif, im, compress, photometric, bits_per_sample,
1061 if (!TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extra_count, &extras)) {
1062 i_push_error(0, "write TIFF: setting extra samples tag");
1067 if (compress == COMPRESSION_JPEG) {
1069 if (i_tags_get_int(&im->tags, "tiff_jpegquality", 0, &jpeg_quality)
1070 && jpeg_quality >= 0 && jpeg_quality <= 100) {
1071 if (!TIFFSetField(tif, TIFFTAG_JPEGQUALITY, jpeg_quality)) {
1072 i_push_error(0, "write TIFF: setting jpeg quality pseudo-tag");
1082 write_one_32(TIFF *tif, i_img *im) {
1083 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1088 size_t sample_count = im->xsize * im->channels;
1089 size_t sample_index;
1091 mm_log((1, "tiff - write_one_32(tif %p, im %p)\n", tif, im));
1093 /* only 8 and 12 bit samples are supported by jpeg compression */
1094 if (compress == COMPRESSION_JPEG)
1095 compress = COMPRESSION_PACKBITS;
1097 if (!set_direct_tags(tif, im, compress, 32))
1100 in_row = mymalloc(sample_count * sizeof(unsigned));
1101 out_size = TIFFScanlineSize(tif);
1102 out_row = (uint32 *)_TIFFmalloc( out_size );
1104 for (y = 0; y < im->ysize; ++y) {
1105 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 32) <= 0) {
1106 i_push_error(0, "Cannot read 32-bit samples");
1109 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1110 out_row[sample_index] = in_row[sample_index];
1111 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1114 i_push_error(0, "write TIFF: write scan line failed");
1126 write_one_16(TIFF *tif, i_img *im) {
1127 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1132 size_t sample_count = im->xsize * im->channels;
1133 size_t sample_index;
1135 mm_log((1, "tiff - write_one_16(tif %p, im %p)\n", tif, im));
1137 /* only 8 and 12 bit samples are supported by jpeg compression */
1138 if (compress == COMPRESSION_JPEG)
1139 compress = COMPRESSION_PACKBITS;
1141 if (!set_direct_tags(tif, im, compress, 16))
1144 in_row = mymalloc(sample_count * sizeof(unsigned));
1145 out_size = TIFFScanlineSize(tif);
1146 out_row = (uint16 *)_TIFFmalloc( out_size );
1148 for (y = 0; y < im->ysize; ++y) {
1149 if (i_gsamp_bits(im, 0, im->xsize, y, in_row, NULL, im->channels, 16) <= 0) {
1150 i_push_error(0, "Cannot read 16-bit samples");
1153 for (sample_index = 0; sample_index < sample_count; ++sample_index)
1154 out_row[sample_index] = in_row[sample_index];
1155 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1158 i_push_error(0, "write TIFF: write scan line failed");
1170 write_one_8(TIFF *tif, i_img *im) {
1171 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1173 unsigned char *out_row;
1175 size_t sample_count = im->xsize * im->channels;
1177 mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
1179 if (!set_direct_tags(tif, im, compress, 8))
1182 out_size = TIFFScanlineSize(tif);
1183 if (out_size < sample_count)
1184 out_size = sample_count;
1185 out_row = (unsigned char *)_TIFFmalloc( out_size );
1187 for (y = 0; y < im->ysize; ++y) {
1188 if (i_gsamp(im, 0, im->xsize, y, out_row, NULL, im->channels) <= 0) {
1189 i_push_error(0, "Cannot read 8-bit samples");
1192 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1194 i_push_error(0, "write TIFF: write scan line failed");
1204 i_writetiff_low(TIFF *tif, i_img *im) {
1205 uint32 width, height;
1211 channels = im->channels;
1213 mm_log((1, "i_writetiff_low: width=%d, height=%d, channels=%d, bits=%d\n", width, height, channels, im->bits));
1214 if (im->type == i_palette_type) {
1215 mm_log((1, "i_writetiff_low: paletted, colors=%d\n", i_colorcount(im)));
1218 if (i_img_is_monochrome(im, &zero_is_white)) {
1219 if (!write_one_bilevel(tif, im, zero_is_white))
1222 else if (im->type == i_palette_type) {
1223 if (i_colorcount(im) <= 16) {
1224 if (!write_one_paletted4(tif, im))
1228 if (!write_one_paletted8(tif, im))
1232 else if (im->bits > 16) {
1233 if (!write_one_32(tif, im))
1236 else if (im->bits > 8) {
1237 if (!write_one_16(tif, im))
1241 if (!write_one_8(tif, im))
1245 if (!save_tiff_tags(tif, im))
1252 =item i_writetiff_multi_wiol(ig, imgs, count, fine_mode)
1254 Stores an image in the iolayer object.
1256 ig - io_object that defines source to write to
1257 imgs,count - the images to write
1263 i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1265 TIFFErrorHandler old_handler;
1268 old_handler = TIFFSetErrorHandler(error_handler);
1271 mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
1274 /* FIXME: Enable the mmap interface */
1276 tif = TIFFClientOpen("No name",
1279 (TIFFReadWriteProc) ig->readcb,
1280 (TIFFReadWriteProc) ig->writecb,
1281 (TIFFSeekProc) comp_seek,
1282 (TIFFCloseProc) ig->closecb,
1283 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1284 (TIFFMapFileProc) comp_mmap,
1285 (TIFFUnmapFileProc) comp_munmap);
1290 mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n"));
1291 i_push_error(0, "Could not create TIFF object");
1292 TIFFSetErrorHandler(old_handler);
1296 for (i = 0; i < count; ++i) {
1297 if (!i_writetiff_low(tif, imgs[i])) {
1299 TIFFSetErrorHandler(old_handler);
1303 if (!TIFFWriteDirectory(tif)) {
1304 i_push_error(0, "Cannot write TIFF directory");
1306 TIFFSetErrorHandler(old_handler);
1311 TIFFSetErrorHandler(old_handler);
1312 (void) TIFFClose(tif);
1318 =item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1320 Stores an image in the iolayer object.
1322 ig - io_object that defines source to write to
1323 imgs,count - the images to write
1324 fine_mode - select fine or normal mode fax images
1331 i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1334 TIFFErrorHandler old_handler;
1336 old_handler = TIFFSetErrorHandler(error_handler);
1339 mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
1342 /* FIXME: Enable the mmap interface */
1344 tif = TIFFClientOpen("No name",
1347 (TIFFReadWriteProc) ig->readcb,
1348 (TIFFReadWriteProc) ig->writecb,
1349 (TIFFSeekProc) comp_seek,
1350 (TIFFCloseProc) ig->closecb,
1351 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1352 (TIFFMapFileProc) comp_mmap,
1353 (TIFFUnmapFileProc) comp_munmap);
1358 mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
1359 i_push_error(0, "Could not create TIFF object");
1360 TIFFSetErrorHandler(old_handler);
1364 for (i = 0; i < count; ++i) {
1365 if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1367 TIFFSetErrorHandler(old_handler);
1371 if (!TIFFWriteDirectory(tif)) {
1372 i_push_error(0, "Cannot write TIFF directory");
1374 TIFFSetErrorHandler(old_handler);
1379 (void) TIFFClose(tif);
1380 TIFFSetErrorHandler(old_handler);
1386 =item i_writetiff_wiol(im, ig)
1388 Stores an image in the iolayer object.
1390 im - image object to write out
1391 ig - io_object that defines source to write to
1396 i_writetiff_wiol(i_img *img, io_glue *ig) {
1398 TIFFErrorHandler old_handler;
1400 old_handler = TIFFSetErrorHandler(error_handler);
1403 mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", img, ig));
1405 /* FIXME: Enable the mmap interface */
1407 tif = TIFFClientOpen("No name",
1410 (TIFFReadWriteProc) ig->readcb,
1411 (TIFFReadWriteProc) ig->writecb,
1412 (TIFFSeekProc) comp_seek,
1413 (TIFFCloseProc) ig->closecb,
1414 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1415 (TIFFMapFileProc) comp_mmap,
1416 (TIFFUnmapFileProc) comp_munmap);
1421 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1422 i_push_error(0, "Could not create TIFF object");
1423 TIFFSetErrorHandler(old_handler);
1427 if (!i_writetiff_low(tif, img)) {
1429 TIFFSetErrorHandler(old_handler);
1433 (void) TIFFClose(tif);
1434 TIFFSetErrorHandler(old_handler);
1442 =item i_writetiff_wiol_faxable(i_img *, io_glue *)
1444 Stores an image in the iolayer object in faxable tiff format.
1446 im - image object to write out
1447 ig - io_object that defines source to write to
1449 Note, this may be rewritten to use to simply be a call to a
1450 lower-level function that gives more options for writing tiff at some
1457 i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1459 TIFFErrorHandler old_handler;
1461 old_handler = TIFFSetErrorHandler(error_handler);
1464 mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", im, ig));
1466 /* FIXME: Enable the mmap interface */
1468 tif = TIFFClientOpen("No name",
1471 (TIFFReadWriteProc) ig->readcb,
1472 (TIFFReadWriteProc) ig->writecb,
1473 (TIFFSeekProc) comp_seek,
1474 (TIFFCloseProc) ig->closecb,
1475 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1476 (TIFFMapFileProc) comp_mmap,
1477 (TIFFUnmapFileProc) comp_munmap);
1482 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
1483 i_push_error(0, "Could not create TIFF object");
1484 TIFFSetErrorHandler(old_handler);
1488 if (!i_writetiff_low_faxable(tif, im, fine)) {
1490 TIFFSetErrorHandler(old_handler);
1494 (void) TIFFClose(tif);
1495 TIFFSetErrorHandler(old_handler);
1500 static int save_tiff_tags(TIFF *tif, i_img *im) {
1503 for (i = 0; i < text_tag_count; ++i) {
1505 if (i_tags_find(&im->tags, text_tag_names[i].name, 0, &entry)) {
1506 if (!TIFFSetField(tif, text_tag_names[i].tag,
1507 im->tags.tags[entry].data)) {
1508 i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1519 unpack_4bit_to(unsigned char *dest, const unsigned char *src,
1520 int src_byte_count) {
1521 while (src_byte_count > 0) {
1522 *dest++ = *src >> 4;
1523 *dest++ = *src++ & 0xf;
1528 static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
1531 while (i < pixel_count) {
1533 *dest = *src++ << 4;
1543 make_rgb(TIFF *tif, int width, int height, int *alpha_chan) {
1545 uint16 channels, in_channels;
1549 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1550 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1552 switch (photometric) {
1553 case PHOTOMETRIC_SEPARATED:
1557 case PHOTOMETRIC_MINISWHITE:
1558 case PHOTOMETRIC_MINISBLACK:
1559 /* the TIFF RGBA functions expand single channel grey into RGB,
1560 so reduce it, we move the alpha channel into the right place
1569 /* TIFF images can have more than one alpha channel, but Imager can't
1570 this ignores the possibility of 2 channel images with 2 alpha,
1571 but there's not much I can do about that */
1573 if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)
1575 *alpha_chan = channels++;
1578 return i_img_8_new(width, height, channels);
1582 read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete) {
1584 uint32* raster = NULL;
1585 uint32 rowsperstrip, row;
1590 im = make_rgb(tif, width, height, &alpha_chan);
1594 rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1595 mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
1597 if (rc != 1 || rowsperstrip==-1) {
1598 rowsperstrip = height;
1601 raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
1604 i_push_error(0, "No space for raster buffer");
1608 line_buf = mymalloc(sizeof(i_color) * width);
1610 for( row = 0; row < height; row += rowsperstrip ) {
1611 uint32 newrows, i_row;
1613 if (!TIFFReadRGBAStrip(tif, row, raster)) {
1614 if (allow_incomplete) {
1615 i_tags_setn(&im->tags, "i_lines_read", row);
1616 i_tags_setn(&im->tags, "i_incomplete", 1);
1620 i_push_error(0, "could not read TIFF image strip");
1627 newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
1628 mm_log((1, "newrows=%d\n", newrows));
1630 for( i_row = 0; i_row < newrows; i_row++ ) {
1632 i_color *outp = line_buf;
1634 for(x = 0; x<width; x++) {
1635 uint32 temp = raster[x+width*(newrows-i_row-1)];
1636 outp->rgba.r = TIFFGetR(temp);
1637 outp->rgba.g = TIFFGetG(temp);
1638 outp->rgba.b = TIFFGetB(temp);
1641 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1642 alpha in the right place and scale it */
1644 outp->channel[alpha_chan] = TIFFGetA(temp);
1645 if (outp->channel[alpha_chan]) {
1646 for (ch = 0; ch < alpha_chan; ++ch) {
1647 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1654 i_plin(im, 0, width, i_row+row, line_buf);
1664 /* adapted from libtiff
1666 libtiff's TIFFReadRGBATile succeeds even when asked to read an
1667 invalid tile, which means we have no way of knowing whether the data
1668 we received from it is valid or not.
1670 So the caller here has set stoponerror to 1 so that
1671 TIFFRGBAImageGet() will fail.
1673 read_one_rgb_tiled() then takes that into account for i_incomplete
1677 myTIFFReadRGBATile(TIFFRGBAImage *img, uint32 col, uint32 row, uint32 * raster)
1681 uint32 tile_xsize, tile_ysize;
1682 uint32 read_xsize, read_ysize;
1686 * Verify that our request is legal - on a tile file, and on a
1690 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILEWIDTH, &tile_xsize);
1691 TIFFGetFieldDefaulted(img->tif, TIFFTAG_TILELENGTH, &tile_ysize);
1692 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
1694 i_push_errorf(0, "Row/col passed to myTIFFReadRGBATile() must be top"
1695 "left corner of a tile.");
1700 * The TIFFRGBAImageGet() function doesn't allow us to get off the
1701 * edge of the image, even to fill an otherwise valid tile. So we
1702 * figure out how much we can read, and fix up the tile buffer to
1703 * a full tile configuration afterwards.
1706 if( row + tile_ysize > img->height )
1707 read_ysize = img->height - row;
1709 read_ysize = tile_ysize;
1711 if( col + tile_xsize > img->width )
1712 read_xsize = img->width - col;
1714 read_xsize = tile_xsize;
1717 * Read the chunk of imagery.
1720 img->row_offset = row;
1721 img->col_offset = col;
1723 ok = TIFFRGBAImageGet(img, raster, read_xsize, read_ysize );
1726 * If our read was incomplete we will need to fix up the tile by
1727 * shifting the data around as if a full tile of data is being returned.
1729 * This is all the more complicated because the image is organized in
1730 * bottom to top format.
1733 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
1736 for( i_row = 0; i_row < read_ysize; i_row++ ) {
1737 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
1738 raster + (read_ysize - i_row - 1) * read_xsize,
1739 read_xsize * sizeof(uint32) );
1740 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
1741 0, sizeof(uint32) * (tile_xsize - read_xsize) );
1744 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
1745 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
1746 0, sizeof(uint32) * tile_xsize );
1753 read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete) {
1755 uint32* raster = NULL;
1758 uint32 tile_width, tile_height;
1759 unsigned long pixels = 0;
1760 char emsg[1024] = "";
1765 im = make_rgb(tif, width, height, &alpha_chan);
1769 if (!TIFFRGBAImageOK(tif, emsg)
1770 || !TIFFRGBAImageBegin(&img, tif, 1, emsg)) {
1771 i_push_error(0, emsg);
1776 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width);
1777 TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height);
1778 mm_log((1, "i_readtiff_wiol: tile_width=%d, tile_height=%d\n", tile_width, tile_height));
1780 raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
1783 i_push_error(0, "No space for raster buffer");
1784 TIFFRGBAImageEnd(&img);
1787 line = mymalloc(tile_width * sizeof(i_color));
1789 for( row = 0; row < height; row += tile_height ) {
1790 for( col = 0; col < width; col += tile_width ) {
1792 /* Read the tile into an RGBA array */
1793 if (myTIFFReadRGBATile(&img, col, row, raster)) {
1795 uint32 newrows = (row+tile_height > height) ? height-row : tile_height;
1796 uint32 newcols = (col+tile_width > width ) ? width-col : tile_width;
1798 mm_log((1, "i_readtiff_wiol: tile(%d, %d) newcols=%d newrows=%d\n", col, row, newcols, newrows));
1799 for( i_row = 0; i_row < newrows; i_row++ ) {
1800 i_color *outp = line;
1801 for(x = 0; x < newcols; x++) {
1802 uint32 temp = raster[x+tile_width*(tile_height-i_row-1)];
1803 outp->rgba.r = TIFFGetR(temp);
1804 outp->rgba.g = TIFFGetG(temp);
1805 outp->rgba.b = TIFFGetB(temp);
1806 outp->rgba.a = TIFFGetA(temp);
1809 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1810 alpha in the right place and scale it */
1812 outp->channel[alpha_chan] = TIFFGetA(temp);
1814 if (outp->channel[alpha_chan]) {
1815 for (ch = 0; ch < alpha_chan; ++ch) {
1816 outp->channel[ch] = outp->channel[ch] * 255 / outp->channel[alpha_chan];
1823 i_plin(im, col, col+newcols, row+i_row, line);
1825 pixels += newrows * newcols;
1828 if (allow_incomplete) {
1840 i_push_error(0, "TIFF: No image data could be read from the image");
1844 /* incomplete image */
1845 i_tags_setn(&im->tags, "i_incomplete", 1);
1846 i_tags_setn(&im->tags, "i_lines_read", pixels / width);
1850 TIFFRGBAImageEnd(&img);
1858 TIFFRGBAImageEnd(&img);
1864 i_tiff_libversion(void) {
1865 return TIFFGetVersion();
1869 setup_paletted(read_state_t *state) {
1872 int color_count = 1 << state->bits_per_sample;
1874 state->img = i_img_pal_new(state->width, state->height, 3, 256);
1878 /* setup the color map */
1879 if (!TIFFGetField(state->tif, TIFFTAG_COLORMAP, maps+0, maps+1, maps+2)) {
1880 i_push_error(0, "Cannot get colormap for paletted image");
1881 i_img_destroy(state->img);
1884 for (i = 0; i < color_count; ++i) {
1886 for (ch = 0; ch < 3; ++ch) {
1887 c.channel[ch] = Sample16To8(maps[ch][i]);
1889 i_addcolors(state->img, &c, 1);
1896 tile_contig_getter(read_state_t *state, read_putter_t putter) {
1897 uint32 tile_width, tile_height;
1898 uint32 this_tile_height, this_tile_width;
1899 uint32 rows_left, cols_left;
1902 state->raster = _TIFFmalloc(TIFFTileSize(state->tif));
1903 if (!state->raster) {
1904 i_push_error(0, "tiff: Out of memory allocating tile buffer");
1908 TIFFGetField(state->tif, TIFFTAG_TILEWIDTH, &tile_width);
1909 TIFFGetField(state->tif, TIFFTAG_TILELENGTH, &tile_height);
1910 rows_left = state->height;
1911 for (y = 0; y < state->height; y += this_tile_height) {
1912 this_tile_height = rows_left > tile_height ? tile_height : rows_left;
1914 cols_left = state->width;
1915 for (x = 0; x < state->width; x += this_tile_width) {
1916 this_tile_width = cols_left > tile_width ? tile_width : cols_left;
1918 if (TIFFReadTile(state->tif,
1921 if (!state->allow_incomplete) {
1926 putter(state, x, y, this_tile_width, this_tile_height, tile_width - this_tile_width);
1929 cols_left -= this_tile_width;
1932 rows_left -= this_tile_height;
1939 strip_contig_getter(read_state_t *state, read_putter_t putter) {
1940 uint32 rows_per_strip;
1941 tsize_t strip_size = TIFFStripSize(state->tif);
1942 uint32 y, strip_rows, rows_left;
1944 state->raster = _TIFFmalloc(strip_size);
1945 if (!state->raster) {
1946 i_push_error(0, "tiff: Out of memory allocating strip buffer");
1950 TIFFGetFieldDefaulted(state->tif, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
1951 rows_left = state->height;
1952 for (y = 0; y < state->height; y += strip_rows) {
1953 strip_rows = rows_left > rows_per_strip ? rows_per_strip : rows_left;
1954 if (TIFFReadEncodedStrip(state->tif,
1955 TIFFComputeStrip(state->tif, y, 0),
1958 if (!state->allow_incomplete)
1962 putter(state, 0, y, state->width, strip_rows, 0);
1964 rows_left -= strip_rows;
1971 paletted_putter8(read_state_t *state, int x, int y, int width, int height, int extras) {
1972 unsigned char *p = state->raster;
1974 state->pixels_read += (unsigned long) width * height;
1975 while (height > 0) {
1976 i_ppal(state->img, x, x + width, y, p);
1977 p += width + extras;
1986 paletted_putter4(read_state_t *state, int x, int y, int width, int height, int extras) {
1987 uint32 img_line_size = (width + 1) / 2;
1988 uint32 skip_line_size = (width + extras + 1) / 2;
1989 unsigned char *p = state->raster;
1991 if (!state->line_buf)
1992 state->line_buf = mymalloc(state->width);
1994 state->pixels_read += (unsigned long) width * height;
1995 while (height > 0) {
1996 unpack_4bit_to(state->line_buf, p, img_line_size);
1997 i_ppal(state->img, x, x + width, y, state->line_buf);
1998 p += skip_line_size;
2007 rgb_channels(read_state_t *state, int *out_channels) {
2013 state->alpha_chan = 0;
2014 state->scale_alpha = 0;
2017 if (state->samples_per_pixel == 3)
2020 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2021 mm_log((1, "tiff: samples != 3 but no extra samples tag\n"));
2026 mm_log((1, "tiff: samples != 3 but no extra samples listed"));
2031 state->alpha_chan = 3;
2033 case EXTRASAMPLE_UNSPECIFIED:
2034 case EXTRASAMPLE_ASSOCALPHA:
2035 state->scale_alpha = 1;
2038 case EXTRASAMPLE_UNASSALPHA:
2039 state->scale_alpha = 0;
2043 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2045 state->scale_alpha = 1;
2048 mm_log((1, "tiff alpha channel %d scale %d\n", state->alpha_chan, state->scale_alpha));
2052 grey_channels(read_state_t *state, int *out_channels) {
2058 state->alpha_chan = 0;
2059 state->scale_alpha = 0;
2062 if (state->samples_per_pixel == 1)
2065 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2066 mm_log((1, "tiff: samples != 1 but no extra samples tag\n"));
2071 mm_log((1, "tiff: samples != 1 but no extra samples listed"));
2076 state->alpha_chan = 1;
2078 case EXTRASAMPLE_UNSPECIFIED:
2079 case EXTRASAMPLE_ASSOCALPHA:
2080 state->scale_alpha = 1;
2083 case EXTRASAMPLE_UNASSALPHA:
2084 state->scale_alpha = 0;
2088 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2090 state->scale_alpha = 1;
2096 setup_16_rgb(read_state_t *state) {
2099 rgb_channels(state, &out_channels);
2101 state->img = i_img_16_new(state->width, state->height, out_channels);
2104 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2110 setup_16_grey(read_state_t *state) {
2113 grey_channels(state, &out_channels);
2115 state->img = i_img_16_new(state->width, state->height, out_channels);
2118 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2124 putter_16(read_state_t *state, int x, int y, int width, int height,
2126 uint16 *p = state->raster;
2127 int out_chan = state->img->channels;
2129 state->pixels_read += (unsigned long) width * height;
2130 while (height > 0) {
2133 unsigned *outp = state->line_buf;
2135 for (i = 0; i < width; ++i) {
2136 for (ch = 0; ch < out_chan; ++ch) {
2139 if (state->alpha_chan && state->scale_alpha && outp[state->alpha_chan]) {
2140 for (ch = 0; ch < state->alpha_chan; ++ch) {
2141 int result = 0.5 + (outp[ch] * 65535.0 / outp[state->alpha_chan]);
2142 outp[ch] = CLAMP16(result);
2145 p += state->samples_per_pixel;
2149 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2151 p += row_extras * state->samples_per_pixel;
2160 setup_8_rgb(read_state_t *state) {
2163 rgb_channels(state, &out_channels);
2165 state->img = i_img_8_new(state->width, state->height, out_channels);
2168 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2174 setup_8_grey(read_state_t *state) {
2177 grey_channels(state, &out_channels);
2179 state->img = i_img_8_new(state->width, state->height, out_channels);
2182 state->line_buf = mymalloc(sizeof(i_color) * state->width * out_channels);
2188 putter_8(read_state_t *state, int x, int y, int width, int height,
2190 unsigned char *p = state->raster;
2191 int out_chan = state->img->channels;
2193 state->pixels_read += (unsigned long) width * height;
2194 while (height > 0) {
2197 i_color *outp = state->line_buf;
2199 for (i = 0; i < width; ++i) {
2200 for (ch = 0; ch < out_chan; ++ch) {
2201 outp->channel[ch] = p[ch];
2203 if (state->alpha_chan && state->scale_alpha
2204 && outp->channel[state->alpha_chan]) {
2205 for (ch = 0; ch < state->alpha_chan; ++ch) {
2206 int result = (outp->channel[ch] * 255 + 127) / outp->channel[state->alpha_chan];
2208 outp->channel[ch] = CLAMP8(result);
2211 p += state->samples_per_pixel;
2215 i_plin(state->img, x, x + width, y, state->line_buf);
2217 p += row_extras * state->samples_per_pixel;
2226 setup_32_rgb(read_state_t *state) {
2229 rgb_channels(state, &out_channels);
2231 state->img = i_img_double_new(state->width, state->height, out_channels);
2234 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2240 setup_32_grey(read_state_t *state) {
2243 grey_channels(state, &out_channels);
2245 state->img = i_img_double_new(state->width, state->height, out_channels);
2248 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2254 putter_32(read_state_t *state, int x, int y, int width, int height,
2256 uint32 *p = state->raster;
2257 int out_chan = state->img->channels;
2259 state->pixels_read += (unsigned long) width * height;
2260 while (height > 0) {
2263 i_fcolor *outp = state->line_buf;
2265 for (i = 0; i < width; ++i) {
2266 for (ch = 0; ch < out_chan; ++ch) {
2267 outp->channel[ch] = p[ch] / 4294967295.0;
2269 if (state->alpha_chan && state->scale_alpha && outp->channel[state->alpha_chan]) {
2270 for (ch = 0; ch < state->alpha_chan; ++ch)
2271 outp->channel[ch] /= outp->channel[state->alpha_chan];
2273 p += state->samples_per_pixel;
2277 i_plinf(state->img, x, x + width, y, state->line_buf);
2279 p += row_extras * state->samples_per_pixel;
2288 setup_bilevel(read_state_t *state) {
2289 i_color black, white;
2290 state->img = i_img_pal_new(state->width, state->height, 1, 256);
2293 black.channel[0] = black.channel[1] = black.channel[2] =
2294 black.channel[3] = 0;
2295 white.channel[0] = white.channel[1] = white.channel[2] =
2296 white.channel[3] = 255;
2297 if (state->photometric == PHOTOMETRIC_MINISBLACK) {
2298 i_addcolors(state->img, &black, 1);
2299 i_addcolors(state->img, &white, 1);
2302 i_addcolors(state->img, &white, 1);
2303 i_addcolors(state->img, &black, 1);
2305 state->line_buf = mymalloc(state->width);
2311 putter_bilevel(read_state_t *state, int x, int y, int width, int height,
2313 unsigned char *line_in = state->raster;
2314 size_t line_size = (width + row_extras + 7) / 8;
2316 /* tifflib returns the bits in MSB2LSB order even when the file is
2317 in LSB2MSB, so we only need to handle MSB2LSB */
2318 state->pixels_read += (unsigned long) width * height;
2319 while (height > 0) {
2321 unsigned char *outp = state->line_buf;
2322 unsigned char *inp = line_in;
2323 unsigned mask = 0x80;
2325 for (i = 0; i < width; ++i) {
2326 *outp++ = *inp & mask ? 1 : 0;
2334 i_ppal(state->img, x, x + width, y, state->line_buf);
2336 line_in += line_size;
2345 cmyk_channels(read_state_t *state, int *out_channels) {
2351 state->alpha_chan = 0;
2352 state->scale_alpha = 0;
2355 if (state->samples_per_pixel == 4)
2358 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2359 mm_log((1, "tiff: CMYK samples != 4 but no extra samples tag\n"));
2364 mm_log((1, "tiff: CMYK samples != 4 but no extra samples listed"));
2369 state->alpha_chan = 4;
2371 case EXTRASAMPLE_UNSPECIFIED:
2372 case EXTRASAMPLE_ASSOCALPHA:
2373 state->scale_alpha = 1;
2376 case EXTRASAMPLE_UNASSALPHA:
2377 state->scale_alpha = 0;
2381 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2383 state->scale_alpha = 1;
2389 setup_cmyk8(read_state_t *state) {
2392 cmyk_channels(state, &channels);
2393 state->img = i_img_8_new(state->width, state->height, channels);
2395 state->line_buf = mymalloc(sizeof(i_color) * state->width);
2401 putter_cmyk8(read_state_t *state, int x, int y, int width, int height,
2403 unsigned char *p = state->raster;
2405 state->pixels_read += (unsigned long) width * height;
2406 while (height > 0) {
2409 i_color *outp = state->line_buf;
2411 for (i = 0; i < width; ++i) {
2412 unsigned char c, m, y, k;
2417 outp->rgba.r = (k * (255 - c)) / 255;
2418 outp->rgba.g = (k * (255 - m)) / 255;
2419 outp->rgba.b = (k * (255 - y)) / 255;
2420 if (state->alpha_chan) {
2421 outp->rgba.a = p[state->alpha_chan];
2422 if (state->scale_alpha
2424 for (ch = 0; ch < 3; ++ch) {
2425 int result = (outp->channel[ch] * 255 + 127) / outp->rgba.a;
2426 outp->channel[ch] = CLAMP8(result);
2430 p += state->samples_per_pixel;
2434 i_plin(state->img, x, x + width, y, state->line_buf);
2436 p += row_extras * state->samples_per_pixel;
2445 setup_cmyk16(read_state_t *state) {
2448 cmyk_channels(state, &channels);
2449 state->img = i_img_16_new(state->width, state->height, channels);
2451 state->line_buf = mymalloc(sizeof(unsigned) * state->width * channels);
2457 putter_cmyk16(read_state_t *state, int x, int y, int width, int height,
2459 uint16 *p = state->raster;
2460 int out_chan = state->img->channels;
2462 mm_log((4, "putter_cmyk16(%p, %d, %d, %d, %d, %d)\n", x, y, width, height, row_extras));
2464 state->pixels_read += (unsigned long) width * height;
2465 while (height > 0) {
2468 unsigned *outp = state->line_buf;
2470 for (i = 0; i < width; ++i) {
2471 unsigned c, m, y, k;
2476 outp[0] = (k * (65535U - c)) / 65535U;
2477 outp[1] = (k * (65535U - m)) / 65535U;
2478 outp[2] = (k * (65535U - y)) / 65535U;
2479 if (state->alpha_chan) {
2480 outp[3] = p[state->alpha_chan];
2481 if (state->scale_alpha
2483 for (ch = 0; ch < 3; ++ch) {
2484 int result = (outp[ch] * 65535 + 32767) / outp[3];
2485 outp[3] = CLAMP16(result);
2489 p += state->samples_per_pixel;
2493 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2495 p += row_extras * state->samples_per_pixel;
2505 Older versions of tifflib we support don't define this, so define it
2508 If you want this detection to do anything useful, use a newer
2512 #if TIFFLIB_VERSION < 20031121
2515 TIFFIsCODECConfigured(uint16 scheme) {
2517 /* these schemes are all shipped with tifflib */
2518 case COMPRESSION_NONE:
2519 case COMPRESSION_PACKBITS:
2520 case COMPRESSION_CCITTRLE:
2521 case COMPRESSION_CCITTRLEW:
2522 case COMPRESSION_CCITTFAX3:
2523 case COMPRESSION_CCITTFAX4:
2526 /* these require external library support */
2528 case COMPRESSION_JPEG:
2529 case COMPRESSION_LZW:
2530 case COMPRESSION_DEFLATE:
2531 case COMPRESSION_ADOBE_DEFLATE:
2539 myTIFFIsCODECConfigured(uint16 scheme) {
2540 #if TIFFLIB_VERSION < 20040724
2541 if (scheme == COMPRESSION_LZW)
2545 return TIFFIsCODECConfigured(scheme);
2553 Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tony@imager.perl.org>