Skip to content

Commit

Permalink
introduce "frame-of-reference" (#123)
Browse files Browse the repository at this point in the history
* Add coordinate systems documentation and diagram

Added a new documentation file `coordinate_systems.markdown` to the
Doxyfile's INPUT section. Introduced a "Coordinate Systems" section
in the new file with a header and placeholder description for CZI and
libCZI coordinate systems. Also, added a new diagram in
`coordinate_systems.drawio` named "Page-1" that includes graphical
elements representing a coordinate system with labeled axes.

* Update coordinate systems documentation in libCZI

* Improve documentation clarity for coordinate systems

Rephrased a sentence in `coordinate_systems.markdown` for clarity. Updated comments in `libCZI.h` to clarify bounding boxes and coordinate systems. Enhanced `libCZI_Compositor.h` comments to specify ROI and positions in the 'raw-subblock-coordinate-system'. Removed summary tags and redundant information to streamline documentation. These changes provide clearer and more precise descriptions of coordinate systems and bounding boxes in libCZI.

* Update project to version 0.62.7

Updated CMakeLists.txt to change project version from 0.62.6 to 0.62.7.
Added a new entry in version-history.markdown for version 0.62.7, documenting a "documentation update" linked to pull request #122.

* remove "high-res-bitmaps"

* wip

* fix table

* cosmetic

* Refactor coordinate transformation methods

Added TransformPoint to CCZIReader for point transformations.
Updated CZIReader.h to declare TransformPoint method.
Modified CSingleChannelTileAccessor::Get to use TransformRectangle.
Added TransformRectangle to ISubBlockRepository in libCZI.h.
Introduced IntPoint and IntPointAndFrameOfReference structures.
Removed ConvertToFrameOfReference function from libCZI_Utilities.
Minor formatting changes in libCZI.h and libCZI_Utilities.h.
Improved code design, readability, and maintainability.

* Update TransformPoint to return IntPointAndFrameOfReference

Updated TransformPoint method to return libCZI::IntPointAndFrameOfReference instead of libCZI::IntPoint. This change is reflected across various classes and interfaces, including CCZIReader, CziReaderWriter, and libCZI::ISubBlockRepository.

Added a new member variable default_frame_of_reference to CCZIReader and libCZI::Options to handle cases where the frame of reference is set to Default. Updated TransformRectangle method to handle the new return type of TransformPoint. Implemented changes in test_TileAccessorCoverageOptimization.cpp to reflect the new return type.

* Add frame of reference handling and related tests

- Initialize `default_frame_of_reference` to `CZIFrameOfReference::Invalid` in `CCZIReader` constructor.
- Update `CCZIReader::Open` to use a switch statement for `options->default_frame_of_reference`.
- Modify `ISubBlockRepository::TransformRectangle` to return `IntRectAndFrameOfReference`.
- Update `CSingleChannelTileAccessor::Get` to use the `rectangle` member of `IntRectAndFrameOfReference`.
- Add `test_frame_of_reference_transform.cpp` with tests for point and rectangle transformations.
- Include new test file in `libCZI_UnitTests` target in `CMakeLists.txt`.

* linter

* cosmetic

* Refactor TransformPoint and add new tests

Refactored `CCZIReader::TransformPoint` for robust frame-of-reference transformations. Updated `AccessorType` enum in `libCZI_Compositor.h` to use `std::uint8_t`. Corrected typo in `backGroundColor` comment. Added `Check2x2Gray8Bitmap` function and new tests in `test_frame_of_reference_transform.cpp` for point transformations and tile composite verification.

* Add TransformPoint method and default frame of reference

Implemented TransformPoint in CCziReaderWriter for frame-of-reference transformations. Added GetDefaultFrameOfReference method and updated ICziReaderWriterInfo interface. Fixed formatting issues and improved type safety. Added test case for TransformPoint. Updated documentation and constructor initialization. Handled unsupported transformations with exceptions.

* Update bounding-box and transformation expectations

Updated the comment to reflect the correct bounding-box (0, -1, 1, 1) and transformation result (0, -1) after removing subblocks. Adjusted the test assertion for the y-coordinate of the transformed point to expect -1 instead of 0.

* Refactor and cleanup in SingleChannelTileAccessor

Modified the constructor in SingleChannelTileAccessor.cpp to make
roi_raw_sub_block_cs a const IntRect, ensuring immutability.
Removed a commented-out Get method declaration in
SingleChannelTileAccessor.h for improved readability.

* Refactor to use IntPointAndFrameOfReference type

Updated method signatures in SingleChannelTileAccessor.cpp and .h to use IntPointAndFrameOfReference instead of separate xPos and yPos parameters. Adjusted libCZI_Compositor.h to reflect these changes and added inline methods for backward compatibility. Updated ISingleChannelTileAccessor destructor to use override keyword for modern C++ standards adherence.

* linter

* Improve comment formatting in Z-order description

Added a space after the period in the comment describing the Z-order behavior when `sortByM` is false. This change enhances readability and consistency of the comments in the codebase.

* Refactor Get methods and update documentation

- Updated `Get` methods in `CSingleChannelScalingTileAccessor` and `libCZI::ISingleChannelScalingTileAccessor` to use `IntRectAndFrameOfReference` instead of `IntRect`.
- Added overloads to handle `IntRect` by converting to `IntRectAndFrameOfReference`.
- Modified `InternalCalcSize` to use the transformed rectangle in the raw sub-block coordinate system.
- Corrected typo in `Options` struct documentation ("back ground color" to "background color").
- Updated `SingleChannelScalingTileAccessorHandler` in `test_TileAccessorCoverageOptimization.cpp` to use a shared pointer to `ISingleChannelScalingTileAccessor`.
- Added documentation to `libCZI::ISingleChannelScalingTileAccessor` interface for new `Get` methods and their parameters.

* Refactor coordinate handling to use explicit frames

Updated SingleChannelPyramidLevelTileAccessor to use IntRectAndFrameOfReference and IntPointAndFrameOfReference for coordinates, ensuring explicit frame of reference handling. Transformed input coordinates to RawSubBlockCoordinateSystem in Get methods for consistency. Updated InternalGet method accordingly. Modified libCZI_Compositor.h to reflect new method signatures and retained old methods with internal transformations. Improved clarity and correctness of coordinate handling.

* Refactor ROI coordinate calculation and formatting

Updated ROI calculation to use boundingBoxLayer0Only instead of boundingBox for relative coordinates in execute.cpp and executeBase.cpp. Applied consistent changes across multiple sections. Added spaces after commas in ROI initialization for better readability.

* Update project to version 0.63.0

Updated CMakeLists.txt to change project version from 0.62.7 to 0.63.0.
Added a new entry in version-history.markdown for version 0.63.0, documenting the introduction of "frames-of-reference". The entry for version 0.62.7 remains unchanged.

* add documentation

* fix typos

* Update Src/CZICmd/execute.cpp

Co-authored-by: m-aXimilian <[email protected]>

* Update Src/libCZI/libCZI_ReadWrite.h

Co-authored-by: m-aXimilian <[email protected]>

* Simplify return statements with brace-enclosed initializer

Simplified the return statements in two conditional blocks by removing the explicit type `libCZI::IntPointAndFrameOfReference` and using the brace-enclosed initializer list directly. This change makes the code more concise and leverages the compiler's ability to deduce the return type.

---------

Co-authored-by: m-aXimilian <[email protected]>
  • Loading branch information
ptahmose and m-aXimilian authored Dec 13, 2024
1 parent ae43e1b commit 1127eb0
Show file tree
Hide file tree
Showing 22 changed files with 764 additions and 104 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW) # enable new "MSVC runtime library selection" (https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html)

project(libCZI
VERSION 0.62.7
VERSION 0.63.0
HOMEPAGE_URL "https://github.com/ZEISS/libczi"
DESCRIPTION "libCZI is an Open Source Cross-Platform C++ library to read and write CZI")

Expand Down
14 changes: 7 additions & 7 deletions Src/CZICmd/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,12 +556,12 @@ class CExecuteSingleChannelTileAccessor : CExecuteBase
sctaOptions.sceneFilter = options.GetSceneIndexSet();
sctaOptions.useVisibilityCheckOptimization = options.GetUseVisibilityCheckOptimization();

IntRect roi{ options.GetRectX() ,options.GetRectY(),options.GetRectW(),options.GetRectH() };
IntRect roi{ options.GetRectX(), options.GetRectY(), options.GetRectW(), options.GetRectH() };
if (options.GetIsRelativeRectCoordinate())
{
auto statistics = spReader->GetStatistics();
roi.x += statistics.boundingBox.x;
roi.y += statistics.boundingBox.y;
roi.x += statistics.boundingBoxLayer0Only.x;
roi.y += statistics.boundingBoxLayer0Only.y;
}

auto re = accessor->Get(roi, &coordinate, &sctaOptions);
Expand Down Expand Up @@ -676,8 +676,8 @@ class CExecuteChannelComposite : CExecuteBase
IntRect roi{ options.GetRectX() ,options.GetRectY() ,options.GetRectW(),options.GetRectH() };
if (options.GetIsRelativeRectCoordinate())
{
roi.x += subBlockStatistics.boundingBox.x;
roi.y += subBlockStatistics.boundingBox.y;
roi.x += subBlockStatistics.boundingBoxLayer0Only.x;
roi.y += subBlockStatistics.boundingBoxLayer0Only.y;
}

auto accessor = reader->CreateSingleChannelTileAccessor();
Expand Down Expand Up @@ -861,8 +861,8 @@ class CExecuteScalingChannelComposite : CExecuteBase
IntRect roi{ options.GetRectX() ,options.GetRectY() ,options.GetRectW(),options.GetRectH() };
if (options.GetIsRelativeRectCoordinate())
{
roi.x += subBlockStatistics.boundingBox.x;
roi.y += subBlockStatistics.boundingBox.y;
roi.x += subBlockStatistics.boundingBoxLayer0Only.x;
roi.y += subBlockStatistics.boundingBoxLayer0Only.y;
}

auto accessor = reader->CreateSingleChannelScalingTileAccessor();
Expand Down
4 changes: 2 additions & 2 deletions Src/CZICmd/executeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ IntRect CExecuteBase::GetRoiFromOptions(const CCmdLineOptions& options, const Su
IntRect roi{ options.GetRectX(), options.GetRectY(), options.GetRectW(), options.GetRectH() };
if (options.GetIsRelativeRectCoordinate())
{
roi.x += subBlockStatistics.boundingBox.x;
roi.y += subBlockStatistics.boundingBox.y;
roi.x += subBlockStatistics.boundingBoxLayer0Only.x;
roi.y += subBlockStatistics.boundingBoxLayer0Only.y;
}

return roi;
Expand Down
69 changes: 66 additions & 3 deletions Src/libCZI/CZIReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static CCZIParse::SubblockDirectoryParseOptions GetParseOptionsFromOpenOptions(c
return parse_options;
}

CCZIReader::CCZIReader() : isOperational(false)
CCZIReader::CCZIReader() : isOperational(false), default_frame_of_reference(CZIFrameOfReference::Invalid)
{
}

Expand Down Expand Up @@ -60,6 +60,17 @@ CCZIReader::CCZIReader() : isOperational(false)
}

this->stream = stream;
switch (options->default_frame_of_reference)
{
case CZIFrameOfReference::Invalid:
case CZIFrameOfReference::Default:
this->default_frame_of_reference = CZIFrameOfReference::RawSubBlockCoordinateSystem;
break;
default:
this->default_frame_of_reference = options->default_frame_of_reference;
break;
}

this->SetOperationalState(true);
}

Expand Down Expand Up @@ -96,6 +107,58 @@ CCZIReader::CCZIReader() : isOperational(false)
return this->subBlkDir.GetPyramidStatistics();
}

/*virtual*/libCZI::IntPointAndFrameOfReference CCZIReader::TransformPoint(const libCZI::IntPointAndFrameOfReference& source_point, libCZI::CZIFrameOfReference destination_frame_of_reference)
{
CZIFrameOfReference source_frame_of_reference_consolidated;
switch (source_point.frame_of_reference)
{
case CZIFrameOfReference::RawSubBlockCoordinateSystem:
case CZIFrameOfReference::PixelCoordinateSystem:
source_frame_of_reference_consolidated = source_point.frame_of_reference;
break;
case CZIFrameOfReference::Default:
source_frame_of_reference_consolidated = this->default_frame_of_reference;
break;
default:
throw invalid_argument("Unsupported frame-of-reference.");
}

CZIFrameOfReference destination_frame_of_reference_consolidated;
switch (destination_frame_of_reference)
{
case CZIFrameOfReference::RawSubBlockCoordinateSystem:
case CZIFrameOfReference::PixelCoordinateSystem:
destination_frame_of_reference_consolidated = destination_frame_of_reference;
break;
case CZIFrameOfReference::Default:
destination_frame_of_reference_consolidated = this->default_frame_of_reference;
break;
default:
throw invalid_argument("Unsupported frame-of-reference.");
}

if (destination_frame_of_reference_consolidated == source_frame_of_reference_consolidated)
{
return { source_frame_of_reference_consolidated, source_point.point };
}

if (source_frame_of_reference_consolidated == CZIFrameOfReference::PixelCoordinateSystem &&
destination_frame_of_reference_consolidated == CZIFrameOfReference::RawSubBlockCoordinateSystem)
{
const auto& statistics = this->subBlkDir.GetStatistics();
return { CZIFrameOfReference::RawSubBlockCoordinateSystem, {source_point.point.x + statistics.boundingBoxLayer0Only.x, source_point.point.y + statistics.boundingBoxLayer0Only.y} };
}

if (source_frame_of_reference_consolidated == CZIFrameOfReference::RawSubBlockCoordinateSystem &&
destination_frame_of_reference_consolidated == CZIFrameOfReference::PixelCoordinateSystem)
{
const auto& statistics = this->subBlkDir.GetStatistics();
return { CZIFrameOfReference::PixelCoordinateSystem, {source_point.point.x - statistics.boundingBoxLayer0Only.x, source_point.point.y - statistics.boundingBoxLayer0Only.y} };
}

throw logic_error("Unsupported frame-of-reference transformation.");
}

/*virtual*/void CCZIReader::EnumerateSubBlocks(const std::function<bool(int index, const SubBlockInfo& info)>& funcEnum)
{
this->ThrowIfNotOperational();
Expand Down Expand Up @@ -205,8 +268,8 @@ CCZIReader::CCZIReader() : isOperational(false)
this->ThrowIfNotOperational();
CziReaderCommon::EnumerateSubset(
std::bind(&CCziAttachmentsDirectory::EnumAttachments, &this->attachmentDir, std::placeholders::_1),
contentFileType,
name,
contentFileType,
name,
funcEnum);
}

Expand Down
2 changes: 2 additions & 0 deletions Src/libCZI/CZIReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class CCZIReader : public libCZI::ICZIReader, public std::enable_shared_from_thi
CCziSubBlockDirectory subBlkDir;
CCziAttachmentsDirectory attachmentDir;
bool isOperational; ///< If true, then stream, hdrSegmentData and subBlkDir can be considered valid and operational
libCZI::CZIFrameOfReference default_frame_of_reference;
public:
CCZIReader();
~CCZIReader() override = default;
Expand All @@ -33,6 +34,7 @@ class CCZIReader : public libCZI::ICZIReader, public std::enable_shared_from_thi
bool TryGetSubBlockInfo(int index, libCZI::SubBlockInfo* info) const override;
libCZI::SubBlockStatistics GetStatistics() override;
libCZI::PyramidStatistics GetPyramidStatistics() override;
libCZI::IntPointAndFrameOfReference TransformPoint(const libCZI::IntPointAndFrameOfReference& source_point, libCZI::CZIFrameOfReference destination_frame_of_reference) override;

// interface ISubBlockRepositoryEx
void EnumerateSubBlocksEx(const std::function<bool(int index, const libCZI::DirectorySubBlockInfo& info)>& funcEnum) override;
Expand Down
80 changes: 73 additions & 7 deletions Src/libCZI/CziReaderWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ struct ReplaceHelper
int key;
ICziReaderWriter* t;
ReplaceHelper(int key, ICziReaderWriter* t)
:key(key), t(t) {}
:key(key), t(t)
{}

void operator()(const AddSubBlockInfo& addSbBlkInfo) const
{
Expand All @@ -60,17 +61,17 @@ void ICziReaderWriter::SyncAddSubBlock(const libCZI::AddSubBlockInfoStridedBitma
void ICziReaderWriter::ReplaceSubBlock(int key, const libCZI::AddSubBlockInfoMemPtr& addSbBlkInfoMemPtr)
{
struct ReplaceHelper f(key, this);
AddSubBlockHelper::SyncAddSubBlock<ReplaceHelper >(f, addSbBlkInfoMemPtr);
AddSubBlockHelper::SyncAddSubBlock<ReplaceHelper>(f, addSbBlkInfoMemPtr);
}
void ICziReaderWriter::ReplaceSubBlock(int key, const libCZI::AddSubBlockInfoLinewiseBitmap& addSbInfoLinewise)
{
struct ReplaceHelper f(key, this);
AddSubBlockHelper::SyncAddSubBlock<ReplaceHelper >(f, addSbInfoLinewise);
AddSubBlockHelper::SyncAddSubBlock<ReplaceHelper>(f, addSbInfoLinewise);
}
void ICziReaderWriter::ReplaceSubBlock(int key, const libCZI::AddSubBlockInfoStridedBitmap& addSbBlkInfoStrideBitmap)
{
struct ReplaceHelper f(key, this);
AddSubBlockHelper::SyncAddSubBlock<ReplaceHelper >(f, addSbBlkInfoStrideBitmap);
AddSubBlockHelper::SyncAddSubBlock<ReplaceHelper>(f, addSbBlkInfoStrideBitmap);
}

//--------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -335,7 +336,7 @@ void CCziReaderWriter::Finish()

void CCziReaderWriter::UpdateFileHeader()
{
FileHeaderSegment fhs = { 0 };
FileHeaderSegment fhs = {};

fhs.header.AllocatedSize = fhs.header.UsedSize = sizeof(fhs.data);
memcpy(&fhs.header.Id, &CCZIParse::FILEHDRMAGIC, 16);
Expand Down Expand Up @@ -430,7 +431,7 @@ void CCziReaderWriter::ReadCziStructure()
else
{
// if there is no valid CZI-file-header, we now write one
FileHeaderSegment fhs = { 0 };
FileHeaderSegment fhs = {};
fhs.header.AllocatedSize = fhs.header.UsedSize = sizeof(fhs.data);
memcpy(&fhs.header.Id, &CCZIParse::FILEHDRMAGIC, 16);

Expand Down Expand Up @@ -489,7 +490,7 @@ void CCziReaderWriter::DetermineNextSubBlockOffset()
this->attachmentDirectory.EnumEntries(
[&](size_t index, const CCziAttachmentsDirectoryBase::AttachmentEntry& attEntry)->bool
{
if (uint64_t(attEntry.FilePosition) > lastSegmentPos)
if (static_cast<uint64_t>(attEntry.FilePosition) > lastSegmentPos)
{
lastSegmentPos = attEntry.FilePosition;
}
Expand Down Expand Up @@ -712,6 +713,58 @@ void CCziReaderWriter::WriteToOutputStream(std::uint64_t offset, const void* pv,
return this->sbBlkDirectory.GetPyramidStatistics();
}

/*virtual*/libCZI::IntPointAndFrameOfReference CCziReaderWriter::TransformPoint(const libCZI::IntPointAndFrameOfReference& source_point, libCZI::CZIFrameOfReference destination_frame_of_reference)
{
CZIFrameOfReference source_frame_of_reference_consolidated;
switch (source_point.frame_of_reference)
{
case CZIFrameOfReference::RawSubBlockCoordinateSystem:
case CZIFrameOfReference::PixelCoordinateSystem:
source_frame_of_reference_consolidated = source_point.frame_of_reference;
break;
case CZIFrameOfReference::Default:
source_frame_of_reference_consolidated = this->GetDefaultFrameOfReference();
break;
default:
throw invalid_argument("Unsupported frame-of-reference.");
}

CZIFrameOfReference destination_frame_of_reference_consolidated;
switch (destination_frame_of_reference)
{
case CZIFrameOfReference::RawSubBlockCoordinateSystem:
case CZIFrameOfReference::PixelCoordinateSystem:
destination_frame_of_reference_consolidated = destination_frame_of_reference;
break;
case CZIFrameOfReference::Default:
destination_frame_of_reference_consolidated = this->GetDefaultFrameOfReference();
break;
default:
throw invalid_argument("Unsupported frame-of-reference.");
}

if (destination_frame_of_reference_consolidated == source_frame_of_reference_consolidated)
{
return { source_frame_of_reference_consolidated, source_point.point };
}

if (source_frame_of_reference_consolidated == CZIFrameOfReference::PixelCoordinateSystem &&
destination_frame_of_reference_consolidated == CZIFrameOfReference::RawSubBlockCoordinateSystem)
{
const auto& statistics = this->GetStatistics();
return libCZI::IntPointAndFrameOfReference{ CZIFrameOfReference::RawSubBlockCoordinateSystem, {source_point.point.x + statistics.boundingBoxLayer0Only.x, source_point.point.y + statistics.boundingBoxLayer0Only.y} };
}

if (source_frame_of_reference_consolidated == CZIFrameOfReference::RawSubBlockCoordinateSystem &&
destination_frame_of_reference_consolidated == CZIFrameOfReference::PixelCoordinateSystem)
{
const auto& statistics = this->GetStatistics();
return libCZI::IntPointAndFrameOfReference{ CZIFrameOfReference::PixelCoordinateSystem, {source_point.point.x - statistics.boundingBoxLayer0Only.x, source_point.point.y - statistics.boundingBoxLayer0Only.y} };
}

throw logic_error("Unsupported frame-of-reference transformation.");
}

/*virtual*/void CCziReaderWriter::EnumerateAttachments(const std::function<bool(int index, const libCZI::AttachmentInfo& info)>& funcEnum)
{
this->ThrowIfNotOperational();
Expand Down Expand Up @@ -874,3 +927,16 @@ void CCziReaderWriter::ThrowIfAlreadyInitialized() const
throw logic_error("CCziReaderWriter is already operational.");
}
}

libCZI::CZIFrameOfReference CCziReaderWriter::GetDefaultFrameOfReference() const
{
const auto default_frame_of_reference_from_info = this->info->GetDefaultFrameOfReference();
switch (default_frame_of_reference_from_info)
{
case CZIFrameOfReference::RawSubBlockCoordinateSystem:
case CZIFrameOfReference::PixelCoordinateSystem:
return default_frame_of_reference_from_info;
default:
return CZIFrameOfReference::RawSubBlockCoordinateSystem;
}
}
2 changes: 2 additions & 0 deletions Src/libCZI/CziReaderWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class CCziReaderWriter : public libCZI::ICziReaderWriter
bool TryGetSubBlockInfo(int index, libCZI::SubBlockInfo* info) const override;
libCZI::SubBlockStatistics GetStatistics() override;
libCZI::PyramidStatistics GetPyramidStatistics() override;
libCZI::IntPointAndFrameOfReference TransformPoint(const libCZI::IntPointAndFrameOfReference& source_point, libCZI::CZIFrameOfReference destination_frame_of_reference) override;

// interface IAttachmentRepository
void EnumerateAttachments(const std::function<bool(int index, const libCZI::AttachmentInfo& info)>& funcEnum) override;
Expand Down Expand Up @@ -80,6 +81,7 @@ class CCziReaderWriter : public libCZI::ICziReaderWriter
void UpdateFileHeader();
void ThrowIfNotOperational() const;
void ThrowIfAlreadyInitialized() const;
libCZI::CZIFrameOfReference GetDefaultFrameOfReference() const;
private:
class CNextSegment
{
Expand Down
3 changes: 2 additions & 1 deletion Src/libCZI/Doc/version-history.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ version history {#version_history}
0.62.4 | [117](https://github.com/ZEISS/libczi/pull/117) | fix build with private RapidJSON library
0.62.5 | [119](https://github.com/ZEISS/libczi/pull/119) | fix a discrepancy between code and documentation
0.62.6 | [120](https://github.com/ZEISS/libczi/pull/120) | fix workload identity in the azure blob inputstream
0.62.7 | [122](https://github.com/ZEISS/libczi/pull/122) | documentation update
0.62.7 | [122](https://github.com/ZEISS/libczi/pull/122) | documentation update
0.63.0 | [123](https://github.com/ZEISS/libczi/pull/123) | introduce "frames-of-reference"
16 changes: 9 additions & 7 deletions Src/libCZI/SingleChannelPyramidLevelTileAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ CSingleChannelPyramidLevelTileAccessor::CSingleChannelPyramidLevelTileAccessor(c
{
}

/*virtual*/std::shared_ptr<libCZI::IBitmapData> CSingleChannelPyramidLevelTileAccessor::Get(const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, const PyramidLayerInfo& pyramidInfo, const ISingleChannelPyramidLayerTileAccessor::Options* pOptions)
/*virtual*/std::shared_ptr<libCZI::IBitmapData> CSingleChannelPyramidLevelTileAccessor::Get(const libCZI::IntRectAndFrameOfReference& roi, const libCZI::IDimCoordinate* planeCoordinate, const PyramidLayerInfo& pyramidInfo, const ISingleChannelPyramidLayerTileAccessor::Options* pOptions)
{
if (pOptions == nullptr)
{
Expand All @@ -34,7 +34,7 @@ CSingleChannelPyramidLevelTileAccessor::CSingleChannelPyramidLevelTileAccessor(c
return this->Get(pixelType, roi, planeCoordinate, pyramidInfo, pOptions);
}

/*virtual*/std::shared_ptr<libCZI::IBitmapData> CSingleChannelPyramidLevelTileAccessor::Get(libCZI::PixelType pixeltype, const libCZI::IntRect& roi, const libCZI::IDimCoordinate* planeCoordinate, const PyramidLayerInfo& pyramidInfo, const libCZI::ISingleChannelPyramidLayerTileAccessor::Options* pOptions)
/*virtual*/std::shared_ptr<libCZI::IBitmapData> CSingleChannelPyramidLevelTileAccessor::Get(libCZI::PixelType pixeltype, const libCZI::IntRectAndFrameOfReference& roi, const libCZI::IDimCoordinate* planeCoordinate, const PyramidLayerInfo& pyramidInfo, const libCZI::ISingleChannelPyramidLayerTileAccessor::Options* pOptions)
{
if (pOptions == nullptr)
{
Expand All @@ -43,31 +43,33 @@ CSingleChannelPyramidLevelTileAccessor::CSingleChannelPyramidLevelTileAccessor(c
return this->Get(pixeltype, roi, planeCoordinate, pyramidInfo, &opt);
}

const IntRect roi_raw_sub_block_cs = this->sbBlkRepository->TransformRectangle(roi, CZIFrameOfReference::RawSubBlockCoordinateSystem).rectangle;
const int sizeOfPixel = CalcSizeOfPixelOnLayer0(pyramidInfo);
const IntSize sizeOfBitmap{ static_cast<std::uint32_t>(roi.w / sizeOfPixel),static_cast<std::uint32_t>(roi.h / sizeOfPixel) };
const IntSize sizeOfBitmap{ static_cast<std::uint32_t>(roi_raw_sub_block_cs.w / sizeOfPixel),static_cast<std::uint32_t>(roi_raw_sub_block_cs.h / sizeOfPixel) };
if (sizeOfBitmap.w == 0 || sizeOfBitmap.h == 0)
{
// TODO
throw runtime_error("error");
}

auto bmDest = GetSite()->CreateBitmap(pixeltype, sizeOfBitmap.w, sizeOfBitmap.h);
this->InternalGet(bmDest.get(), roi.x, roi.y, sizeOfPixel, planeCoordinate, pyramidInfo, *pOptions);
this->InternalGet(bmDest.get(), roi_raw_sub_block_cs.x, roi_raw_sub_block_cs.y, sizeOfPixel, planeCoordinate, pyramidInfo, *pOptions);
return bmDest;
}

/*virtual*/void CSingleChannelPyramidLevelTileAccessor::Get(libCZI::IBitmapData* pDest, int xPos, int yPos, const libCZI::IDimCoordinate* planeCoordinate, const PyramidLayerInfo& pyramidInfo, const Options* pOptions)
/*virtual*/void CSingleChannelPyramidLevelTileAccessor::Get(libCZI::IBitmapData* pDest, const libCZI::IntPointAndFrameOfReference& position, const libCZI::IDimCoordinate* planeCoordinate, const PyramidLayerInfo& pyramidInfo, const Options* pOptions)
{
if (pOptions == nullptr)
{
Options opt;
opt.Clear();
this->Get(pDest, xPos, yPos, planeCoordinate, pyramidInfo, &opt);
this->Get(pDest, position, planeCoordinate, pyramidInfo, &opt);
return;
}

const IntPoint point_raw_sub_block_cs = this->sbBlkRepository->TransformPoint(position, CZIFrameOfReference::RawSubBlockCoordinateSystem).point;
const int sizeOfPixel = CalcSizeOfPixelOnLayer0(pyramidInfo);
this->InternalGet(pDest, xPos, yPos, sizeOfPixel, planeCoordinate, pyramidInfo, *pOptions);
this->InternalGet(pDest, point_raw_sub_block_cs.x, point_raw_sub_block_cs.y, sizeOfPixel, planeCoordinate, pyramidInfo, *pOptions);
}

void CSingleChannelPyramidLevelTileAccessor::InternalGet(libCZI::IBitmapData* pDest, int xPos, int yPos, int sizeOfPixelOnLayer0, const libCZI::IDimCoordinate* planeCoordinate, const PyramidLayerInfo& pyramidInfo, const Options& options)
Expand Down
Loading

0 comments on commit 1127eb0

Please sign in to comment.