Skip to content

Commit

Permalink
pango_image: Add basic Tiff loading support.
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenlovegrove committed May 26, 2022
1 parent 118a1ba commit bd61af1
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
12 changes: 12 additions & 0 deletions components/pango_image/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ if(BUILD_PANGOLIN_LIBRAW)
endif()
endif()

option(BUILD_PANGOLIN_LIBTIFF "Build support for tiff images (libtiff)" ON)
if(BUILD_PANGOLIN_LIBTIFF)
find_package(TIFF QUIET)
if(TIFF_FOUND)
target_compile_definitions(${COMPONENT} PRIVATE HAVE_LIBTIFF)
target_include_directories(${COMPONENT} PRIVATE $TIFF_INCLUDE_DIR} )
target_link_libraries(${COMPONENT} PRIVATE ${TIFF_LIBRARIES})
message(STATUS "libtiff Found and Enabled")
endif()
endif()

target_sources( ${COMPONENT}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/pixel_format.cpp
Expand All @@ -99,6 +110,7 @@ PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/image_io_bmp.cpp
${CMAKE_CURRENT_LIST_DIR}/src/image_io_zstd.cpp
${CMAKE_CURRENT_LIST_DIR}/src/image_io_libraw.cpp
${CMAKE_CURRENT_LIST_DIR}/src/image_io_tiff.cpp
)

target_link_libraries(${COMPONENT} PUBLIC pango_core)
Expand Down
7 changes: 5 additions & 2 deletions components/pango_image/src/image_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ void SavePacked12bit(const Image<unsigned char>& image, const pangolin::PixelFor
// LibRaw raw camera files
TypedImage LoadLibRaw(const std::string& filename);

// TIFF
TypedImage LoadTiff(const std::string& filename);

TypedImage LoadImage(std::istream& in, ImageFileType file_type)
{
switch (file_type) {
Expand Down Expand Up @@ -118,9 +121,9 @@ TypedImage LoadImage(const std::string& filename, ImageFileType file_type)
case ImageFileTypePango:
return LoadPango(filename);
case ImageFileTypeArw:
[[fallthrough]];
case ImageFileTypeTiff:
return LoadLibRaw(filename);
case ImageFileTypeTiff:
return LoadTiff(filename);
default:
throw std::runtime_error("Unsupported image file type, '" + filename + "'");
}
Expand Down
78 changes: 78 additions & 0 deletions components/pango_image/src/image_io_tiff.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <cassert>
#include <pangolin/image/typed_image.h>

#ifdef HAVE_LIBTIFF
# include <tiffio.h>
#endif

namespace pangolin {

#ifdef HAVE_LIBTIFF
template<typename T>
T GetOrThrow(TIFF* tif, uint32_t tag)
{
T r;
if (TIFFGetField(tif, tag, &r) != 1) {
throw std::runtime_error("Expected tag missing when reading tiff (" + std::to_string(tag) + ")");
}
return r;
}

template<typename T>
T GetOrDefault(TIFF* tif, uint32_t tag, T default_val)
{
T r = default_val;
TIFFGetField(tif, tag, &r);
return r;
}
#endif

TypedImage LoadTiff(
const std::string& filename
) {
#ifdef HAVE_LIBTIFF
TIFF* tif = TIFFOpen(filename.c_str(),"r");
if (!tif) {
throw std::runtime_error("libtiff failed to open " + filename);
}

const auto width = GetOrThrow<uint32_t>(tif, TIFFTAG_IMAGEWIDTH);
const auto height = GetOrThrow<uint32_t>(tif, TIFFTAG_IMAGELENGTH);
const auto channels = GetOrThrow<uint16_t>(tif, TIFFTAG_SAMPLESPERPIXEL);
const auto bits_per_channel = GetOrThrow<uint16_t>(tif, TIFFTAG_BITSPERSAMPLE);
const auto sample_format = GetOrDefault<uint16_t>(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
const auto planar = GetOrThrow<uint16_t>(tif, TIFFTAG_PLANARCONFIG);
// const auto photom = GetOrThrow<uint16_t>(tif, TIFFTAG_PHOTOMETRIC);

assert(width >= 0 && height >= 0 && channels >= 0 && bits_per_channel > 0);

if(planar != PLANARCONFIG_CONTIG /*|| photom != PHOTOMETRIC_RGB*/ || bits_per_channel % 8 != 0 || !(channels == 1 || channels == 3))
throw std::runtime_error("TIFF support is currently limited. Consider contributing to image_io_tiff.cpp.");

std::string sfmt;
switch(sample_format) {
case SAMPLEFORMAT_UINT: sfmt = (channels == 3) ? "RGB24" : "GRAY8"; break;
case SAMPLEFORMAT_IEEEFP: sfmt = (channels == 3) ? "RGB96F" : "GRAY32F"; break;
default: throw std::runtime_error("TIFF support is currently limited. Consider contributing to image_io_tiff.cpp.");
}

TypedImage image(width, height, PixelFormatFromString(sfmt));
const tsize_t scanlength_bytes = TIFFScanlineSize(tif);
if(scanlength_bytes != image.pitch)
throw std::runtime_error("TIFF: unexpected scanline length");

for (size_t row = 0; row < height; ++row) {
TIFFReadScanline(tif, image.RowPtr(row), row);
}

TIFFClose(tif);

return image;
#else
PANGOLIN_UNUSED(filename);
throw std::runtime_error("Rebuild Pangolin for libtiff support.");
#endif
}

}

0 comments on commit bd61af1

Please sign in to comment.