Merge pull request #5997 from Beep6581/tiff_read

Improve error logging and memory handling when reading tiff files
This commit is contained in:
Ingo Weyrich
2021-01-04 23:13:41 +01:00
committed by GitHub

View File

@@ -25,6 +25,7 @@
#include <cstring>
#include <fcntl.h>
#include <libiptcdata/iptc-jpeg.h>
#include <memory>
#include "rt_math.h"
#include "procparams.h"
#include "utils.h"
@@ -792,6 +793,8 @@ int ImageIO::loadTIFF (const Glib::ustring &fname)
if (!hasTag) {
// These are needed
TIFFClose(in);
fprintf(stderr, "Error 1 loading %s\n", fname.c_str());
fflush(stderr);
return IMIO_VARIANTNOTSUPPORTED;
}
@@ -800,6 +803,8 @@ int ImageIO::loadTIFF (const Glib::ustring &fname)
if (config != PLANARCONFIG_CONTIG) {
TIFFClose(in);
fprintf(stderr, "Error 2 loading %s\n", fname.c_str());
fflush(stderr);
return IMIO_VARIANTNOTSUPPORTED;
}
@@ -859,32 +864,33 @@ int ImageIO::loadTIFF (const Glib::ustring &fname)
allocate (width, height);
unsigned char* linebuffer = new unsigned char[TIFFScanlineSize(in) * (samplesperpixel == 1 ? 3 : 1)];
std::unique_ptr<unsigned char[]> linebuffer(new unsigned char[TIFFScanlineSize(in) * (samplesperpixel == 1 ? 3 : 1)]);
for (int row = 0; row < height; row++) {
if (TIFFReadScanline(in, linebuffer, row, 0) < 0) {
if (TIFFReadScanline(in, linebuffer.get(), row, 0) < 0) {
TIFFClose(in);
delete [] linebuffer;
fprintf(stderr, "Error 3 loading %s\n", fname.c_str());
fflush(stderr);
return IMIO_READERROR;
}
if (samplesperpixel > 3) {
for (int i = 0; i < width; i++) {
memcpy (linebuffer + i * 3 * bitspersample / 8, linebuffer + i * samplesperpixel * bitspersample / 8, 3 * bitspersample / 8);
memcpy(linebuffer.get() + i * 3 * bitspersample / 8, linebuffer.get() + i * samplesperpixel * bitspersample / 8, 3 * bitspersample / 8);
}
}
else if (samplesperpixel == 1) {
const size_t bytes = bitspersample / 8;
for (int i = width - 1; i >= 0; --i) {
const unsigned char* const src = linebuffer + i * bytes;
unsigned char* const dest = linebuffer + i * 3 * bytes;
const unsigned char* const src = linebuffer.get() + i * bytes;
unsigned char* const dest = linebuffer.get() + i * 3 * bytes;
memcpy(dest + 2 * bytes, src, bytes);
memcpy(dest + 1 * bytes, src, bytes);
memcpy(dest + 0 * bytes, src, bytes);
}
}
setScanline (row, linebuffer, bitspersample);
setScanline (row, linebuffer.get(), bitspersample);
if (pl && !(row % 100)) {
pl->setProgress ((double)(row + 1) / height);
@@ -892,7 +898,6 @@ int ImageIO::loadTIFF (const Glib::ustring &fname)
}
TIFFClose(in);
delete [] linebuffer;
if (pl) {
pl->setProgressStr ("PROGRESSBAR_READY");