Skip to content

Commit

Permalink
TIFFIO: Fix memmap endianness issues (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
csparker247 authored Oct 18, 2024
1 parent f3df583 commit 08e5c9a
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 9 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ jobs:
run: |
sudo xcode-select -s /Library/Developer/CommandLineTools
- name: Remove problematic SDKs
run: |
sudo rm -rf /Library/Developer/CommandLineTools/SDKs/MacOSX15*.sdk
- name: Install dependencies
run: |
brew bundle
Expand Down
7 changes: 5 additions & 2 deletions apps/src/Packager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct VolumeInfo {
Flip flipOption{Flip::None};
vc::Metadata meta;
bool compress{false};
bool forceWrite{false};
};

static bool DoAnalyze{true};
Expand Down Expand Up @@ -99,7 +100,8 @@ auto main(int argc, char* argv[]) -> int

po::options_description all("Usage");
all.add(helpOpts).add_options()(
"analyze", po::value<bool>()->default_value(true), "Analyze volume");
"analyze", po::value<bool>()->default_value(true), "Analyze volume")
("force-write", "Force writing new TIFF files even if they could be copied");
// clang-format on

// Parse the command line and separate out flags for volumes
Expand Down Expand Up @@ -194,6 +196,7 @@ auto main(int argc, char* argv[]) -> int
///// Add Volumes /////
for (const auto& v : vargs) {
VolumeInfo info = GetVolumeInfo(v);
info.forceWrite = args.count("force-write") > 0;
AddVolume(volpkg, info);
}
}
Expand Down Expand Up @@ -475,7 +478,7 @@ void AddVolume(vc::VolumePkg::Pointer& volpkg, const VolumeInfo& info)
auto& slice = pair.second;
// Convert or flip
if (slice.needsConvert() || slice.needsScale() || needsFlip ||
info.compress) {
info.compress || info.forceWrite) {
// Override slice min/max with volume min/max
if (slice.needsScale()) {
slice.setScale(volMax, volMin);
Expand Down
9 changes: 9 additions & 0 deletions core/include/vc/core/util/MemMap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
namespace volcart
{

namespace endian
{
/** Returns whether the system is little endian */
auto little() -> bool;

/** Returns whether the system is big endian */
auto big() -> bool;
} // namespace endian

/** @brief Memmap record */
struct mmap_info {
/** Whether this is a valid mapping */
Expand Down
8 changes: 8 additions & 0 deletions core/src/MemMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
namespace vc = volcart;
namespace fs = vc::filesystem;

auto vc::endian::little() -> bool
{
constexpr int i{1};
return *reinterpret_cast<const char*>(&i) == 1;
}

auto vc::endian::big() -> bool { return not little(); }

vc::mmap_info::operator bool() const { return addr and size > 0; }

vc::auto_mmap_info::auto_mmap_info(const mmap_info& rhs) : mmap_info(rhs) {}
Expand Down
18 changes: 11 additions & 7 deletions core/src/TIFFIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct TIFFHeader {
std::uint16_t config = 0;
std::uint64_t* stripOffsets{nullptr};
tio::Compression compression{tio::Compression::NONE};
bool bigEndian{false};
};

auto ReadHeader(lt::TIFF* tif)
Expand All @@ -95,6 +96,7 @@ auto ReadHeader(lt::TIFF* tif)
TIFFGetField(tif, TIFFTAG_COMPRESSION, &hdr.compression);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &hdr.rowsPerStrip);
TIFFGetField(tif, TIFFTAG_STRIPOFFSETS, &hdr.stripOffsets);
hdr.bigEndian = lt::TIFFIsBigEndian(tif) != 0;
return hdr;
}

Expand Down Expand Up @@ -144,13 +146,15 @@ auto ReadImage(lt::TIFF* tif, const TIFFHeader& hdr) -> cv::Mat
// Returns whether this TIFF file is encoded for memory mapping
auto CanMMap(const TIFFHeader& hdr) -> bool
{
auto res = hdr.config == PLANARCONFIG_CONTIG;
res &= hdr.type == SAMPLEFORMAT_UINT;
res &= hdr.depth == 16 and hdr.channels == 1;
res &= hdr.compression == tio::Compression::NONE;
// important: full image is in a single strip
res &= hdr.rowsPerStrip == hdr.height;
return res;
const auto isContig = hdr.config == PLANARCONFIG_CONTIG;
const auto isUint = hdr.type == SAMPLEFORMAT_UINT;
const auto is16bpc = hdr.depth == 16;
const auto isMono = hdr.channels == 1;
const auto uncompressed = hdr.compression == tio::Compression::NONE;
const auto singleStrip = hdr.rowsPerStrip == hdr.height;
const auto endianMatch = hdr.bigEndian == vc::endian::big();
return isContig and isUint and is16bpc and isMono and uncompressed and
singleStrip and endianMatch;
}

// Memory mapp the tiff
Expand Down

0 comments on commit 08e5c9a

Please sign in to comment.