]> git.imager.perl.org - imager.git/blame - TIFF/imtiff.c
use DEFINE from Imager::Probe
[imager.git] / TIFF / imtiff.c
CommitLineData
bd8052a6 1#include <tiffio.h>
e5ee047b
TC
2#include <string.h>
3#include "imtiff.h"
4#include "imext.h"
5c829fcf 5
bd8052a6
TC
6/* needed to implement our substitute TIFFIsCODECConfigured */
7#if TIFFLIB_VERSION < 20031121
bd8052a6
TC
8static int TIFFIsCODECConfigured(uint16 scheme);
9#endif
10
02d1d628
AMH
11/*
12=head1 NAME
13
14tiff.c - implements reading and writing tiff files, uses io layer.
15
16=head1 SYNOPSIS
17
18 io_glue *ig = io_new_fd( fd );
19 i_img *im = i_readtiff_wiol(ig, -1); // no limit on how much is read
20 // or
21 io_glue *ig = io_new_fd( fd );
22 return_code = i_writetiff_wiol(im, ig);
23
24=head1 DESCRIPTION
25
26tiff.c implements the basic functions to read and write tiff files.
27It uses the iolayer and needs either a seekable source or an entire
28memory mapped buffer.
29
30=head1 FUNCTION REFERENCE
31
32Some of these functions are internal.
33
b8c2033e 34=over
02d1d628
AMH
35
36=cut
37*/
38
5c829fcf
AMH
39#define byteswap_macro(x) \
40 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
41 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
42
bd8052a6
TC
43#define CLAMP8(x) ((x) < 0 ? 0 : (x) > 255 ? 255 : (x))
44#define CLAMP16(x) ((x) < 0 ? 0 : (x) > 65535 ? 65535 : (x))
45
e5ee047b
TC
46#define Sample16To8(num) ((num) / 257)
47
fd9a31d2
TC
48struct tag_name {
49 char *name;
50 uint32 tag;
51};
52
bd8052a6
TC
53static i_img *read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete);
54static i_img *read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete);
55
fd9a31d2
TC
56static struct tag_name text_tag_names[] =
57{
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, },
67};
68
bd8052a6
TC
69static struct tag_name
70compress_values[] =
71 {
72 { "none", COMPRESSION_NONE },
73 { "ccittrle", COMPRESSION_CCITTRLE },
74 { "fax3", COMPRESSION_CCITTFAX3 },
b57dd0e4 75 { "t4", COMPRESSION_CCITTFAX3 },
bd8052a6 76 { "fax4", COMPRESSION_CCITTFAX4 },
b57dd0e4 77 { "t6", COMPRESSION_CCITTFAX4 },
bd8052a6
TC
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 },
85 };
86
87static const int compress_value_count =
88 sizeof(compress_values) / sizeof(*compress_values);
89
f8d72f20
TC
90static int
91myTIFFIsCODECConfigured(uint16 scheme);
92
bd8052a6
TC
93typedef struct read_state_tag read_state_t;
94/* the setup function creates the image object, allocates the line buffer */
95typedef int (*read_setup_t)(read_state_t *state);
96
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
101 image) */
102
103typedef int (*read_putter_t)(read_state_t *state, int x, int y, int width,
104 int height, int extras);
105
106/* reads from a tiled or strip image and calls the putter.
107 This may need a second type for handling non-contiguous images
108 at some point */
109typedef int (*read_getter_t)(read_state_t *state, read_putter_t putter);
110
111struct read_state_tag {
112 TIFF *tif;
113 i_img *img;
114 void *raster;
115 unsigned long pixels_read;
116 int allow_incomplete;
117 void *line_buf;
118 uint32 width, height;
119 uint16 bits_per_sample;
120 uint16 photometric;
121
122 /* the total number of channels (samples per pixel) */
123 int samples_per_pixel;
124
125 /* if non-zero, which channel is the alpha channel, typically 3 for rgb */
126 int alpha_chan;
127
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 */
132 int scale_alpha;
133};
134
135static int tile_contig_getter(read_state_t *state, read_putter_t putter);
136static int strip_contig_getter(read_state_t *state, read_putter_t putter);
137
138static int setup_paletted(read_state_t *state);
139static int paletted_putter8(read_state_t *, int, int, int, int, int);
140static int paletted_putter4(read_state_t *, int, int, int, int, int);
141
142static int setup_16_rgb(read_state_t *state);
143static int setup_16_grey(read_state_t *state);
144static int putter_16(read_state_t *, int, int, int, int, int);
145
146static int setup_8_rgb(read_state_t *state);
147static int setup_8_grey(read_state_t *state);
148static int putter_8(read_state_t *, int, int, int, int, int);
149
150static int setup_32_rgb(read_state_t *state);
151static int setup_32_grey(read_state_t *state);
152static int putter_32(read_state_t *, int, int, int, int, int);
153
154static int setup_bilevel(read_state_t *state);
155static int putter_bilevel(read_state_t *, int, int, int, int, int);
156
157static int setup_cmyk8(read_state_t *state);
158static int putter_cmyk8(read_state_t *, int, int, int, int, int);
159
160static int setup_cmyk16(read_state_t *state);
161static int putter_cmyk16(read_state_t *, int, int, int, int, int);
162
fd9a31d2
TC
163static const int text_tag_count =
164 sizeof(text_tag_names) / sizeof(*text_tag_names);
5c829fcf 165
5bb828f1 166static void error_handler(char const *module, char const *fmt, va_list ap) {
bd8052a6 167 mm_log((1, "tiff error fmt %s\n", fmt));
5bb828f1
TC
168 i_push_errorvf(0, fmt, ap);
169}
170
ffeb4a67
TC
171#define WARN_BUFFER_LIMIT 10000
172static char *warn_buffer = NULL;
173static int warn_buffer_size = 0;
174
be371490 175static void warn_handler(char const *module, char const *fmt, va_list ap) {
ffeb4a67
TC
176 char buf[1000];
177
178 buf[0] = '\0';
179#ifdef HAVE_SNPRINTF
180 vsnprintf(buf, sizeof(buf), fmt, ap);
181#else
182 vsprintf(buf, fmt, ap);
183#endif
bd8052a6
TC
184 mm_log((1, "tiff warning %s\n", buf));
185
ffeb4a67
TC
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;
191 }
192 warn_buffer = myrealloc(warn_buffer, new_size);
193 if (!old_buffer) *warn_buffer = '\0';
194 warn_buffer_size = new_size;
195 }
196 if (strlen(warn_buffer)+strlen(buf)+2 <= warn_buffer_size) {
197 strcat(warn_buffer, buf);
198 strcat(warn_buffer, "\n");
199 }
be371490
TC
200}
201
5bb828f1
TC
202static int save_tiff_tags(TIFF *tif, i_img *im);
203
bd8052a6
TC
204static void
205pack_4bit_to(unsigned char *dest, const unsigned char *src, int count);
f62b2d84 206
caa833d5
AMH
207
208static toff_t sizeproc(thandle_t x) {
209 return 0;
210}
211
212
02d1d628
AMH
213/*
214=item comp_seek(h, o, w)
215
216Compatability for 64 bit systems like latest freebsd (internal)
217
218 h - tiff handle, cast an io_glue object
219 o - offset
220 w - whence
221
222=cut
223*/
224
225static
226toff_t
227comp_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);
230}
231
e18f39b3
TC
232/*
233=item comp_mmap(thandle_t, tdata_t*, toff_t*)
234
235Dummy mmap stub.
236
237This shouldn't ever be called but newer tifflibs want it anyway.
238
239=cut
240*/
241
242static
243int
244comp_mmap(thandle_t h, tdata_t*p, toff_t*off) {
245 return -1;
246}
247
248/*
249=item comp_munmap(thandle_t h, tdata_t p, toff_t off)
250
251Dummy munmap stub.
252
253This shouldn't ever be called but newer tifflibs want it anyway.
254
255=cut
256*/
257
258static void
259comp_munmap(thandle_t h, tdata_t p, toff_t off) {
260 /* do nothing */
261}
262
d87dc9a4 263static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
02d1d628
AMH
264 i_img *im;
265 uint32 width, height;
bd8052a6 266 uint16 samples_per_pixel;
02d1d628 267 int tiled, error;
faa9b3e7
TC
268 float xres, yres;
269 uint16 resunit;
270 int gotXres, gotYres;
fd9a31d2 271 uint16 photometric;
5bb828f1 272 uint16 bits_per_sample;
bd8052a6
TC
273 uint16 planar_config;
274 uint16 inkset;
275 uint16 compress;
fd9a31d2 276 int i;
bd8052a6
TC
277 read_state_t state;
278 read_setup_t setupf = NULL;
279 read_getter_t getterf = NULL;
280 read_putter_t putterf = NULL;
02d1d628
AMH
281
282 error = 0;
283
02d1d628
AMH
284 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
285 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
bd8052a6 286 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
02d1d628 287 tiled = TIFFIsTiled(tif);
5bb828f1
TC
288 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
289 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
bd8052a6
TC
290 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
291 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
02d1d628 292
bd8052a6 293 mm_log((1, "i_readtiff_wiol: width=%d, height=%d, channels=%d\n", width, height, samples_per_pixel));
02d1d628
AMH
294 mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
295 mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
faa9b3e7 296
bd8052a6
TC
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;
304 else
305 mm_log((1, "unsupported paletted bits_per_sample %d\n", bits_per_sample));
a50608d2 306 }
bd8052a6
TC
307 else if (bits_per_sample == 16
308 && photometric == PHOTOMETRIC_RGB
309 && samples_per_pixel >= 3) {
310 setupf = setup_16_rgb;
311 putterf = putter_16;
312 }
313 else if (bits_per_sample == 16
314 && photometric == PHOTOMETRIC_MINISBLACK) {
315 setupf = setup_16_grey;
316 putterf = putter_16;
317 }
318 else if (bits_per_sample == 8
319 && photometric == PHOTOMETRIC_MINISBLACK) {
320 setupf = setup_8_grey;
321 putterf = putter_8;
322 }
323 else if (bits_per_sample == 8
324 && photometric == PHOTOMETRIC_RGB) {
325 setupf = setup_8_rgb;
326 putterf = putter_8;
327 }
328 else if (bits_per_sample == 32
329 && photometric == PHOTOMETRIC_RGB
330 && samples_per_pixel >= 3) {
331 setupf = setup_32_rgb;
332 putterf = putter_32;
333 }
334 else if (bits_per_sample == 32
335 && photometric == PHOTOMETRIC_MINISBLACK) {
336 setupf = setup_32_grey;
337 putterf = putter_32;
338 }
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;
345 }
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;
352 }
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;
359 }
360 if (tiled) {
361 if (planar_config == PLANARCONFIG_CONTIG)
362 getterf = tile_contig_getter;
363 }
364 else {
365 if (planar_config == PLANARCONFIG_CONTIG)
366 getterf = strip_contig_getter;
367 }
368 if (setupf && getterf && putterf) {
369 unsigned long total_pixels = (unsigned long)width * height;
370 memset(&state, 0, sizeof(state));
371 state.tif = tif;
372 state.allow_incomplete = allow_incomplete;
373 state.width = width;
374 state.height = height;
375 state.bits_per_sample = bits_per_sample;
376 state.samples_per_pixel = samples_per_pixel;
377 state.photometric = photometric;
378
379 if (!setupf(&state))
380 return NULL;
381 if (!getterf(&state, putterf) || !state.pixels_read) {
382 if (state.img)
383 i_img_destroy(state.img);
384 if (state.raster)
385 _TIFFfree(state.raster);
386 if (state.line_buf)
387 myfree(state.line_buf);
388
389 return NULL;
390 }
a50608d2 391
bd8052a6
TC
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);
396 }
397 im = state.img;
398
399 if (state.raster)
400 _TIFFfree(state.raster);
401 if (state.line_buf)
402 myfree(state.line_buf);
5bb828f1
TC
403 }
404 else {
bd8052a6
TC
405 if (tiled) {
406 im = read_one_rgb_tiled(tif, width, height, allow_incomplete);
407 }
408 else {
409 im = read_one_rgb_lines(tif, width, height, allow_incomplete);
410 }
5bb828f1 411 }
8c3af7b3
TC
412
413 if (!im)
414 return NULL;
f00e06a0
TC
415
416 /* general metadata */
e5ee047b
TC
417 i_tags_setn(&im->tags, "tiff_bitspersample", bits_per_sample);
418 i_tags_setn(&im->tags, "tiff_photometric", photometric);
bd8052a6 419 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
5bb828f1 420
fd9a31d2 421 /* resolution tags */
5bb828f1 422 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
faa9b3e7
TC
423 gotXres = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
424 gotYres = TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
425 if (gotXres || gotYres) {
426 if (!gotXres)
427 xres = yres;
428 else if (!gotYres)
429 yres = xres;
e5ee047b 430 i_tags_setn(&im->tags, "tiff_resolutionunit", resunit);
faa9b3e7
TC
431 if (resunit == RESUNIT_CENTIMETER) {
432 /* from dots per cm to dpi */
433 xres *= 2.54;
434 yres *= 2.54;
e5ee047b 435 i_tags_set(&im->tags, "tiff_resolutionunit_name", "centimeter", -1);
faa9b3e7 436 }
3cff89e2 437 else if (resunit == RESUNIT_NONE) {
e5ee047b
TC
438 i_tags_setn(&im->tags, "i_aspect_only", 1);
439 i_tags_set(&im->tags, "tiff_resolutionunit_name", "none", -1);
3cff89e2
TC
440 }
441 else if (resunit == RESUNIT_INCH) {
e5ee047b 442 i_tags_set(&im->tags, "tiff_resolutionunit_name", "inch", -1);
3cff89e2
TC
443 }
444 else {
e5ee047b 445 i_tags_set(&im->tags, "tiff_resolutionunit_name", "unknown", -1);
3cff89e2 446 }
2e41e30b
TC
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);
faa9b3e7 452 }
fd9a31d2
TC
453
454 /* Text tags */
455 for (i = 0; i < text_tag_count; ++i) {
456 char *data;
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));
e5ee047b 460 i_tags_set(&im->tags, text_tag_names[i].name, data, -1);
fd9a31d2
TC
461 }
462 }
8c3af7b3 463
e5ee047b 464 i_tags_set(&im->tags, "i_format", "tiff", 4);
ffeb4a67 465 if (warn_buffer && *warn_buffer) {
e5ee047b 466 i_tags_set(&im->tags, "i_warning", warn_buffer, -1);
ffeb4a67
TC
467 *warn_buffer = '\0';
468 }
bd8052a6
TC
469
470 for (i = 0; i < compress_value_count; ++i) {
471 if (compress_values[i].tag == compress) {
e5ee047b 472 i_tags_set(&im->tags, "tiff_compression", compress_values[i].name, -1);
bd8052a6 473 break;
5bb828f1 474 }
5bb828f1 475 }
1b0554d1 476
10461f9a
TC
477 return im;
478}
479
480/*
481=item i_readtiff_wiol(im, ig)
482
483=cut
484*/
485i_img*
d87dc9a4 486i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
10461f9a
TC
487 TIFF* tif;
488 TIFFErrorHandler old_handler;
be371490 489 TIFFErrorHandler old_warn_handler;
10461f9a
TC
490 i_img *im;
491
492 i_clear_error();
493 old_handler = TIFFSetErrorHandler(error_handler);
be371490 494 old_warn_handler = TIFFSetWarningHandler(warn_handler);
ffeb4a67
TC
495 if (warn_buffer)
496 *warn_buffer = '\0';
10461f9a
TC
497
498 /* Add code to get the filename info from the iolayer */
499 /* Also add code to check for mmapped code */
500
d87dc9a4 501 mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
10461f9a
TC
502
503 tif = TIFFClientOpen("(Iolayer)",
504 "rm",
505 (thandle_t) ig,
506 (TIFFReadWriteProc) ig->readcb,
507 (TIFFReadWriteProc) ig->writecb,
508 (TIFFSeekProc) comp_seek,
509 (TIFFCloseProc) ig->closecb,
caa833d5 510 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
e18f39b3
TC
511 (TIFFMapFileProc) comp_mmap,
512 (TIFFUnmapFileProc) comp_munmap);
10461f9a
TC
513
514 if (!tif) {
515 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
2691d220 516 i_push_error(0, "Error opening file");
10461f9a 517 TIFFSetErrorHandler(old_handler);
be371490 518 TIFFSetWarningHandler(old_warn_handler);
10461f9a
TC
519 return NULL;
520 }
521
8f8bd9aa
TC
522 if (page != 0) {
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);
01f2d357 528 TIFFClose(tif);
8f8bd9aa
TC
529 return NULL;
530 }
531 }
532
d87dc9a4 533 im = read_one_tiff(tif, allow_incomplete);
10461f9a 534
02d1d628 535 if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
5bb828f1 536 TIFFSetErrorHandler(old_handler);
be371490 537 TIFFSetWarningHandler(old_warn_handler);
5bb828f1 538 TIFFClose(tif);
02d1d628
AMH
539 return im;
540}
541
10461f9a 542/*
e5ee047b 543=item i_readtiff_multi_wiol(ig, *count)
02d1d628 544
10461f9a 545Reads multiple images from a TIFF.
02d1d628 546
10461f9a
TC
547=cut
548*/
549i_img**
e5ee047b 550i_readtiff_multi_wiol(io_glue *ig, int *count) {
10461f9a
TC
551 TIFF* tif;
552 TIFFErrorHandler old_handler;
be371490 553 TIFFErrorHandler old_warn_handler;
10461f9a
TC
554 i_img **results = NULL;
555 int result_alloc = 0;
556 int dirnum = 0;
02d1d628 557
10461f9a
TC
558 i_clear_error();
559 old_handler = TIFFSetErrorHandler(error_handler);
be371490 560 old_warn_handler = TIFFSetWarningHandler(warn_handler);
ffeb4a67
TC
561 if (warn_buffer)
562 *warn_buffer = '\0';
02d1d628 563
10461f9a
TC
564 /* Add code to get the filename info from the iolayer */
565 /* Also add code to check for mmapped code */
02d1d628 566
e5ee047b 567 mm_log((1, "i_readtiff_wiol(ig %p, length %d)\n", ig));
10461f9a
TC
568
569 tif = TIFFClientOpen("(Iolayer)",
570 "rm",
571 (thandle_t) ig,
572 (TIFFReadWriteProc) ig->readcb,
573 (TIFFReadWriteProc) ig->writecb,
574 (TIFFSeekProc) comp_seek,
575 (TIFFCloseProc) ig->closecb,
e18f39b3
TC
576 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
577 (TIFFMapFileProc) comp_mmap,
578 (TIFFUnmapFileProc) comp_munmap);
10461f9a
TC
579
580 if (!tif) {
581 mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
2691d220 582 i_push_error(0, "Error opening file");
10461f9a 583 TIFFSetErrorHandler(old_handler);
be371490 584 TIFFSetWarningHandler(old_warn_handler);
10461f9a
TC
585 return NULL;
586 }
02d1d628 587
10461f9a
TC
588 *count = 0;
589 do {
9c106321 590 i_img *im = read_one_tiff(tif, 0);
10461f9a
TC
591 if (!im)
592 break;
593 if (++*count > result_alloc) {
594 if (result_alloc == 0) {
595 result_alloc = 5;
596 results = mymalloc(result_alloc * sizeof(i_img *));
597 }
598 else {
599 i_img **newresults;
600 result_alloc *= 2;
601 newresults = myrealloc(results, result_alloc * sizeof(i_img *));
be371490
TC
602 if (!newresults) {
603 i_img_destroy(im); /* don't leak it */
604 break;
605 }
606 results = newresults;
10461f9a
TC
607 }
608 }
609 results[*count-1] = im;
610 } while (TIFFSetDirectory(tif, ++dirnum));
611
be371490 612 TIFFSetWarningHandler(old_warn_handler);
10461f9a
TC
613 TIFFSetErrorHandler(old_handler);
614 TIFFClose(tif);
615 return results;
616}
02d1d628
AMH
617
618undef_int
10461f9a
TC
619i_writetiff_low_faxable(TIFF *tif, i_img *im, int fine) {
620 uint32 width, height;
621 unsigned char *linebuf = NULL;
622 uint32 y;
623 int rc;
624 uint32 x;
10461f9a
TC
625 uint32 rowsperstrip;
626 float vres = fine ? 196 : 98;
627 int luma_chan;
628
629 width = im->xsize;
630 height = im->ysize;
631
632 switch (im->channels) {
633 case 1:
634 case 2:
635 luma_chan = 0;
636 break;
637 case 3:
638 case 4:
639 luma_chan = 1;
640 break;
641 default:
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));
644 return 0;
645 }
646
647 /* Add code to get the filename info from the iolayer */
648 /* Also add code to check for mmapped code */
649
650
651 mm_log((1, "i_writetiff_wiol_faxable: width=%d, height=%d, channels=%d\n", width, height, im->channels));
652
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; }
799d55a6 665 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
10461f9a
TC
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; }
669
670 linebuf = (unsigned char *)_TIFFmalloc( TIFFScanlineSize(tif) );
671
672 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
673 mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField rowsperstrip=-1\n")); return 0; }
674
675 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
676 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rc);
677
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));
681
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;
688 }
689
690 if (!save_tiff_tags(tif, im)) {
691 return 0;
692 }
693
694 for (y=0; y<height; y++) {
695 int linebufpos=0;
696 for(x=0; x<width; x+=8) {
697 int bits;
698 int bitpos;
699 i_sample_t luma[8];
700 uint8 bitval = 128;
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++) {
799d55a6 705 linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
10461f9a
TC
706 bitval >>= 1;
707 }
708 linebufpos++;
709 }
710 if (TIFFWriteScanline(tif, linebuf, y, 0) < 0) {
711 mm_log((1, "i_writetiff_wiol_faxable: TIFFWriteScanline failed.\n"));
712 break;
713 }
714 }
715 if (linebuf) _TIFFfree(linebuf);
716
717 return 1;
718}
719
bd8052a6
TC
720static uint16
721find_compression(char const *name, uint16 *compress) {
722 int i;
02d1d628 723
bd8052a6
TC
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;
727 return 1;
f62b2d84 728 }
02d1d628 729 }
bd8052a6 730 *compress = COMPRESSION_NONE;
02d1d628 731
bd8052a6
TC
732 return 0;
733}
02d1d628 734
bd8052a6
TC
735static uint16
736get_compression(i_img *im, uint16 def_compress) {
737 int entry;
738 int value;
739
740 if (i_tags_find(&im->tags, "tiff_compression", 0, &entry)
741 && im->tags.tags[entry].data) {
742 uint16 compress;
743 if (find_compression(im->tags.tags[entry].data, &compress)
f8d72f20 744 && myTIFFIsCODECConfigured(compress))
bd8052a6 745 return compress;
10461f9a 746 }
bd8052a6
TC
747 if (i_tags_get_int(&im->tags, "tiff_compression", 0, &value)) {
748 if ((uint16)value == value
f8d72f20 749 && myTIFFIsCODECConfigured((uint16)value))
bd8052a6 750 return (uint16)value;
10461f9a 751 }
bd8052a6
TC
752
753 return def_compress;
754}
755
756int
757i_tiff_has_compression(const char *name) {
758 uint16 compress;
759
760 if (!find_compression(name, &compress))
761 return 0;
762
f8d72f20 763 return myTIFFIsCODECConfigured(compress);
bd8052a6
TC
764}
765
766static int
767set_base_tags(TIFF *tif, i_img *im, uint16 compress, uint16 photometric,
768 uint16 bits_per_sample, uint16 samples_per_pixel) {
769 double xres, yres;
770 int resunit;
771 int got_xres, got_yres;
772 int aspect_only;
773
774 if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->xsize)) {
775 i_push_error(0, "write TIFF: setting width tag");
776 return 0;
10461f9a 777 }
bd8052a6
TC
778 if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->ysize)) {
779 i_push_error(0, "write TIFF: setting length tag");
780 return 0;
10461f9a 781 }
bd8052a6
TC
782 if (!TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)) {
783 i_push_error(0, "write TIFF: setting orientation tag");
784 return 0;
10461f9a 785 }
bd8052a6
TC
786 if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
787 i_push_error(0, "write TIFF: setting planar configuration tag");
788 return 0;
02d1d628 789 }
bd8052a6
TC
790 if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
791 i_push_error(0, "write TIFF: setting photometric tag");
792 return 0;
f62b2d84 793 }
bd8052a6
TC
794 if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, compress)) {
795 i_push_error(0, "write TIFF: setting compression tag");
796 return 0;
f62b2d84 797 }
bd8052a6
TC
798 if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) {
799 i_push_error(0, "write TIFF: setting bits per sample tag");
f62b2d84
TC
800 return 0;
801 }
bd8052a6
TC
802 if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel)) {
803 i_push_error(0, "write TIFF: setting samples per pixel tag");
02d1d628
AMH
804 return 0;
805 }
02d1d628 806
faa9b3e7
TC
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))
810 aspect_only = 0;
811 if (!i_tags_get_int(&im->tags, "tiff_resolutionunit", 0, &resunit))
812 resunit = RESUNIT_INCH;
813 if (got_xres || got_yres) {
814 if (!got_xres)
815 xres = yres;
816 else if (!got_yres)
817 yres = xres;
818 if (aspect_only) {
819 resunit = RESUNIT_NONE;
820 }
821 else {
822 if (resunit == RESUNIT_CENTIMETER) {
823 xres /= 2.54;
824 yres /= 2.54;
825 }
826 else {
827 resunit = RESUNIT_INCH;
828 }
829 }
830 if (!TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xres)) {
bd8052a6 831 i_push_error(0, "write TIFF: setting xresolution tag");
faa9b3e7
TC
832 return 0;
833 }
834 if (!TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)yres)) {
bd8052a6 835 i_push_error(0, "write TIFF: setting yresolution tag");
faa9b3e7
TC
836 return 0;
837 }
838 if (!TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (uint16)resunit)) {
bd8052a6 839 i_push_error(0, "write TIFF: setting resolutionunit tag");
faa9b3e7 840 return 0;
02d1d628
AMH
841 }
842 }
fd9a31d2 843
bd8052a6
TC
844 return 1;
845}
846
847static int
848write_one_bilevel(TIFF *tif, i_img *im, int zero_is_white) {
849 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
850 uint16 photometric;
851 unsigned char *in_row;
852 unsigned char *out_row;
853 unsigned out_size;
854 int x, y;
855 int invert;
856
857 mm_log((1, "tiff - write_one_bilevel(tif %p, im %p, zero_is_white %d)\n",
858 tif, im, zero_is_white));
859
860 /* ignore a silly choice */
861 if (compress == COMPRESSION_JPEG)
862 compress = COMPRESSION_PACKBITS;
863
864 switch (compress) {
865 case COMPRESSION_CCITTRLE:
866 case COMPRESSION_CCITTFAX3:
867 case COMPRESSION_CCITTFAX4:
868 /* natural fax photometric */
869 photometric = PHOTOMETRIC_MINISWHITE;
870 break;
871
872 default:
873 /* natural for most computer images */
874 photometric = PHOTOMETRIC_MINISBLACK;
875 break;
fd9a31d2
TC
876 }
877
bd8052a6
TC
878 if (!set_base_tags(tif, im, compress, photometric, 1, 1))
879 return 0;
880
881 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
882 i_push_error(0, "write TIFF: setting rows per strip tag");
883 return 0;
f62b2d84 884 }
bd8052a6
TC
885
886 out_size = TIFFScanlineSize(tif);
887 out_row = (unsigned char *)_TIFFmalloc( out_size );
888 in_row = mymalloc(im->xsize);
889
890 invert = (photometric == PHOTOMETRIC_MINISWHITE) != (zero_is_white != 0);
891
892 for (y = 0; y < im->ysize; ++y) {
893 int mask = 0x80;
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]) {
899 *outp |= mask;
f62b2d84 900 }
bd8052a6
TC
901 mask >>= 1;
902 if (!mask) {
903 ++outp;
904 mask = 0x80;
f62b2d84 905 }
02d1d628 906 }
bd8052a6
TC
907 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
908 _TIFFfree(out_row);
909 myfree(in_row);
910 i_push_error(0, "write TIFF: write scan line failed");
911 return 0;
912 }
02d1d628 913 }
d2dfdcc9 914
bd8052a6
TC
915 _TIFFfree(out_row);
916 myfree(in_row);
d2dfdcc9 917
bd8052a6
TC
918 return 1;
919}
d2dfdcc9 920
bd8052a6
TC
921static int
922set_palette(TIFF *tif, i_img *im, int size) {
923 int count;
924 uint16 *colors;
925 uint16 *out[3];
926 i_color c;
927 int i, ch;
928
929 colors = (uint16 *)_TIFFmalloc(sizeof(uint16) * 3 * size);
930 out[0] = colors;
931 out[1] = colors + size;
932 out[2] = colors + 2 * size;
933
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;
939 }
940 for (; i < size; ++i) {
941 for (ch = 0; ch < 3; ++ch)
942 out[ch][i] = 0;
943 }
944 if (!TIFFSetField(tif, TIFFTAG_COLORMAP, out[0], out[1], out[2])) {
945 _TIFFfree(colors);
946 i_push_error(0, "write TIFF: setting color map");
947 return 0;
948 }
949 _TIFFfree(colors);
950
951 return 1;
952}
d2dfdcc9 953
bd8052a6
TC
954static int
955write_one_paletted8(TIFF *tif, i_img *im) {
956 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
957 unsigned char *out_row;
958 unsigned out_size;
959 int y;
d2dfdcc9 960
bd8052a6 961 mm_log((1, "tiff - write_one_paletted8(tif %p, im %p)\n", tif, im));
2691d220 962
bd8052a6
TC
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;
d2dfdcc9 969
bd8052a6
TC
970 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
971 i_push_error(0, "write TIFF: setting rows per strip tag");
972 return 0;
973 }
10461f9a 974
bd8052a6
TC
975 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 8, 1))
976 return 0;
10461f9a 977
bd8052a6 978 if (!set_palette(tif, im, 256))
d2dfdcc9 979 return 0;
d2dfdcc9 980
bd8052a6
TC
981 out_size = TIFFScanlineSize(tif);
982 out_row = (unsigned char *)_TIFFmalloc( out_size );
983
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) {
987 _TIFFfree(out_row);
988 i_push_error(0, "write TIFF: write scan line failed");
10461f9a
TC
989 return 0;
990 }
bd8052a6 991 }
10461f9a 992
bd8052a6
TC
993 _TIFFfree(out_row);
994
995 return 1;
996}
997
998static int
999write_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;
1003 unsigned out_size;
1004 int y;
1005
1006 mm_log((1, "tiff - write_one_paletted4(tif %p, im %p)\n", tif, im));
1007
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;
1014
1015 if (!set_base_tags(tif, im, compress, PHOTOMETRIC_PALETTE, 4, 1))
1016 return 0;
1017
1018 if (!set_palette(tif, im, 16))
1019 return 0;
1020
1021 if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1))) {
1022 i_push_error(0, "write TIFF: setting rows per strip tag");
1023 return 0;
1024 }
1025
1026 in_row = mymalloc(im->xsize);
1027 out_size = TIFFScanlineSize(tif);
1028 out_row = (unsigned char *)_TIFFmalloc( out_size );
1029
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) {
1035 _TIFFfree(out_row);
1036 i_push_error(0, "write TIFF: write scan line failed");
1037 return 0;
1038 }
1039 }
1040
1041 myfree(in_row);
1042 _TIFFfree(out_row);
1043
1044 return 1;
1045}
1046
1047static int
1048set_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;
1054
1055 if (!set_base_tags(tif, im, compress, photometric, bits_per_sample,
1056 im->channels)) {
1057 return 0;
1058 }
1059
1060 if (extra_count) {
1061 if (!TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, extra_count, &extras)) {
1062 i_push_error(0, "write TIFF: setting extra samples tag");
1063 return 0;
1064 }
1065 }
1066
1067 if (compress == COMPRESSION_JPEG) {
1068 int jpeg_quality;
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");
1073 return 0;
1074 }
1075 }
1076 }
1077
1078 return 1;
1079}
1080
1081static int
1082write_one_32(TIFF *tif, i_img *im) {
1083 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1084 unsigned *in_row;
1085 size_t out_size;
1086 uint32 *out_row;
1087 int y;
1088 size_t sample_count = im->xsize * im->channels;
1089 size_t sample_index;
1090
1091 mm_log((1, "tiff - write_one_32(tif %p, im %p)\n", tif, im));
1092
1093 /* only 8 and 12 bit samples are supported by jpeg compression */
1094 if (compress == COMPRESSION_JPEG)
1095 compress = COMPRESSION_PACKBITS;
1096
1097 if (!set_direct_tags(tif, im, compress, 32))
1098 return 0;
1099
1100 in_row = mymalloc(sample_count * sizeof(unsigned));
1101 out_size = TIFFScanlineSize(tif);
1102 out_row = (uint32 *)_TIFFmalloc( out_size );
1103
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");
1107 return 0;
1108 }
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) {
1112 myfree(in_row);
1113 _TIFFfree(out_row);
1114 i_push_error(0, "write TIFF: write scan line failed");
1115 return 0;
1116 }
1117 }
1118
1119 myfree(in_row);
1120 _TIFFfree(out_row);
1121
1122 return 1;
1123}
1124
1125static int
1126write_one_16(TIFF *tif, i_img *im) {
1127 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1128 unsigned *in_row;
1129 size_t out_size;
1130 uint16 *out_row;
1131 int y;
1132 size_t sample_count = im->xsize * im->channels;
1133 size_t sample_index;
1134
1135 mm_log((1, "tiff - write_one_16(tif %p, im %p)\n", tif, im));
1136
1137 /* only 8 and 12 bit samples are supported by jpeg compression */
1138 if (compress == COMPRESSION_JPEG)
1139 compress = COMPRESSION_PACKBITS;
1140
1141 if (!set_direct_tags(tif, im, compress, 16))
1142 return 0;
1143
1144 in_row = mymalloc(sample_count * sizeof(unsigned));
1145 out_size = TIFFScanlineSize(tif);
1146 out_row = (uint16 *)_TIFFmalloc( out_size );
1147
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");
1151 return 0;
1152 }
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) {
1156 myfree(in_row);
1157 _TIFFfree(out_row);
1158 i_push_error(0, "write TIFF: write scan line failed");
1159 return 0;
1160 }
1161 }
1162
1163 myfree(in_row);
1164 _TIFFfree(out_row);
1165
1166 return 1;
1167}
1168
1169static int
1170write_one_8(TIFF *tif, i_img *im) {
1171 uint16 compress = get_compression(im, COMPRESSION_PACKBITS);
1172 size_t out_size;
1173 unsigned char *out_row;
1174 int y;
1175 size_t sample_count = im->xsize * im->channels;
1176
1177 mm_log((1, "tiff - write_one_8(tif %p, im %p)\n", tif, im));
1178
1179 if (!set_direct_tags(tif, im, compress, 8))
1180 return 0;
1181
1182 out_size = TIFFScanlineSize(tif);
1183 if (out_size < sample_count)
1184 out_size = sample_count;
1185 out_row = (unsigned char *)_TIFFmalloc( out_size );
1186
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");
1190 return 0;
1191 }
1192 if (TIFFWriteScanline(tif, out_row, y, 0) < 0) {
1193 _TIFFfree(out_row);
1194 i_push_error(0, "write TIFF: write scan line failed");
1195 return 0;
1196 }
1197 }
1198 _TIFFfree(out_row);
1199
1200 return 1;
1201}
1202
1203static int
1204i_writetiff_low(TIFF *tif, i_img *im) {
1205 uint32 width, height;
1206 uint16 channels;
1207 int zero_is_white;
1208
1209 width = im->xsize;
1210 height = im->ysize;
1211 channels = im->channels;
1212
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)));
1216 }
1217
1218 if (i_img_is_monochrome(im, &zero_is_white)) {
1219 if (!write_one_bilevel(tif, im, zero_is_white))
1220 return 0;
1221 }
1222 else if (im->type == i_palette_type) {
1223 if (i_colorcount(im) <= 16) {
1224 if (!write_one_paletted4(tif, im))
1225 return 0;
1226 }
1227 else {
1228 if (!write_one_paletted8(tif, im))
1229 return 0;
1230 }
1231 }
1232 else if (im->bits > 16) {
1233 if (!write_one_32(tif, im))
1234 return 0;
1235 }
1236 else if (im->bits > 8) {
1237 if (!write_one_16(tif, im))
1238 return 0;
1239 }
1240 else {
1241 if (!write_one_8(tif, im))
1242 return 0;
1243 }
1244
1245 if (!save_tiff_tags(tif, im))
1246 return 0;
1247
1248 return 1;
1249}
1250
1251/*
1252=item i_writetiff_multi_wiol(ig, imgs, count, fine_mode)
1253
1254Stores an image in the iolayer object.
1255
1256 ig - io_object that defines source to write to
1257 imgs,count - the images to write
1258
1259=cut
1260*/
1261
1262undef_int
1263i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
1264 TIFF* tif;
1265 TIFFErrorHandler old_handler;
1266 int i;
1267
1268 old_handler = TIFFSetErrorHandler(error_handler);
1269
bd8052a6
TC
1270 i_clear_error();
1271 mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
1272 ig, imgs, count));
1273
1274 /* FIXME: Enable the mmap interface */
1275
1276 tif = TIFFClientOpen("No name",
1277 "wm",
1278 (thandle_t) ig,
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);
1286
1287
1288
1289 if (!tif) {
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);
1293 return 0;
1294 }
1295
1296 for (i = 0; i < count; ++i) {
1297 if (!i_writetiff_low(tif, imgs[i])) {
1298 TIFFClose(tif);
1299 TIFFSetErrorHandler(old_handler);
1300 return 0;
1301 }
1302
1303 if (!TIFFWriteDirectory(tif)) {
1304 i_push_error(0, "Cannot write TIFF directory");
1305 TIFFClose(tif);
2691d220 1306 TIFFSetErrorHandler(old_handler);
10461f9a
TC
1307 return 0;
1308 }
1309 }
1310
2691d220 1311 TIFFSetErrorHandler(old_handler);
10461f9a 1312 (void) TIFFClose(tif);
2691d220 1313
10461f9a
TC
1314 return 1;
1315}
1316
1317/*
1318=item i_writetiff_multi_wiol_faxable(ig, imgs, count, fine_mode)
1319
1320Stores an image in the iolayer object.
1321
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
1325
1326=cut
1327*/
1328
1329
1330undef_int
1331i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
1332 TIFF* tif;
1333 int i;
2691d220
TC
1334 TIFFErrorHandler old_handler;
1335
1336 old_handler = TIFFSetErrorHandler(error_handler);
d2dfdcc9 1337
10461f9a
TC
1338 i_clear_error();
1339 mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
1340 ig, imgs, count));
d2dfdcc9
TC
1341
1342 /* FIXME: Enable the mmap interface */
1343
1344 tif = TIFFClientOpen("No name",
1345 "wm",
1346 (thandle_t) ig,
1347 (TIFFReadWriteProc) ig->readcb,
1348 (TIFFReadWriteProc) ig->writecb,
1349 (TIFFSeekProc) comp_seek,
1350 (TIFFCloseProc) ig->closecb,
e18f39b3
TC
1351 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1352 (TIFFMapFileProc) comp_mmap,
1353 (TIFFUnmapFileProc) comp_munmap);
10461f9a
TC
1354
1355
d2dfdcc9
TC
1356
1357 if (!tif) {
10461f9a 1358 mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
2691d220
TC
1359 i_push_error(0, "Could not create TIFF object");
1360 TIFFSetErrorHandler(old_handler);
d2dfdcc9
TC
1361 return 0;
1362 }
1363
10461f9a
TC
1364 for (i = 0; i < count; ++i) {
1365 if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
1366 TIFFClose(tif);
2691d220 1367 TIFFSetErrorHandler(old_handler);
10461f9a
TC
1368 return 0;
1369 }
d2dfdcc9 1370
10461f9a
TC
1371 if (!TIFFWriteDirectory(tif)) {
1372 i_push_error(0, "Cannot write TIFF directory");
1373 TIFFClose(tif);
2691d220 1374 TIFFSetErrorHandler(old_handler);
10461f9a
TC
1375 return 0;
1376 }
1377 }
d2dfdcc9 1378
10461f9a 1379 (void) TIFFClose(tif);
2691d220
TC
1380 TIFFSetErrorHandler(old_handler);
1381
10461f9a
TC
1382 return 1;
1383}
d2dfdcc9 1384
10461f9a
TC
1385/*
1386=item i_writetiff_wiol(im, ig)
d2dfdcc9 1387
10461f9a
TC
1388Stores an image in the iolayer object.
1389
1390 im - image object to write out
1391 ig - io_object that defines source to write to
1392
1393=cut
1394*/
1395undef_int
1396i_writetiff_wiol(i_img *img, io_glue *ig) {
1397 TIFF* tif;
2691d220
TC
1398 TIFFErrorHandler old_handler;
1399
1400 old_handler = TIFFSetErrorHandler(error_handler);
10461f9a 1401
10461f9a
TC
1402 i_clear_error();
1403 mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", img, ig));
1404
1405 /* FIXME: Enable the mmap interface */
2691d220 1406
10461f9a
TC
1407 tif = TIFFClientOpen("No name",
1408 "wm",
1409 (thandle_t) ig,
1410 (TIFFReadWriteProc) ig->readcb,
1411 (TIFFReadWriteProc) ig->writecb,
1412 (TIFFSeekProc) comp_seek,
1413 (TIFFCloseProc) ig->closecb,
e18f39b3
TC
1414 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1415 (TIFFMapFileProc) comp_mmap,
1416 (TIFFUnmapFileProc) comp_munmap);
10461f9a
TC
1417
1418
1419
1420 if (!tif) {
1421 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
2691d220
TC
1422 i_push_error(0, "Could not create TIFF object");
1423 TIFFSetErrorHandler(old_handler);
10461f9a 1424 return 0;
d2dfdcc9 1425 }
d2dfdcc9 1426
10461f9a 1427 if (!i_writetiff_low(tif, img)) {
fd9a31d2 1428 TIFFClose(tif);
2691d220 1429 TIFFSetErrorHandler(old_handler);
fd9a31d2
TC
1430 return 0;
1431 }
1432
10461f9a 1433 (void) TIFFClose(tif);
2691d220
TC
1434 TIFFSetErrorHandler(old_handler);
1435
10461f9a
TC
1436 return 1;
1437}
1438
1439
1440
1441/*
1442=item i_writetiff_wiol_faxable(i_img *, io_glue *)
1443
1444Stores an image in the iolayer object in faxable tiff format.
1445
1446 im - image object to write out
1447 ig - io_object that defines source to write to
1448
1449Note, this may be rewritten to use to simply be a call to a
1450lower-level function that gives more options for writing tiff at some
1451point.
1452
1453=cut
1454*/
1455
1456undef_int
1457i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
1458 TIFF* tif;
2691d220
TC
1459 TIFFErrorHandler old_handler;
1460
1461 old_handler = TIFFSetErrorHandler(error_handler);
10461f9a 1462
10461f9a
TC
1463 i_clear_error();
1464 mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", im, ig));
1465
1466 /* FIXME: Enable the mmap interface */
1467
1468 tif = TIFFClientOpen("No name",
1469 "wm",
1470 (thandle_t) ig,
1471 (TIFFReadWriteProc) ig->readcb,
1472 (TIFFReadWriteProc) ig->writecb,
1473 (TIFFSeekProc) comp_seek,
1474 (TIFFCloseProc) ig->closecb,
e18f39b3
TC
1475 ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
1476 (TIFFMapFileProc) comp_mmap,
1477 (TIFFUnmapFileProc) comp_munmap);
10461f9a
TC
1478
1479
1480
1481 if (!tif) {
1482 mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
2691d220
TC
1483 i_push_error(0, "Could not create TIFF object");
1484 TIFFSetErrorHandler(old_handler);
10461f9a 1485 return 0;
d2dfdcc9 1486 }
10461f9a
TC
1487
1488 if (!i_writetiff_low_faxable(tif, im, fine)) {
1489 TIFFClose(tif);
2691d220 1490 TIFFSetErrorHandler(old_handler);
10461f9a
TC
1491 return 0;
1492 }
1493
d2dfdcc9 1494 (void) TIFFClose(tif);
2691d220
TC
1495 TIFFSetErrorHandler(old_handler);
1496
d2dfdcc9
TC
1497 return 1;
1498}
1499
fd9a31d2
TC
1500static int save_tiff_tags(TIFF *tif, i_img *im) {
1501 int i;
10461f9a 1502
fd9a31d2
TC
1503 for (i = 0; i < text_tag_count; ++i) {
1504 int entry;
1505 if (i_tags_find(&im->tags, text_tag_names[i].name, 0, &entry)) {
1506 if (!TIFFSetField(tif, text_tag_names[i].tag,
10461f9a
TC
1507 im->tags.tags[entry].data)) {
1508 i_push_errorf(0, "cannot save %s to TIFF", text_tag_names[i].name);
1509 return 0;
fd9a31d2
TC
1510 }
1511 }
1512 }
10461f9a 1513
fd9a31d2
TC
1514 return 1;
1515}
b8c2033e 1516
10461f9a 1517
bd8052a6
TC
1518static void
1519unpack_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;
1524 --src_byte_count;
1525 }
1526}
5bb828f1 1527
bd8052a6
TC
1528static void pack_4bit_to(unsigned char *dest, const unsigned char *src,
1529 int pixel_count) {
1530 int i = 0;
1531 while (i < pixel_count) {
1532 if ((i & 1) == 0) {
1533 *dest = *src++ << 4;
1534 }
1535 else {
1536 *dest++ |= *src++;
1537 }
1538 ++i;
1539 }
1540}
5bb828f1 1541
bd8052a6
TC
1542static i_img *
1543make_rgb(TIFF *tif, int width, int height, int *alpha_chan) {
1544 uint16 photometric;
1545 uint16 channels, in_channels;
1546 uint16 extra_count;
1547 uint16 *extras;
5bb828f1 1548
bd8052a6
TC
1549 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &in_channels);
1550 TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &photometric);
5bb828f1 1551
bd8052a6
TC
1552 switch (photometric) {
1553 case PHOTOMETRIC_SEPARATED:
1554 channels = 3;
1555 break;
1556
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
1561 if needed */
1562 channels = 1;
1563 break;
5bb828f1 1564
bd8052a6
TC
1565 default:
1566 channels = 3;
1567 break;
1568 }
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 */
1572 *alpha_chan = 0;
1573 if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)
1574 && extra_count) {
1575 *alpha_chan = channels++;
5bb828f1 1576 }
bd8052a6
TC
1577
1578 return i_img_8_new(width, height, channels);
5bb828f1
TC
1579}
1580
bd8052a6
TC
1581static i_img *
1582read_one_rgb_lines(TIFF *tif, int width, int height, int allow_incomplete) {
1583 i_img *im;
1584 uint32* raster = NULL;
1585 uint32 rowsperstrip, row;
1586 i_color *line_buf;
1587 int alpha_chan;
694d935c 1588 int rc;
bd8052a6
TC
1589
1590 im = make_rgb(tif, width, height, &alpha_chan);
1591 if (!im)
1592 return NULL;
1593
694d935c 1594 rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
bd8052a6
TC
1595 mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
1596
1597 if (rc != 1 || rowsperstrip==-1) {
1598 rowsperstrip = height;
1599 }
1600
1601 raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
1602 if (!raster) {
1603 i_img_destroy(im);
1604 i_push_error(0, "No space for raster buffer");
1605 return NULL;
1606 }
1607
1608 line_buf = mymalloc(sizeof(i_color) * width);
1609
1610 for( row = 0; row < height; row += rowsperstrip ) {
1611 uint32 newrows, i_row;
1612
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);
1617 break;
1618 }
1619 else {
1620 i_push_error(0, "could not read TIFF image strip");
1621 _TIFFfree(raster);
1622 i_img_destroy(im);
1623 return NULL;
1624 }
1625 }
1626
1627 newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
1628 mm_log((1, "newrows=%d\n", newrows));
1629
1630 for( i_row = 0; i_row < newrows; i_row++ ) {
1631 uint32 x;
1632 i_color *outp = line_buf;
1633
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);
1639
1640 if (alpha_chan) {
1641 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1642 alpha in the right place and scale it */
1643 int ch;
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];
1648 }
1649 }
1650 }
1651
1652 outp++;
1653 }
1654 i_plin(im, 0, width, i_row+row, line_buf);
1655 }
f62b2d84 1656 }
bd8052a6
TC
1657
1658 myfree(line_buf);
1659 _TIFFfree(raster);
1660
1661 return im;
1662}
1663
1664/* adapted from libtiff
1665
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.
1669
1670 So the caller here has set stoponerror to 1 so that
1671 TIFFRGBAImageGet() will fail.
1672
1673 read_one_rgb_tiled() then takes that into account for i_incomplete
1674 or failure.
1675 */
1676static int
1677myTIFFReadRGBATile(TIFFRGBAImage *img, uint32 col, uint32 row, uint32 * raster)
1678
1679{
1680 int ok;
1681 uint32 tile_xsize, tile_ysize;
1682 uint32 read_xsize, read_ysize;
1683 uint32 i_row;
1684
1685 /*
1686 * Verify that our request is legal - on a tile file, and on a
1687 * tile boundary.
1688 */
1689
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 )
1693 {
1694 i_push_errorf(0, "Row/col passed to myTIFFReadRGBATile() must be top"
1695 "left corner of a tile.");
1696 return 0;
1697 }
1698
1699 /*
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.
1704 */
1705
1706 if( row + tile_ysize > img->height )
1707 read_ysize = img->height - row;
1708 else
1709 read_ysize = tile_ysize;
1710
1711 if( col + tile_xsize > img->width )
1712 read_xsize = img->width - col;
1713 else
1714 read_xsize = tile_xsize;
1715
1716 /*
1717 * Read the chunk of imagery.
1718 */
1719
1720 img->row_offset = row;
1721 img->col_offset = col;
1722
1723 ok = TIFFRGBAImageGet(img, raster, read_xsize, read_ysize );
1724
1725 /*
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.
1728 *
1729 * This is all the more complicated because the image is organized in
1730 * bottom to top format.
1731 */
1732
1733 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
1734 return( ok );
1735
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) );
1742 }
1743
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 );
1747 }
1748
1749 return (ok);
f62b2d84 1750}
5bb828f1 1751
bd8052a6
TC
1752static i_img *
1753read_one_rgb_tiled(TIFF *tif, int width, int height, int allow_incomplete) {
1754 i_img *im;
1755 uint32* raster = NULL;
1756 int ok = 1;
1757 uint32 row, col;
1758 uint32 tile_width, tile_height;
1759 unsigned long pixels = 0;
1760 char emsg[1024] = "";
1761 TIFFRGBAImage img;
1762 i_color *line;
1763 int alpha_chan;
1764
1765 im = make_rgb(tif, width, height, &alpha_chan);
1766 if (!im)
1767 return NULL;
1768
1769 if (!TIFFRGBAImageOK(tif, emsg)
1770 || !TIFFRGBAImageBegin(&img, tif, 1, emsg)) {
1771 i_push_error(0, emsg);
1772 i_img_destroy(im);
1773 return( 0 );
1774 }
1775
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));
1779
1780 raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
1781 if (!raster) {
1782 i_img_destroy(im);
1783 i_push_error(0, "No space for raster buffer");
1784 TIFFRGBAImageEnd(&img);
1785 return NULL;
1786 }
1787 line = mymalloc(tile_width * sizeof(i_color));
1788
1789 for( row = 0; row < height; row += tile_height ) {
1790 for( col = 0; col < width; col += tile_width ) {
1791
1792 /* Read the tile into an RGBA array */
1793 if (myTIFFReadRGBATile(&img, col, row, raster)) {
1794 uint32 i_row, x;
1795 uint32 newrows = (row+tile_height > height) ? height-row : tile_height;
1796 uint32 newcols = (col+tile_width > width ) ? width-col : tile_width;
1797
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);
1807
1808 if (alpha_chan) {
1809 /* the libtiff RGBA code expands greyscale into RGBA, so put the
1810 alpha in the right place and scale it */
1811 int ch;
1812 outp->channel[alpha_chan] = TIFFGetA(temp);
1813
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];
1817 }
1818 }
1819 }
1820
1821 ++outp;
1822 }
1823 i_plin(im, col, col+newcols, row+i_row, line);
1824 }
1825 pixels += newrows * newcols;
1826 }
1827 else {
1828 if (allow_incomplete) {
1829 ok = 0;
1830 }
1831 else {
1832 goto error;
1833 }
1834 }
1835 }
1836 }
1837
1838 if (!ok) {
1839 if (pixels == 0) {
1840 i_push_error(0, "TIFF: No image data could be read from the image");
1841 goto error;
1842 }
1843
1844 /* incomplete image */
1845 i_tags_setn(&im->tags, "i_incomplete", 1);
1846 i_tags_setn(&im->tags, "i_lines_read", pixels / width);
1847 }
1848
1849 myfree(line);
1850 TIFFRGBAImageEnd(&img);
1851 _TIFFfree(raster);
1852
1853 return im;
1854
1855 error:
1856 myfree(line);
1857 _TIFFfree(raster);
1858 TIFFRGBAImageEnd(&img);
1859 i_img_destroy(im);
1860 return NULL;
1861}
1862
1863char const *
1864i_tiff_libversion(void) {
1865 return TIFFGetVersion();
1866}
1867
1868static int
1869setup_paletted(read_state_t *state) {
1870 uint16 *maps[3];
1871 int i, ch;
1872 int color_count = 1 << state->bits_per_sample;
1873
1874 state->img = i_img_pal_new(state->width, state->height, 3, 256);
1875 if (!state->img)
1876 return 0;
1877
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);
1882 return 0;
1883 }
1884 for (i = 0; i < color_count; ++i) {
1885 i_color c;
1886 for (ch = 0; ch < 3; ++ch) {
1887 c.channel[ch] = Sample16To8(maps[ch][i]);
1888 }
1889 i_addcolors(state->img, &c, 1);
1890 }
1891
1892 return 1;
1893}
1894
1895static int
1896tile_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;
1900 uint32 x, y;
1901
1902 state->raster = _TIFFmalloc(TIFFTileSize(state->tif));
1903 if (!state->raster) {
1904 i_push_error(0, "tiff: Out of memory allocating tile buffer");
1905 return 0;
1906 }
1907
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;
1913
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;
1917
1918 if (TIFFReadTile(state->tif,
1919 state->raster,
1920 x, y, 0, 0) < 0) {
1921 if (!state->allow_incomplete) {
1922 return 0;
1923 }
1924 }
1925 else {
1926 putter(state, x, y, this_tile_width, this_tile_height, tile_width - this_tile_width);
1927 }
1928
1929 cols_left -= this_tile_width;
1930 }
1931
1932 rows_left -= this_tile_height;
1933 }
1934
1935 return 1;
1936}
1937
1938static int
1939strip_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;
1943
1944 state->raster = _TIFFmalloc(strip_size);
1945 if (!state->raster) {
1946 i_push_error(0, "tiff: Out of memory allocating strip buffer");
1947 return 0;
1948 }
1949
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),
1956 state->raster,
1957 strip_size) < 0) {
1958 if (!state->allow_incomplete)
1959 return 0;
1960 }
1961 else {
1962 putter(state, 0, y, state->width, strip_rows, 0);
1963 }
1964 rows_left -= strip_rows;
1965 }
1966
1967 return 1;
1968}
1969
1970static int
1971paletted_putter8(read_state_t *state, int x, int y, int width, int height, int extras) {
1972 unsigned char *p = state->raster;
1973
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;
1978 --height;
1979 ++y;
1980 }
1981
1982 return 1;
1983}
1984
1985static int
1986paletted_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;
1990
1991 if (!state->line_buf)
1992 state->line_buf = mymalloc(state->width);
1993
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;
1999 --height;
2000 ++y;
2001 }
2002
2003 return 1;
2004}
2005
2006static void
2007rgb_channels(read_state_t *state, int *out_channels) {
2008 uint16 extra_count;
2009 uint16 *extras;
2010
2011 /* safe defaults */
2012 *out_channels = 3;
2013 state->alpha_chan = 0;
2014 state->scale_alpha = 0;
2015
2016 /* plain RGB */
2017 if (state->samples_per_pixel == 3)
2018 return;
2019
2020 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2021 mm_log((1, "tiff: samples != 3 but no extra samples tag\n"));
2022 return;
2023 }
2024
2025 if (!extra_count) {
2026 mm_log((1, "tiff: samples != 3 but no extra samples listed"));
2027 return;
2028 }
2029
2030 ++*out_channels;
2031 state->alpha_chan = 3;
2032 switch (*extras) {
2033 case EXTRASAMPLE_UNSPECIFIED:
2034 case EXTRASAMPLE_ASSOCALPHA:
2035 state->scale_alpha = 1;
2036 break;
2037
2038 case EXTRASAMPLE_UNASSALPHA:
2039 state->scale_alpha = 0;
2040 break;
2041
2042 default:
2043 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2044 *extras));
2045 state->scale_alpha = 1;
2046 break;
2047 }
2048 mm_log((1, "tiff alpha channel %d scale %d\n", state->alpha_chan, state->scale_alpha));
2049}
2050
2051static void
2052grey_channels(read_state_t *state, int *out_channels) {
2053 uint16 extra_count;
2054 uint16 *extras;
2055
2056 /* safe defaults */
2057 *out_channels = 1;
2058 state->alpha_chan = 0;
2059 state->scale_alpha = 0;
2060
2061 /* plain grey */
2062 if (state->samples_per_pixel == 1)
2063 return;
2064
2065 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2066 mm_log((1, "tiff: samples != 1 but no extra samples tag\n"));
2067 return;
2068 }
2069
2070 if (!extra_count) {
2071 mm_log((1, "tiff: samples != 1 but no extra samples listed"));
2072 return;
2073 }
2074
2075 ++*out_channels;
2076 state->alpha_chan = 1;
2077 switch (*extras) {
2078 case EXTRASAMPLE_UNSPECIFIED:
2079 case EXTRASAMPLE_ASSOCALPHA:
2080 state->scale_alpha = 1;
2081 break;
2082
2083 case EXTRASAMPLE_UNASSALPHA:
2084 state->scale_alpha = 0;
2085 break;
2086
2087 default:
2088 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2089 *extras));
2090 state->scale_alpha = 1;
2091 break;
2092 }
2093}
2094
2095static int
2096setup_16_rgb(read_state_t *state) {
2097 int out_channels;
2098
2099 rgb_channels(state, &out_channels);
2100
2101 state->img = i_img_16_new(state->width, state->height, out_channels);
2102 if (!state->img)
2103 return 0;
2104 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2105
2106 return 1;
2107}
2108
2109static int
2110setup_16_grey(read_state_t *state) {
2111 int out_channels;
2112
2113 grey_channels(state, &out_channels);
2114
2115 state->img = i_img_16_new(state->width, state->height, out_channels);
2116 if (!state->img)
2117 return 0;
2118 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2119
2120 return 1;
2121}
2122
2123static int
2124putter_16(read_state_t *state, int x, int y, int width, int height,
2125 int row_extras) {
2126 uint16 *p = state->raster;
2127 int out_chan = state->img->channels;
2128
2129 state->pixels_read += (unsigned long) width * height;
2130 while (height > 0) {
2131 int i;
2132 int ch;
2133 unsigned *outp = state->line_buf;
2134
2135 for (i = 0; i < width; ++i) {
2136 for (ch = 0; ch < out_chan; ++ch) {
2137 outp[ch] = p[ch];
2138 }
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);
2143 }
2144 }
2145 p += state->samples_per_pixel;
2146 outp += out_chan;
2147 }
2148
2149 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2150
2151 p += row_extras * state->samples_per_pixel;
2152 --height;
2153 ++y;
2154 }
2155
2156 return 1;
2157}
2158
2159static int
2160setup_8_rgb(read_state_t *state) {
2161 int out_channels;
2162
2163 rgb_channels(state, &out_channels);
2164
2165 state->img = i_img_8_new(state->width, state->height, out_channels);
2166 if (!state->img)
2167 return 0;
2168 state->line_buf = mymalloc(sizeof(unsigned) * state->width * out_channels);
2169
2170 return 1;
2171}
2172
2173static int
2174setup_8_grey(read_state_t *state) {
2175 int out_channels;
2176
2177 grey_channels(state, &out_channels);
2178
2179 state->img = i_img_8_new(state->width, state->height, out_channels);
2180 if (!state->img)
2181 return 0;
2182 state->line_buf = mymalloc(sizeof(i_color) * state->width * out_channels);
2183
2184 return 1;
2185}
2186
2187static int
2188putter_8(read_state_t *state, int x, int y, int width, int height,
2189 int row_extras) {
2190 unsigned char *p = state->raster;
2191 int out_chan = state->img->channels;
2192
2193 state->pixels_read += (unsigned long) width * height;
2194 while (height > 0) {
2195 int i;
2196 int ch;
2197 i_color *outp = state->line_buf;
2198
2199 for (i = 0; i < width; ++i) {
2200 for (ch = 0; ch < out_chan; ++ch) {
2201 outp->channel[ch] = p[ch];
2202 }
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];
2207
2208 outp->channel[ch] = CLAMP8(result);
2209 }
2210 }
2211 p += state->samples_per_pixel;
2212 outp++;
2213 }
2214
2215 i_plin(state->img, x, x + width, y, state->line_buf);
2216
2217 p += row_extras * state->samples_per_pixel;
2218 --height;
2219 ++y;
2220 }
2221
2222 return 1;
2223}
2224
2225static int
2226setup_32_rgb(read_state_t *state) {
2227 int out_channels;
2228
2229 rgb_channels(state, &out_channels);
2230
2231 state->img = i_img_double_new(state->width, state->height, out_channels);
2232 if (!state->img)
2233 return 0;
2234 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2235
2236 return 1;
2237}
2238
2239static int
2240setup_32_grey(read_state_t *state) {
2241 int out_channels;
2242
2243 grey_channels(state, &out_channels);
2244
2245 state->img = i_img_double_new(state->width, state->height, out_channels);
2246 if (!state->img)
2247 return 0;
2248 state->line_buf = mymalloc(sizeof(i_fcolor) * state->width);
2249
2250 return 1;
2251}
2252
2253static int
2254putter_32(read_state_t *state, int x, int y, int width, int height,
2255 int row_extras) {
2256 uint32 *p = state->raster;
2257 int out_chan = state->img->channels;
2258
2259 state->pixels_read += (unsigned long) width * height;
2260 while (height > 0) {
2261 int i;
2262 int ch;
2263 i_fcolor *outp = state->line_buf;
2264
2265 for (i = 0; i < width; ++i) {
2266 for (ch = 0; ch < out_chan; ++ch) {
2267 outp->channel[ch] = p[ch] / 4294967295.0;
2268 }
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];
2272 }
2273 p += state->samples_per_pixel;
2274 outp++;
2275 }
2276
2277 i_plinf(state->img, x, x + width, y, state->line_buf);
2278
2279 p += row_extras * state->samples_per_pixel;
2280 --height;
2281 ++y;
2282 }
2283
2284 return 1;
2285}
2286
2287static int
2288setup_bilevel(read_state_t *state) {
2289 i_color black, white;
2290 state->img = i_img_pal_new(state->width, state->height, 1, 256);
2291 if (!state->img)
2292 return 0;
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);
2300 }
2301 else {
2302 i_addcolors(state->img, &white, 1);
2303 i_addcolors(state->img, &black, 1);
2304 }
2305 state->line_buf = mymalloc(state->width);
2306
2307 return 1;
2308}
2309
2310static int
2311putter_bilevel(read_state_t *state, int x, int y, int width, int height,
2312 int row_extras) {
2313 unsigned char *line_in = state->raster;
2314 size_t line_size = (width + row_extras + 7) / 8;
2315
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) {
2320 int i;
2321 unsigned char *outp = state->line_buf;
2322 unsigned char *inp = line_in;
2323 unsigned mask = 0x80;
2324
2325 for (i = 0; i < width; ++i) {
2326 *outp++ = *inp & mask ? 1 : 0;
2327 mask >>= 1;
2328 if (!mask) {
2329 ++inp;
2330 mask = 0x80;
2331 }
2332 }
2333
2334 i_ppal(state->img, x, x + width, y, state->line_buf);
2335
2336 line_in += line_size;
2337 --height;
2338 ++y;
2339 }
2340
2341 return 1;
2342}
2343
2344static void
2345cmyk_channels(read_state_t *state, int *out_channels) {
2346 uint16 extra_count;
2347 uint16 *extras;
2348
2349 /* safe defaults */
2350 *out_channels = 3;
2351 state->alpha_chan = 0;
2352 state->scale_alpha = 0;
2353
2354 /* plain CMYK */
2355 if (state->samples_per_pixel == 4)
2356 return;
2357
2358 if (!TIFFGetField(state->tif, TIFFTAG_EXTRASAMPLES, &extra_count, &extras)) {
2359 mm_log((1, "tiff: CMYK samples != 4 but no extra samples tag\n"));
2360 return;
2361 }
2362
2363 if (!extra_count) {
2364 mm_log((1, "tiff: CMYK samples != 4 but no extra samples listed"));
2365 return;
2366 }
2367
2368 ++*out_channels;
2369 state->alpha_chan = 4;
2370 switch (*extras) {
2371 case EXTRASAMPLE_UNSPECIFIED:
2372 case EXTRASAMPLE_ASSOCALPHA:
2373 state->scale_alpha = 1;
2374 break;
2375
2376 case EXTRASAMPLE_UNASSALPHA:
2377 state->scale_alpha = 0;
2378 break;
2379
2380 default:
2381 mm_log((1, "tiff: unknown extra sample type %d, treating as assoc alpha\n",
2382 *extras));
2383 state->scale_alpha = 1;
2384 break;
2385 }
2386}
2387
2388static int
2389setup_cmyk8(read_state_t *state) {
2390 int channels;
2391
2392 cmyk_channels(state, &channels);
2393 state->img = i_img_8_new(state->width, state->height, channels);
2394
2395 state->line_buf = mymalloc(sizeof(i_color) * state->width);
2396
2397 return 1;
2398}
2399
2400static int
2401putter_cmyk8(read_state_t *state, int x, int y, int width, int height,
2402 int row_extras) {
2403 unsigned char *p = state->raster;
2404
2405 state->pixels_read += (unsigned long) width * height;
2406 while (height > 0) {
2407 int i;
2408 int ch;
2409 i_color *outp = state->line_buf;
2410
2411 for (i = 0; i < width; ++i) {
2412 unsigned char c, m, y, k;
2413 c = p[0];
2414 m = p[1];
2415 y = p[2];
2416 k = 255 - p[3];
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
2423 && outp->rgba.a) {
2424 for (ch = 0; ch < 3; ++ch) {
2425 int result = (outp->channel[ch] * 255 + 127) / outp->rgba.a;
2426 outp->channel[ch] = CLAMP8(result);
2427 }
2428 }
2429 }
2430 p += state->samples_per_pixel;
2431 outp++;
2432 }
2433
2434 i_plin(state->img, x, x + width, y, state->line_buf);
2435
2436 p += row_extras * state->samples_per_pixel;
2437 --height;
2438 ++y;
2439 }
2440
2441 return 1;
2442}
2443
2444static int
2445setup_cmyk16(read_state_t *state) {
2446 int channels;
2447
2448 cmyk_channels(state, &channels);
2449 state->img = i_img_16_new(state->width, state->height, channels);
2450
2451 state->line_buf = mymalloc(sizeof(unsigned) * state->width * channels);
2452
2453 return 1;
2454}
2455
2456static int
2457putter_cmyk16(read_state_t *state, int x, int y, int width, int height,
2458 int row_extras) {
2459 uint16 *p = state->raster;
2460 int out_chan = state->img->channels;
2461
2462 mm_log((4, "putter_cmyk16(%p, %d, %d, %d, %d, %d)\n", x, y, width, height, row_extras));
2463
2464 state->pixels_read += (unsigned long) width * height;
2465 while (height > 0) {
2466 int i;
2467 int ch;
2468 unsigned *outp = state->line_buf;
2469
2470 for (i = 0; i < width; ++i) {
2471 unsigned c, m, y, k;
2472 c = p[0];
2473 m = p[1];
2474 y = p[2];
2475 k = 65535 - p[3];
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
2482 && outp[3]) {
2483 for (ch = 0; ch < 3; ++ch) {
2484 int result = (outp[ch] * 65535 + 32767) / outp[3];
2485 outp[3] = CLAMP16(result);
2486 }
2487 }
2488 }
2489 p += state->samples_per_pixel;
2490 outp += out_chan;
2491 }
2492
2493 i_psamp_bits(state->img, x, x + width, y, state->line_buf, NULL, out_chan, 16);
2494
2495 p += row_extras * state->samples_per_pixel;
2496 --height;
2497 ++y;
2498 }
2499
2500 return 1;
2501}
2502
2503/*
2504
2505 Older versions of tifflib we support don't define this, so define it
2506 ourselves.
2507
f8d72f20
TC
2508 If you want this detection to do anything useful, use a newer
2509 release of tifflib.
2510
bd8052a6
TC
2511 */
2512#if TIFFLIB_VERSION < 20031121
2513
f8d72f20
TC
2514int
2515TIFFIsCODECConfigured(uint16 scheme) {
bd8052a6 2516 switch (scheme) {
f8d72f20 2517 /* these schemes are all shipped with tifflib */
bd8052a6 2518 case COMPRESSION_NONE:
bd8052a6 2519 case COMPRESSION_PACKBITS:
bd8052a6
TC
2520 case COMPRESSION_CCITTRLE:
2521 case COMPRESSION_CCITTRLEW:
2522 case COMPRESSION_CCITTFAX3:
2523 case COMPRESSION_CCITTFAX4:
f8d72f20 2524 return 1;
bd8052a6 2525
f8d72f20
TC
2526 /* these require external library support */
2527 default:
bd8052a6 2528 case COMPRESSION_JPEG:
bd8052a6 2529 case COMPRESSION_LZW:
bd8052a6
TC
2530 case COMPRESSION_DEFLATE:
2531 case COMPRESSION_ADOBE_DEFLATE:
bd8052a6
TC
2532 return 0;
2533 }
2534}
2535
2536#endif
2537
f8d72f20
TC
2538static int
2539myTIFFIsCODECConfigured(uint16 scheme) {
2540#if TIFFLIB_VERSION < 20040724
2541 if (scheme == COMPRESSION_LZW)
2542 return 0;
2543#endif
2544
2545 return TIFFIsCODECConfigured(scheme);
2546}
2547
b8c2033e
AMH
2548/*
2549=back
2550
2551=head1 AUTHOR
2552
bd8052a6 2553Arnar M. Hrafnkelsson <addi@umich.edu>, Tony Cook <tony@imager.perl.org>
b8c2033e
AMH
2554
2555=head1 SEE ALSO
2556
2557Imager(3)
2558
2559=cut
2560*/