Skip to content

Commit 78bbe5b

Browse files
authored
TIFFIO: Improve logging behavior (#117)
1 parent 9b9bfd9 commit 78bbe5b

File tree

1 file changed

+69
-7
lines changed

1 file changed

+69
-7
lines changed

core/src/TIFFIO.cpp

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
#include <cstddef>
44
#include <cstdint>
5+
#include <cstdio>
56
#include <cstring>
7+
#include <sstream>
8+
#include <string_view>
69
#include <utility>
710

811
#include <opencv2/imgproc.hpp>
@@ -26,6 +29,22 @@ namespace
2629
{
2730
constexpr bool MEMMAP_SUPPORTED = VC_MEMMAP_SUPPORTED;
2831

32+
void TIFFWarningHandler(const char* module, const char* fmt, va_list ap)
33+
{
34+
std::array<char, 1024> buf{};
35+
std::vsnprintf(buf.data(), buf.size(), fmt, ap);
36+
vc::Logger()->debug(
37+
"[TIFFIO] {}: {}", module, std::string_view(buf.data()));
38+
}
39+
40+
void TIFFErrorHandler(const char* module, const char* fmt, va_list ap)
41+
{
42+
std::array<char, 1024> buf{};
43+
std::vsnprintf(buf.data(), buf.size(), fmt, ap);
44+
vc::Logger()->error(
45+
"[TIFFIO] {}: {}", module, std::string_view(buf.data()));
46+
}
47+
2948
// Return a CV Mat type using TIFF type (signed, unsigned, float),
3049
// bit-depth, and number of channels
3150
auto GetCVMatType(
@@ -144,7 +163,7 @@ auto ReadImage(lt::TIFF* tif, const TIFFHeader& hdr) -> cv::Mat
144163
}
145164

146165
// Returns whether this TIFF file is encoded for memory mapping
147-
auto CanMMap(const TIFFHeader& hdr) -> bool
166+
auto CanMMap(const TIFFHeader& hdr) -> std::pair<bool, std::string>
148167
{
149168
const auto isContig = hdr.config == PLANARCONFIG_CONTIG;
150169
const auto isUint = hdr.type == SAMPLEFORMAT_UINT;
@@ -153,8 +172,43 @@ auto CanMMap(const TIFFHeader& hdr) -> bool
153172
const auto uncompressed = hdr.compression == tio::Compression::NONE;
154173
const auto singleStrip = hdr.rowsPerStrip == hdr.height;
155174
const auto endianMatch = hdr.bigEndian == vc::endian::big();
156-
return isContig and isUint and is16bpc and isMono and uncompressed and
157-
singleStrip and endianMatch;
175+
176+
// build result string
177+
std::stringstream ss;
178+
ss << std::boolalpha;
179+
bool hasValue{false};
180+
if (not isContig) {
181+
ss << (hasValue ? ", " : "") << "not contig";
182+
hasValue = true;
183+
}
184+
if (not isUint) {
185+
ss << (hasValue ? ", " : "") << "not uint";
186+
hasValue = true;
187+
}
188+
if (not is16bpc) {
189+
ss << (hasValue ? ", " : "") << "not 16bpc";
190+
hasValue = true;
191+
}
192+
if (not isMono) {
193+
ss << (hasValue ? ", " : "") << "not mono";
194+
hasValue = true;
195+
}
196+
if (not uncompressed) {
197+
ss << (hasValue ? ", " : "") << "not uncompressed";
198+
hasValue = true;
199+
}
200+
if (not singleStrip) {
201+
ss << (hasValue ? ", " : "") << "not single strip";
202+
hasValue = true;
203+
}
204+
if (not endianMatch) {
205+
ss << (hasValue ? ", " : "") << "wrong endian";
206+
}
207+
208+
return {
209+
isContig and isUint and is16bpc and isMono and uncompressed and
210+
singleStrip and endianMatch,
211+
ss.str()};
158212
}
159213

160214
// Memory mapp the tiff
@@ -189,6 +243,10 @@ auto tio::ReadTIFF(const fs::path& path, mmap_info* mmap_info) -> cv::Mat
189243
throw IOException("File does not exist");
190244
}
191245

246+
// Log errors and warnings to VC's logger
247+
lt::TIFFSetErrorHandler(TIFFErrorHandler);
248+
lt::TIFFSetWarningHandler(TIFFWarningHandler);
249+
192250
// Open the file read-only
193251
lt::TIFF* tif = lt::TIFFOpen(path.c_str(), "rc");
194252
if (tif == nullptr) {
@@ -200,7 +258,8 @@ auto tio::ReadTIFF(const fs::path& path, mmap_info* mmap_info) -> cv::Mat
200258
cv::Mat img;
201259

202260
// Load memmap'd image
203-
if (MEMMAP_SUPPORTED and mmap_info and CanMMap(hdr)) {
261+
if (const auto [res, msg] = CanMMap(hdr);
262+
MEMMAP_SUPPORTED and mmap_info and res) {
204263
// Try to mmap
205264
std::tie(img, *mmap_info) = MMapImage(path, hdr);
206265
if (img.empty()) {
@@ -212,9 +271,8 @@ auto tio::ReadTIFF(const fs::path& path, mmap_info* mmap_info) -> cv::Mat
212271
// If we requested memory mapping (and it's available), log the failure
213272
if (MEMMAP_SUPPORTED and mmap_info) {
214273
Logger()->debug(
215-
"TIFF cannot be memory mapped: {}. Image will be read into "
216-
"memory instead",
217-
path.string());
274+
"TIFF cannot be memory mapped: {}. Reason: {}", path.string(),
275+
msg);
218276
}
219277
img = ReadImage(tif, hdr);
220278
}
@@ -239,6 +297,10 @@ void tio::WriteTIFF(
239297
"Invalid file extension " + path.extension().string());
240298
}
241299

300+
// Log errors and warnings to VC's logger
301+
lt::TIFFSetErrorHandler(TIFFErrorHandler);
302+
lt::TIFFSetWarningHandler(TIFFWarningHandler);
303+
242304
// Image metadata
243305
const auto channels = img.channels();
244306
const auto width = static_cast<unsigned>(img.cols);

0 commit comments

Comments
 (0)