/* do nothing */
}
-static i_img *read_one_tiff(TIFF *tif) {
+static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) {
i_img *im;
uint32 width, height;
uint16 channels;
mm_log((1, "i_readtiff_wiol: %stiled\n", tiled?"":"not "));
mm_log((1, "i_readtiff_wiol: %sbyte swapped\n", TIFFIsByteSwapped(tif)?"":"not "));
+ /* separated defaults to CMYK, but if the user is using some strange
+ ink system we can't work out the color anyway */
+ if (photometric == PHOTOMETRIC_SEPARATED && channels >= 4) {
+ /* TIFF can have more than one alpha channel on an image,
+ but Imager can't, only store the first one */
+
+ channels = channels == 4 ? 3 : 4;
+
+ /* unfortunately the RGBA functions don't try to deal with the alpha
+ channel on CMYK images, at some point I'm planning on expanding
+ TIFF support to handle 16-bit/sample images and I'll deal with
+ it then */
+ }
+
+ /* TIFF images can have more than one alpha channel, but Imager can't
+ this ignores the possibility of 2 channel images with 2 alpha,
+ but there's not much I can do about that */
+ if (channels > 4)
+ channels = 4;
+
if (photometric == PHOTOMETRIC_PALETTE && bits_per_sample <= 8) {
channels = 3;
im = i_img_pal_new(width, height, channels, 256);
++row;
}
if (row < height) {
+ if (allow_incomplete) {
+ i_tags_setn(&im->tags, "i_lines_read", row);
+ }
+ else {
+ i_img_destroy(im);
+ _TIFFfree(buffer);
+ return NULL;
+ }
error = 1;
}
/* Ideally we'd optimize the palette, but that could be expensive
uint32 newrows, i_row;
if (!TIFFReadRGBAStrip(tif, row, raster)) {
- error++;
- break;
+ if (allow_incomplete) {
+ i_tags_setn(&im->tags, "i_lines_read", row);
+ error++;
+ break;
+ }
+ else {
+ i_push_error(0, "could not read TIFF image strip");
+ _TIFFfree(raster);
+ i_img_destroy(im);
+ return NULL;
+ }
}
newrows = (row+rowsperstrip > height) ? height-row : rowsperstrip;
}
if (error) {
mm_log((1, "i_readtiff_wiol: error during reading\n"));
- i_tags_addn(&im->tags, "i_incomplete", 0, 1);
+ i_tags_setn(&im->tags, "i_incomplete", 1);
}
if (raster)
_TIFFfree( raster );
=cut
*/
i_img*
-i_readtiff_wiol(io_glue *ig, int length, int page) {
+i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) {
TIFF* tif;
TIFFErrorHandler old_handler;
TIFFErrorHandler old_warn_handler;
/* Also add code to check for mmapped code */
io_glue_commit_types(ig);
- mm_log((1, "i_readtiff_wiol(ig %p, length %d)\n", ig, length));
+ mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page));
tif = TIFFClientOpen("(Iolayer)",
"rm",
if (!tif) {
mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
- i_push_error(0, "opening file");
+ i_push_error(0, "Error opening file");
TIFFSetErrorHandler(old_handler);
TIFFSetWarningHandler(old_warn_handler);
return NULL;
i_push_errorf(0, "could not switch to page %d", page);
TIFFSetErrorHandler(old_handler);
TIFFSetWarningHandler(old_warn_handler);
+ TIFFClose(tif);
return NULL;
}
}
- im = read_one_tiff(tif);
+ im = read_one_tiff(tif, allow_incomplete);
if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
TIFFSetErrorHandler(old_handler);
if (!tif) {
mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
- i_push_error(0, "opening file");
+ i_push_error(0, "Error opening file");
TIFFSetErrorHandler(old_handler);
TIFFSetWarningHandler(old_warn_handler);
return NULL;
*count = 0;
do {
- i_img *im = read_one_tiff(tif);
+ i_img *im = read_one_tiff(tif, 0);
if (!im)
break;
if (++*count > result_alloc) {
{ mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField bitpersample=1\n")); return 0; }
if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG))
{ mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField planarconfig\n")); return 0; }
- if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK))
+ if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE))
{ mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField photometric=%d\n", PHOTOMETRIC_MINISBLACK)); return 0; }
if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, 3))
{ mm_log((1, "i_writetiff_wiol_faxable: TIFFSetField compression=3\n")); return 0; }
bits = width-x; if(bits>8) bits=8;
i_gsamp(im, x, x+8, y, luma, &luma_chan, 1);
for(bitpos=0;bitpos<bits;bitpos++) {
- linebuf[linebufpos] |= ((luma[bitpos]>=128)?bitval:0);
+ linebuf[linebufpos] |= ((luma[bitpos] < 128) ? bitval : 0);
bitval >>= 1;
}
linebufpos++;
undef_int
i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
TIFF* tif;
+ TIFFErrorHandler old_handler;
int i;
+ old_handler = TIFFSetErrorHandler(error_handler);
+
io_glue_commit_types(ig);
i_clear_error();
mm_log((1, "i_writetiff_multi_wiol(ig 0x%p, imgs 0x%p, count %d)\n",
if (!tif) {
- mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
+ mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n"));
+ i_push_error(0, "Could not create TIFF object");
+ TIFFSetErrorHandler(old_handler);
return 0;
}
for (i = 0; i < count; ++i) {
if (!i_writetiff_low(tif, imgs[i])) {
TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
return 0;
}
if (!TIFFWriteDirectory(tif)) {
i_push_error(0, "Cannot write TIFF directory");
TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
return 0;
}
}
+ TIFFSetErrorHandler(old_handler);
(void) TIFFClose(tif);
+
return 1;
}
i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
TIFF* tif;
int i;
+ TIFFErrorHandler old_handler;
+
+ old_handler = TIFFSetErrorHandler(error_handler);
io_glue_commit_types(ig);
i_clear_error();
if (!tif) {
mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n"));
+ i_push_error(0, "Could not create TIFF object");
+ TIFFSetErrorHandler(old_handler);
return 0;
}
for (i = 0; i < count; ++i) {
if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
return 0;
}
if (!TIFFWriteDirectory(tif)) {
i_push_error(0, "Cannot write TIFF directory");
TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
return 0;
}
}
(void) TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
+
return 1;
}
undef_int
i_writetiff_wiol(i_img *img, io_glue *ig) {
TIFF* tif;
+ TIFFErrorHandler old_handler;
+
+ old_handler = TIFFSetErrorHandler(error_handler);
io_glue_commit_types(ig);
i_clear_error();
mm_log((1, "i_writetiff_wiol(img %p, ig 0x%p)\n", img, ig));
/* FIXME: Enable the mmap interface */
-
+
tif = TIFFClientOpen("No name",
"wm",
(thandle_t) ig,
if (!tif) {
mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
+ i_push_error(0, "Could not create TIFF object");
+ TIFFSetErrorHandler(old_handler);
return 0;
}
if (!i_writetiff_low(tif, img)) {
TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
return 0;
}
(void) TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
+
return 1;
}
undef_int
i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
TIFF* tif;
+ TIFFErrorHandler old_handler;
+
+ old_handler = TIFFSetErrorHandler(error_handler);
io_glue_commit_types(ig);
i_clear_error();
if (!tif) {
mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n"));
+ i_push_error(0, "Could not create TIFF object");
+ TIFFSetErrorHandler(old_handler);
return 0;
}
if (!i_writetiff_low_faxable(tif, im, fine)) {
TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
return 0;
}
(void) TIFFClose(tif);
+ TIFFSetErrorHandler(old_handler);
+
return 1;
}