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