Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some fixes for readerwriter #95

Merged
merged 25 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
964185b
clang-tidy fixes
ptahmose Feb 16, 2023
c3d0b08
cosmetic
ptahmose Feb 17, 2023
52059d7
Merge branch 'main' of https://github.com/ptahmose/libczi-zeiss
ptahmose Jul 30, 2023
1f11468
Merge branch 'main' of https://github.com/ptahmose/libczi-zeiss
ptahmose Oct 30, 2023
94bdc16
Merge branch 'ZEISS:main' into main
ptahmose Nov 2, 2023
09d3d84
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Nov 3, 2023
c9858ae
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Nov 6, 2023
0418230
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Nov 18, 2023
ed654c9
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Nov 20, 2023
ab75b94
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Nov 22, 2023
9877f58
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Dec 9, 2023
8cea702
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Dec 12, 2023
9d9ea2b
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Dec 30, 2023
0deb3a6
Merge branch 'main' of github.com:ptahmose/libczi-zeiss
ptahmose Feb 9, 2024
7345030
some fixes for czireaderwriter
ptahmose Feb 10, 2024
a341b3e
bump version
ptahmose Feb 10, 2024
bcac932
fix link
ptahmose Feb 10, 2024
50ec6a5
implement some missing methods
ptahmose Feb 11, 2024
764db70
update
ptahmose Feb 11, 2024
9904b8b
clean up CZIReader.cpp
ptahmose Feb 11, 2024
8d270fb
add unittests for newly implemented methods of CziReaderWriter
ptahmose Feb 11, 2024
3b7c66f
cosmetic
ptahmose Feb 11, 2024
9e2843c
cosmetic
ptahmose Feb 11, 2024
cb591c2
linter
ptahmose Feb 11, 2024
15e7198
formatting...
ptahmose Feb 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.58.0
VERSION 0.58.1
HOMEPAGE_URL "https://github.com/ZEISS/libczi"
DESCRIPTION "libCZI is an Open Source Cross-Platform C++ library to read and write CZI")

Expand Down
2 changes: 2 additions & 0 deletions Src/libCZI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set(LIBCZISRCFILES
CziMetadataSegment.cpp
CziParse.cpp
CZIReader.cpp
CziReaderCommon.cpp
CziReaderWriter.cpp
CziStructs.cpp
CziSubBlock.cpp
Expand Down Expand Up @@ -60,6 +61,7 @@ set(LIBCZISRCFILES
CziMetadataDocumentInfo2.h
CziMetadataSegment.h
CziParse.h
CziReaderCommon.h
CZIReader.h
CziReaderWriter.h
CziStructs.h
Expand Down
104 changes: 10 additions & 94 deletions Src/libCZI/CZIReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "CziUtils.h"
#include "utilities.h"
#include "CziAttachment.h"
#include "CziReaderCommon.h"

using namespace std;
using namespace libCZI;
Expand Down Expand Up @@ -101,15 +102,7 @@
this->subBlkDir.EnumSubBlocks(
[&](int index, const CCziSubBlockDirectory::SubBlkEntry& entry)->bool
{
SubBlockInfo info;
info.compressionModeRaw = entry.Compression;
info.pixelType = CziUtils::PixelTypeFromInt(entry.PixelType);
info.coordinate = entry.coordinate;
info.logicalRect = IntRect{ entry.x,entry.y,entry.width,entry.height };
info.physicalSize = IntSize{ (std::uint32_t)entry.storedWidth, (std::uint32_t)entry.storedHeight };
info.mIndex = entry.mIndex;
info.pyramidType = CziUtils::PyramidTypeFromByte(entry.pyramid_type_from_spare);
return funcEnum(index, info);
return funcEnum(index, CziReaderCommon::ConvertToSubBlockInfo(entry));
});
}

Expand All @@ -135,30 +128,7 @@
/*virtual*/void CCZIReader::EnumSubset(const IDimCoordinate* planeCoordinate, const IntRect* roi, bool onlyLayer0, const std::function<bool(int index, const SubBlockInfo& info)>& funcEnum)
{
this->ThrowIfNotOperational();

// TODO:
// Ok... for a first tentative, experimental and quick-n-dirty implementation, simply
// walk through all the subblocks. We surely want to have something more elaborated
// here.
this->EnumerateSubBlocks(
[&](int index, const SubBlockInfo& info)->bool
{
// TODO: we only deal with layer 0 currently... or, more precisely, we do not take "zoom" into account at all
// -> well... added that boolean "onlyLayer0" - is this sufficient...?
if (onlyLayer0 == false || (info.physicalSize.w == info.logicalRect.w && info.physicalSize.h == info.logicalRect.h))
{
if (planeCoordinate == nullptr || CziUtils::CompareCoordinate(planeCoordinate, &info.coordinate) == true)
{
if (roi == nullptr || Utilities::DoIntersect(*roi, info.logicalRect))
{
bool b = funcEnum(index, info);
return b;
}
}
}

return true;
});
CziReaderCommon::EnumSubset(this, planeCoordinate, roi, onlyLayer0, funcEnum);
}

/*virtual*/std::shared_ptr<ISubBlock> CCZIReader::ReadSubBlock(int index)
Expand All @@ -176,41 +146,7 @@
/*virtual*/bool CCZIReader::TryGetSubBlockInfoOfArbitrarySubBlockInChannel(int channelIndex, SubBlockInfo& info)
{
this->ThrowIfNotOperational();

// TODO: we should be able to gather this information when constructing the subblock-list
// for the time being... just walk through the whole list
//
bool foundASubBlock = false;
SubBlockStatistics s = this->subBlkDir.GetStatistics();
if (!s.dimBounds.IsValid(DimensionIndex::C))
{
// in this case -> just take the first subblock...
this->EnumerateSubBlocks(
[&](int index, const SubBlockInfo& sbinfo)->bool
{
info = sbinfo;
foundASubBlock = true;
return false;
});
}
else
{
this->EnumerateSubBlocks(
[&](int index, const SubBlockInfo& sbinfo)->bool
{
int c;
if (sbinfo.coordinate.TryGetPosition(DimensionIndex::C, &c) == true && c == channelIndex)
{
info = sbinfo;
foundASubBlock = true;
return false;
}

return true;
});
}

return foundASubBlock;
return CziReaderCommon::TryGetSubBlockInfoOfArbitrarySubBlockInChannel(this, channelIndex, info);

Check warning on line 149 in Src/libCZI/CZIReader.cpp

View check run for this annotation

Codecov / codecov/patch

Src/libCZI/CZIReader.cpp#L149

Added line #L149 was not covered by tests
}

/*virtual*/bool CCZIReader::TryGetSubBlockInfo(int index, SubBlockInfo* info) const
Expand All @@ -223,13 +159,7 @@

if (info != nullptr)
{
info->compressionModeRaw = entry.Compression;
info->pixelType = CziUtils::PixelTypeFromInt(entry.PixelType);
info->coordinate = entry.coordinate;
info->logicalRect = IntRect{ entry.x,entry.y,entry.width,entry.height };
info->physicalSize = IntSize{ static_cast<std::uint32_t>(entry.storedWidth), static_cast<std::uint32_t>(entry.storedHeight) };
info->mIndex = entry.mIndex;
info->pyramidType = CziUtils::PyramidTypeFromByte(entry.pyramid_type_from_spare);
*info = CziReaderCommon::ConvertToSubBlockInfo(entry);
}

return true;
Expand Down Expand Up @@ -273,25 +203,11 @@
/*virtual*/void CCZIReader::EnumerateSubset(const char* contentFileType, const char* name, const std::function<bool(int index, const libCZI::AttachmentInfo& info)>& funcEnum)
{
this->ThrowIfNotOperational();
libCZI::AttachmentInfo ai;
ai.contentFileType[sizeof(ai.contentFileType) - 1] = '\0';
this->attachmentDir.EnumAttachments(
[&](int index, const CCziAttachmentsDirectory::AttachmentEntry& ae)
{
if (contentFileType == nullptr || strcmp(contentFileType, ae.ContentFileType) == 0)
{
if (name == nullptr || strcmp(name, ae.Name) == 0)
{
ai.contentGuid = ae.ContentGuid;
memcpy(ai.contentFileType, ae.ContentFileType, sizeof(ae.ContentFileType));
ai.name = ae.Name;
bool b = funcEnum(index, ai);
return b;
}
}

return true;
});
CziReaderCommon::EnumerateSubset(

Check warning on line 206 in Src/libCZI/CZIReader.cpp

View check run for this annotation

Codecov / codecov/patch

Src/libCZI/CZIReader.cpp#L206

Added line #L206 was not covered by tests
std::bind(&CCziAttachmentsDirectory::EnumAttachments, &this->attachmentDir, std::placeholders::_1),
contentFileType,
name,
funcEnum);
}

/*virtual*/std::shared_ptr<libCZI::IAttachment> CCZIReader::ReadAttachment(int index)
Expand Down
118 changes: 118 additions & 0 deletions Src/libCZI/CziReaderCommon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-FileCopyrightText: 2024 Carl Zeiss Microscopy GmbH
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#include "CziReaderCommon.h"

#include "CziUtils.h"
#include "utilities.h"

using namespace std;
using namespace libCZI;

/*static*/void CziReaderCommon::EnumSubset(
libCZI::ISubBlockRepository* repository,
const libCZI::IDimCoordinate* planeCoordinate,
const libCZI::IntRect* roi,
bool onlyLayer0,
const std::function<bool(int index, const libCZI::SubBlockInfo& info)>& funcEnum)
{
// Ok... for a first tentative, experimental and quick-n-dirty implementation, simply
// walk through all the subblocks. We surely want to have something more elaborated
// here.
repository->EnumerateSubBlocks(
[&](int index, const SubBlockInfo& info)->bool
{
if (onlyLayer0 == false || (info.physicalSize.w == info.logicalRect.w && info.physicalSize.h == info.logicalRect.h))
{
if (planeCoordinate == nullptr || CziUtils::CompareCoordinate(planeCoordinate, &info.coordinate) == true)
{
if (roi == nullptr || Utilities::DoIntersect(*roi, info.logicalRect))
{
const bool b = funcEnum(index, info);
return b;
}
}
}

return true;
});
}

/*static*/bool CziReaderCommon::TryGetSubBlockInfoOfArbitrarySubBlockInChannel(
libCZI::ISubBlockRepository* repository,
int channelIndex,
libCZI::SubBlockInfo& info)
{
bool foundASubBlock = false;
SubBlockStatistics s = repository->GetStatistics();
if (!s.dimBounds.IsValid(DimensionIndex::C))
{
// in this case -> just take the first subblock...
repository->EnumerateSubBlocks(

Check warning on line 52 in Src/libCZI/CziReaderCommon.cpp

View check run for this annotation

Codecov / codecov/patch

Src/libCZI/CziReaderCommon.cpp#L52

Added line #L52 was not covered by tests
[&](int index, const SubBlockInfo& sbinfo)->bool
{
info = sbinfo;
foundASubBlock = true;
return false;
});
}

Check warning on line 59 in Src/libCZI/CziReaderCommon.cpp

View check run for this annotation

Codecov / codecov/patch

Src/libCZI/CziReaderCommon.cpp#L55-L59

Added lines #L55 - L59 were not covered by tests
else
{
repository->EnumerateSubBlocks(
[&](int index, const SubBlockInfo& sbinfo)->bool
{
int c;
if (sbinfo.coordinate.TryGetPosition(DimensionIndex::C, &c) == true && c == channelIndex)
{
info = sbinfo;
foundASubBlock = true;
return false;
}

return true;
});
}

return foundASubBlock;
}

/*static*/void CziReaderCommon::EnumerateSubset(
const std::function<void(const std::function<bool(int index, const CCziAttachmentsDirectory::AttachmentEntry&)>&)>& func,
const char* contentFileType,
const char* name,
const std::function<bool(int index, const libCZI::AttachmentInfo& info)>& funcEnum)
{
libCZI::AttachmentInfo ai;
ai.contentFileType[sizeof(ai.contentFileType) - 1] = '\0';
func(
[&](int index, const CCziAttachmentsDirectoryBase::AttachmentEntry& ae)
{
if (contentFileType == nullptr || strcmp(contentFileType, ae.ContentFileType) == 0)
{
if (name == nullptr || strcmp(name, ae.Name) == 0)
{
ai.contentGuid = ae.ContentGuid;
memcpy(ai.contentFileType, ae.ContentFileType, sizeof(ae.ContentFileType));
ai.name = ae.Name;
bool b = funcEnum(index, ai);
return b;
}
}

return true;
});
}

/*static*/libCZI::SubBlockInfo CziReaderCommon::ConvertToSubBlockInfo(const CCziSubBlockDirectory::SubBlkEntry& entry)
{
SubBlockInfo info;
info.compressionModeRaw = entry.Compression;
info.pixelType = CziUtils::PixelTypeFromInt(entry.PixelType);
info.coordinate = entry.coordinate;
info.logicalRect = IntRect{ entry.x,entry.y,entry.width,entry.height };
info.physicalSize = IntSize{ (std::uint32_t)entry.storedWidth, (std::uint32_t)entry.storedHeight };
info.mIndex = entry.mIndex;
info.pyramidType = CziUtils::PyramidTypeFromByte(entry.pyramid_type_from_spare);
return info;
}
34 changes: 34 additions & 0 deletions Src/libCZI/CziReaderCommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: 2024 Carl Zeiss Microscopy GmbH
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#pragma once

#include "libCZI.h"
#include "CziAttachment.h"
#include <functional>

/// Here we gather some common functionality that is used by both the CziReader and the CziReaderWriter classes.
class CziReaderCommon
{
public:
static void EnumSubset(
libCZI::ISubBlockRepository* repository,
const libCZI::IDimCoordinate* planeCoordinate,
const libCZI::IntRect* roi,
bool onlyLayer0,
const std::function<bool(int index, const libCZI::SubBlockInfo& info)>& funcEnum);

static bool TryGetSubBlockInfoOfArbitrarySubBlockInChannel(
libCZI::ISubBlockRepository* repository,
int channelIndex,
libCZI::SubBlockInfo& info);

static void EnumerateSubset(
const std::function<void(const std::function<bool(int index, const CCziAttachmentsDirectory::AttachmentEntry&)>&)>& func,
const char* contentFileType,
const char* name,
const std::function<bool(int index, const libCZI::AttachmentInfo& info)>& funcEnum);

static libCZI::SubBlockInfo ConvertToSubBlockInfo(const CCziSubBlockDirectory::SubBlkEntry& entry);
};
Loading
Loading