diff --git a/CMakeLists.txt b/CMakeLists.txt index 36f0000..8c2acd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.15) project(CZICheck - VERSION 0.1.2 + VERSION 0.2.0 HOMEPAGE_URL "https://github.com/ZEISS/czicheck" DESCRIPTION "CZICheck is a validator for CZI-documents") diff --git a/CZICheck/CMakeLists.txt b/CZICheck/CMakeLists.txt index 31a951d..bd4347a 100644 --- a/CZICheck/CMakeLists.txt +++ b/CZICheck/CMakeLists.txt @@ -70,6 +70,8 @@ set(CZICHECKSRCFILES "checkers/checkerOverlappingScenes.cpp" "checkers/checkerSubBlkBitmapValid.h" "checkers/checkerSubBlkBitmapValid.cpp" +"checkers/checkerTopographyApplianceValidation.h" +"checkers/checkerTopographyApplianceValidation.cpp" checkerfactory.cpp checkerfactory.h checks.h @@ -162,6 +164,8 @@ if (CZICHECK_BUILD_TESTS) -r overlapping_scenes.czi=DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Test/CZICheckSamples/overlapping_scenes.czi} -r jpgxrcompressed_inconsistent_size.czi=DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Test/CZICheckSamples/jpgxrcompressed_inconsistent_size.czi} -r jpgxrcompressed_inconsistent_pixeltype.czi=DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Test/CZICheckSamples/jpgxrcompressed_inconsistent_pixeltype.czi} + -r edf-missing-texture.czi=DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Test/CZICheckSamples/edf-missing-texture.czi} + -r edf-superfluous.czi=DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Test/CZICheckSamples/edf-superfluous.czi} ) # Add a build target to populate the real data. diff --git a/CZICheck/checkerfactory.cpp b/CZICheck/checkerfactory.cpp index 5503b9f..2b65a0b 100644 --- a/CZICheck/checkerfactory.cpp +++ b/CZICheck/checkerfactory.cpp @@ -20,6 +20,7 @@ #include "checkers/checkerXmlBasicMetadataValidation.h" #include "checkers/checkerOverlappingScenes.h" #include "checkers/checkerSubBlkBitmapValid.h" +#include "checkers/checkerTopographyApplianceValidation.h" using namespace std; @@ -94,6 +95,7 @@ static const classEntry classesList[] = MakeEntry(), MakeEntry(), MakeEntry(), + MakeEntry(), #if CZICHECK_XERCESC_AVAILABLE MakeEntry(true), #endif diff --git a/CZICheck/checkers/checkerTopographyApplianceValidation.cpp b/CZICheck/checkers/checkerTopographyApplianceValidation.cpp new file mode 100644 index 0000000..bc0e8a7 --- /dev/null +++ b/CZICheck/checkers/checkerTopographyApplianceValidation.cpp @@ -0,0 +1,261 @@ +// SPDX-FileCopyrightText: 2024 Carl Zeiss Microscopy GmbH +// +// SPDX-License-Identifier: MIT + +#include "checkerTopographyApplianceValidation.h" +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace libCZI; + +/*static*/const char* CCheckTopographyApplianceMetadata::kDisplayName = "Basic semantic checks for TopographyDataItems"; +/*static*/const char* CCheckTopographyApplianceMetadata::kShortName = "topographymetadata"; + +CCheckTopographyApplianceMetadata::CCheckTopographyApplianceMetadata( + const std::shared_ptr& reader, + CResultGatherer& result_gatherer, + const CheckerCreateInfo& additional_info) : + CCheckerBase(reader, result_gatherer, additional_info) +{ +} + +void CCheckTopographyApplianceMetadata::RunCheck() +{ + this->result_gatherer_.StartCheck(CCheckTopographyApplianceMetadata::kCheckType); + + const auto czi_metadata = this->GetCziMetadataAndReportErrors(CCheckTopographyApplianceMetadata::kCheckType); + if (czi_metadata) + { + this->CheckValidDimensionInTopographyDataItems(czi_metadata); + } + + this->result_gatherer_.FinishCheck(CCheckTopographyApplianceMetadata::kCheckType); +} + +void CCheckTopographyApplianceMetadata::CheckValidDimensionInTopographyDataItems(const std::shared_ptr& czi_metadata) +{ + if (!this->ExtractMetaDataDimensions(czi_metadata)) + { + // we don't have any topography items and stop here + return; + } + + if (this->texture_views_.empty() || this->heightmap_views_.empty()) + { + CResultGatherer::Finding finding(CCheckTopographyApplianceMetadata::kCheckType); + finding.severity = CResultGatherer::Severity::Warning; + finding.information = "The image contains incomplete TopographyDataItems."; + this->result_gatherer_.ReportFinding(finding); + + return; + } + + // as soon as we have more than StartC specified for a Texutre or a Heightmap node + // the node contains superfluous data + auto superfluous_elements_check = [](const unordered_map& dim_map) -> bool + { + if (dim_map.size() != 1) + { + return false; + } + + return true; + }; + + auto start_c_defined_check = [](const unordered_map& dim_map) -> bool + { + for (const auto& dim : dim_map) + { + if (dim.second.DimensionIndex == DimensionIndex::C + && dim.second.IsValid()) + return true; + } + + return false; + }; + + bool superfluous_free{ true }; + bool start_c_defined{ true }; + for (const auto& txt : this->texture_views_) + { + superfluous_free &= superfluous_elements_check(txt); + start_c_defined &= start_c_defined_check(txt); + } + + for (const auto& hmp : this->heightmap_views_) + { + superfluous_free &= superfluous_elements_check(hmp); + start_c_defined &= start_c_defined_check(hmp); + } + + if (!superfluous_free) + { + CResultGatherer::Finding finding(CCheckTopographyApplianceMetadata::kCheckType); + finding.severity = CResultGatherer::Severity::Warning; + finding.information = "There are superfluous dimensions specified in the TopographyDataItems. This might yield errors."; + this->result_gatherer_.ReportFinding(finding); + } + + if (!start_c_defined) + { + CResultGatherer::Finding finding(CCheckTopographyApplianceMetadata::kCheckType); + finding.severity = CResultGatherer::Severity::Fatal; + finding.information = "The image contains TopographyDataItems that do not define a channel."; + this->result_gatherer_.ReportFinding(finding); + } +} + +bool CCheckTopographyApplianceMetadata::ExtractMetaDataDimensions(const std::shared_ptr& czi_metadata) +{ + // within the TopographyData we allow + // any number of TopographyDataItem which itself can contain a set of Texutures and a set of heightmaps + // within the heightmaps AND Textures, each item reside in its own channel. + string topography_path{ this->kImageAppliancePath }; + topography_path + .append("/Appliance[Id=") + .append(this->kTopographyItemId) + .append("]"); + + const auto topo_metadata{ czi_metadata->GetChildNodeReadonly(topography_path.c_str()) }; + + if (!topo_metadata) + { + // there is no topo metadata section, we end here + return false; + } + + vector>> heightmaps; + vector>> textures; + + // we need a "named" lambda here to call it recursively + std::function)> enumChildrenLambda = + [this, &heightmaps, &textures, &enumChildrenLambda](const std::shared_ptr& xmlnode) -> bool + { + std::vector> current_texture; + std::vector> current_heightmap; + + auto textureLambda = [¤t_texture](const std::wstring& attr, const std::wstring& val) -> bool + { + current_texture.push_back({ attr, val }); + return true; + }; + + auto heighmapLambda = [¤t_heightmap](const std::wstring& attr, const std::wstring& val) -> bool + { + current_heightmap.push_back({ attr, val }); + return true; + }; + + auto node_name = xmlnode->Name(); + if (node_name == CCheckTopographyApplianceMetadata::kTextureItemKey) + { + xmlnode->EnumAttributes(textureLambda); + + if (!current_texture.empty()) + { + textures.push_back(current_texture); + } + } + + if (node_name == CCheckTopographyApplianceMetadata::kHeightMapItemKey) + { + xmlnode->EnumAttributes(heighmapLambda); + + if (!current_heightmap.empty()) + { + heightmaps.push_back(current_heightmap); + } + } + + // recursively go through child items + xmlnode->EnumChildren(enumChildrenLambda); + + return true; + }; + + // call the enumeration lambda + topo_metadata->EnumChildren(enumChildrenLambda); + + // parse the dimension vectors + for (const auto& hm : heightmaps) + { + this->SetBoundsFromVector(hm, this->heightmap_views_); + } + + for (const auto& tx : textures) + { + this->SetBoundsFromVector(tx, this->texture_views_); + } + + if (!this->heightmap_views_.empty() || !this->texture_views_.empty()) + { + return true; + } + + return false; +} + +bool CCheckTopographyApplianceMetadata::SetBoundsFromVector(const std::vector>& vec, std::vector>& view) +{ + // using a set here to ensure exactly one element per dimension + unordered_map configurations; + + const wstring kStart = L"Start"; + const wstring kSize = L"Size"; + + for (const auto& element : vec) + { + // get the dimension index + char dim{ static_cast(element.first.back()) }; + + configurations.insert({ dim, DimensionView() }); + int value{ -1 }; + try + { + value = stoi(element.second); + } + catch (const invalid_argument&) + { + // this will ensure an "invalid" dimension later + value = -1; + } + + DimensionView& config = configurations.at(dim); + if (config.DimensionIndex == DimensionIndex::invalid) + { + config.DimensionIndex = Utils::CharToDimension(dim); + } + + // -1 means not set + if (element.first.find(kStart) != string::npos && config.Start == -1) + { + config.Start = value; + } + + if (element.first.find(kSize) != string::npos && config.Size == -1) + { + config.Size = value; + } + + // '\0' means not set + if (config.DimensionName == '\0') + { + config.DimensionName = dim; + } + } + + bool all_good{ true }; + for (const auto& el : configurations) + { + all_good &= el.second.IsValid(); + } + + view.push_back(configurations); + + return all_good; +}; diff --git a/CZICheck/checkers/checkerTopographyApplianceValidation.h b/CZICheck/checkers/checkerTopographyApplianceValidation.h new file mode 100644 index 0000000..9f18dd8 --- /dev/null +++ b/CZICheck/checkers/checkerTopographyApplianceValidation.h @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2024 Carl Zeiss Microscopy GmbH +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "checkerbase.h" +#include +#include +#include +#include +#include + +/// This checker validates the topography-XML-metadata. +class CCheckTopographyApplianceMetadata : public IChecker, CCheckerBase +{ +private: + struct DimensionView + { + libCZI::DimensionIndex DimensionIndex{ libCZI::DimensionIndex::invalid }; + char DimensionName{ '\0' }; + int Start{ -1 }; + int Size{ -1 }; + bool IsValid() const + { + // this is an object used exclusively for this checker + // a Size (SizeC, SizeX, etc.) is not needed to yield a "valid" dimension for this + if (this->Start >= 0 && this->DimensionIndex != libCZI::DimensionIndex::invalid) + { + return true; + } + + return false; + } + }; + + static constexpr const char* kTopographyItemId = "Topography:1"; + static constexpr const char* kImageAppliancePath = "ImageDocument/Metadata/Appliances"; + static constexpr const wchar_t* kTextureItemKey = L"Texture"; + static constexpr const wchar_t* kHeightMapItemKey = L"HeightMap"; + + std::vector> texture_views_; + std::vector> heightmap_views_; + +public: + static const CZIChecks kCheckType = CZIChecks::ApplianceMetadataTopographyItemValid; + static const char* kDisplayName; + static const char* kShortName; + + CCheckTopographyApplianceMetadata( + const std::shared_ptr& reader, + CResultGatherer& result_gatherer, + const CheckerCreateInfo& additional_info); + void RunCheck() override; + +private: + void CheckValidDimensionInTopographyDataItems(const std::shared_ptr& czi_metadata); + + bool SetBoundsFromVector(const std::vector>&, std::vector>&); + bool ExtractMetaDataDimensions(const std::shared_ptr& czi_metadata); +}; diff --git a/CZICheck/checks.h b/CZICheck/checks.h index bced5e4..854ff3a 100644 --- a/CZICheck/checks.h +++ b/CZICheck/checks.h @@ -52,5 +52,8 @@ enum class CZIChecks ConsistentMIndex, ///< To be done, not yet implemented. - AttachmentDirectoryPositionsWithinRange ///< To be done, not yet implemented. + AttachmentDirectoryPositionsWithinRange, ///< To be done, not yet implemented. + + /// The Applicance Metadata specified for TopographyDataItem(s) are valid + ApplianceMetadataTopographyItemValid, }; diff --git a/Test/CZICheckSamples/TestCasesLists.txt b/Test/CZICheckSamples/TestCasesLists.txt index 7c5bdea..f8f0667 100644 --- a/Test/CZICheckSamples/TestCasesLists.txt +++ b/Test/CZICheckSamples/TestCasesLists.txt @@ -28,3 +28,5 @@ inaccessible_file.czi,5,* overlapping_scenes.czi,2,overlapping_scenes.txt jpgxrcompressed_inconsistent_size.czi,2,jpgxrcompressed_inconsistent_size.txt jpgxrcompressed_inconsistent_pixeltype.czi,2,jpgxrcompressed_inconsistent_pixeltype.txt +edf-missing-texture.czi,2,edf-missing-texture.txt +edf-superfluous.czi,2,edf-superfluous.txt \ No newline at end of file diff --git a/Test/CZICheckSamples/differentpixeltypeinchannel.txt b/Test/CZICheckSamples/differentpixeltypeinchannel.txt index f469df4..e5d7837 100644 --- a/Test/CZICheckSamples/differentpixeltypeinchannel.txt +++ b/Test/CZICheckSamples/differentpixeltypeinchannel.txt @@ -17,6 +17,9 @@ Test "validate the XML-metadata against XSD-schema" : WARN Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : + Could not read metadata-segment + WARN Result: With Warnings diff --git a/Test/CZICheckSamples/duplicate_coordinates.txt b/Test/CZICheckSamples/duplicate_coordinates.txt index bc08563..7753855 100644 --- a/Test/CZICheckSamples/duplicate_coordinates.txt +++ b/Test/CZICheckSamples/duplicate_coordinates.txt @@ -17,6 +17,9 @@ Test "validate the XML-metadata against XSD-schema" : WARN Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : + Could not read metadata-segment + WARN Result: Errors Detected diff --git a/Test/CZICheckSamples/edf-missing-texture.czi.md5 b/Test/CZICheckSamples/edf-missing-texture.czi.md5 new file mode 100644 index 0000000..4cf840b --- /dev/null +++ b/Test/CZICheckSamples/edf-missing-texture.czi.md5 @@ -0,0 +1 @@ +e1bcf912d13b002f32e8c325ab4ecac6 \ No newline at end of file diff --git a/Test/CZICheckSamples/edf-missing-texture.txt b/Test/CZICheckSamples/edf-missing-texture.txt new file mode 100644 index 0000000..98b305b --- /dev/null +++ b/Test/CZICheckSamples/edf-missing-texture.txt @@ -0,0 +1,24 @@ +Test "SubBlock-Segment in SubBlockDirectory within file" : OK +Test "SubBlock-Segments in SubBlockDirectory are valid" : OK +Test "check subblock's coordinates for 'consistent dimensions'" : OK +Test "check subblock's coordinates being unique" : OK +Test "check whether the document uses the deprecated 'B-index'" : OK +Test "check that the subblocks of a channel have the same pixeltype" : OK +Test "Check that planes indices start at 0" : OK +Test "Check that planes have consecutive indices" : OK +Test "check if all subblocks have the M index" : OK +Test "Basic semantic checks of the XML-metadata" : OK +Test "validate the XML-metadata against XSD-schema" : + (101,22): no declaration found for element 'RotationCenter' + (105,15): element 'RotationCenter' is not allowed for content model 'All(SessionMatrix?,HolderZeissName?,HolderZeissId?,HolderCwsId?,SessionCount?,SessionRotationAtStart?,CustomAttributes?)' + (112,21): no declaration found for element 'LookupTables' + <3 more findings omitted> + FAIL +Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK +Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : + The image contains TopographyDataItems that do not define a channel. + FAIL + + +Result: Errors Detected \ No newline at end of file diff --git a/Test/CZICheckSamples/edf-superfluous.czi.md5 b/Test/CZICheckSamples/edf-superfluous.czi.md5 new file mode 100644 index 0000000..61df631 --- /dev/null +++ b/Test/CZICheckSamples/edf-superfluous.czi.md5 @@ -0,0 +1 @@ +dbecd3a299bc85eac7d45ab77ad3f4dc \ No newline at end of file diff --git a/Test/CZICheckSamples/edf-superfluous.txt b/Test/CZICheckSamples/edf-superfluous.txt new file mode 100644 index 0000000..e70ae5a --- /dev/null +++ b/Test/CZICheckSamples/edf-superfluous.txt @@ -0,0 +1,24 @@ +Test "SubBlock-Segment in SubBlockDirectory within file" : OK +Test "SubBlock-Segments in SubBlockDirectory are valid" : OK +Test "check subblock's coordinates for 'consistent dimensions'" : OK +Test "check subblock's coordinates being unique" : OK +Test "check whether the document uses the deprecated 'B-index'" : OK +Test "check that the subblocks of a channel have the same pixeltype" : OK +Test "Check that planes indices start at 0" : OK +Test "Check that planes have consecutive indices" : OK +Test "check if all subblocks have the M index" : OK +Test "Basic semantic checks of the XML-metadata" : OK +Test "validate the XML-metadata against XSD-schema" : + (121,22): no declaration found for element 'RotationCenter' + (125,15): element 'RotationCenter' is not allowed for content model 'All(SessionMatrix?,HolderZeissName?,HolderZeissId?,HolderCwsId?,SessionCount?,SessionRotationAtStart?,CustomAttributes?)' + (139,21): no declaration found for element 'LookupTables' + <3 more findings omitted> + FAIL +Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK +Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : + There are superfluous dimensions specified in the TopographyDataItems. This might yield errors. + WARN + + +Result: Errors Detected \ No newline at end of file diff --git a/Test/CZICheckSamples/inconsistent_coordinates.txt b/Test/CZICheckSamples/inconsistent_coordinates.txt index 5646d91..0e23fcb 100644 --- a/Test/CZICheckSamples/inconsistent_coordinates.txt +++ b/Test/CZICheckSamples/inconsistent_coordinates.txt @@ -17,6 +17,9 @@ Test "validate the XML-metadata against XSD-schema" : WARN Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : + Could not read metadata-segment + WARN Result: Errors Detected diff --git a/Test/CZICheckSamples/jpgxrcompressed_inconsistent_pixeltype.txt b/Test/CZICheckSamples/jpgxrcompressed_inconsistent_pixeltype.txt index 8d88240..3165d1f 100644 --- a/Test/CZICheckSamples/jpgxrcompressed_inconsistent_pixeltype.txt +++ b/Test/CZICheckSamples/jpgxrcompressed_inconsistent_pixeltype.txt @@ -13,6 +13,7 @@ Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : Error decoding subblock #0 with compression "jpgxr" FAIL +Test "Basic semantic checks for TopographyDataItems" : OK Result: Errors Detected diff --git a/Test/CZICheckSamples/jpgxrcompressed_inconsistent_size.txt b/Test/CZICheckSamples/jpgxrcompressed_inconsistent_size.txt index 8d88240..3165d1f 100644 --- a/Test/CZICheckSamples/jpgxrcompressed_inconsistent_size.txt +++ b/Test/CZICheckSamples/jpgxrcompressed_inconsistent_size.txt @@ -13,6 +13,7 @@ Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : Error decoding subblock #0 with compression "jpgxr" FAIL +Test "Basic semantic checks for TopographyDataItems" : OK Result: Errors Detected diff --git a/Test/CZICheckSamples/layer_0_subblocks_with_no_m_index.txt b/Test/CZICheckSamples/layer_0_subblocks_with_no_m_index.txt index 0c7fc65..b168d40 100644 --- a/Test/CZICheckSamples/layer_0_subblocks_with_no_m_index.txt +++ b/Test/CZICheckSamples/layer_0_subblocks_with_no_m_index.txt @@ -13,6 +13,7 @@ Test "Basic semantic checks of the XML-metadata" : OK Test "validate the XML-metadata against XSD-schema" : OK Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : OK Result: With Warnings diff --git a/Test/CZICheckSamples/negative_plane_start_index.txt b/Test/CZICheckSamples/negative_plane_start_index.txt index eb9b29b..be00c4e 100644 --- a/Test/CZICheckSamples/negative_plane_start_index.txt +++ b/Test/CZICheckSamples/negative_plane_start_index.txt @@ -15,6 +15,7 @@ Test "Basic semantic checks of the XML-metadata" : Test "validate the XML-metadata against XSD-schema" : OK Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : OK Result: With Warnings diff --git a/Test/CZICheckSamples/overlapping_scenes.txt b/Test/CZICheckSamples/overlapping_scenes.txt index 5bfa312..392e8ff 100644 --- a/Test/CZICheckSamples/overlapping_scenes.txt +++ b/Test/CZICheckSamples/overlapping_scenes.txt @@ -23,6 +23,7 @@ Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" <1 more finding omitted> WARN Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : OK Result: Errors Detected diff --git a/Test/CZICheckSamples/pixeltype_mismatch_between_metadata_and_subblocks.txt b/Test/CZICheckSamples/pixeltype_mismatch_between_metadata_and_subblocks.txt index 33371da..689ccf5 100644 --- a/Test/CZICheckSamples/pixeltype_mismatch_between_metadata_and_subblocks.txt +++ b/Test/CZICheckSamples/pixeltype_mismatch_between_metadata_and_subblocks.txt @@ -20,6 +20,7 @@ Test "validate the XML-metadata against XSD-schema" : FAIL Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : OK Result: Errors Detected diff --git a/Test/CZICheckSamples/positive_plane_start_index.txt b/Test/CZICheckSamples/positive_plane_start_index.txt index 85420ee..136852c 100644 --- a/Test/CZICheckSamples/positive_plane_start_index.txt +++ b/Test/CZICheckSamples/positive_plane_start_index.txt @@ -15,6 +15,7 @@ Test "Basic semantic checks of the XML-metadata" : Test "validate the XML-metadata against XSD-schema" : OK Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : OK Result: With Warnings diff --git a/Test/CZICheckSamples/sparse_planes.txt b/Test/CZICheckSamples/sparse_planes.txt index ae99b28..08e2984 100644 --- a/Test/CZICheckSamples/sparse_planes.txt +++ b/Test/CZICheckSamples/sparse_planes.txt @@ -15,6 +15,7 @@ Test "Basic semantic checks of the XML-metadata" : Test "validate the XML-metadata against XSD-schema" : OK Test "check if subblocks at pyramid-layer 0 of different scenes are overlapping" : OK Test "SubBlock-Segments in SubBlockDirectory are valid and valid content" : OK +Test "Basic semantic checks for TopographyDataItems" : OK Result: With Warnings diff --git a/documentation/description_of_checkers.md b/documentation/description_of_checkers.md index d78fa5d..e650925 100644 --- a/documentation/description_of_checkers.md +++ b/documentation/description_of_checkers.md @@ -18,7 +18,8 @@ The following table lists the available checkers and gives a short description o |basicxmlmetadata|Same basic checks of the XML-metadata, which is semantically validated with the content of the file.| |xmlmetadataschema|Validate the XML-metadata against the schema for it.| |overlappingscenes|Test for subblocks within different scenes are overlapping (on pyramid-layer 0).| -|subblkbitmapvalid|Read all subblocks from the file, ensure their syntactical validity and decode the bitmap. Note that this check requires reading all data from disk and decoding, so it may be time consuming. || +|subblkbitmapvalid|Read all subblocks from the file, ensure their syntactical validity and decode the bitmap. Note that this check requires reading all data from disk and decoding, so it may be time consuming. | +|topographymetadata|Checks whether the given TopographyDataItems supplied in the Appliances metadata section of a czi image comply with the specification and the content of that czi image.| ## Details @@ -98,3 +99,7 @@ This check is more thorough than the check 'subblksegmentsvalid', as it also che so it is not necessary to run both checks. Note that this check requires reading all data from disk, and in case of compressed data it is decoded, so it may be time consuming. +### topographymetadata +This checker is implemented in the file 'checkerTopographyApplianceValidation.cpp'. +It checks if an image contains a Topography section in its 'Appliances' metadata section. +If there is such a section, it checks if both 'Textures' and 'HeightMaps' are given within 'TopographyDataItem' containers in the Appliances section. Each of the entries in 'Textures' and 'HeighMaps' should specify a channel (via a 'StartC' information) and no other information. That other information is considered superfluous. \ No newline at end of file diff --git a/documentation/version-history.md b/documentation/version-history.md index e3b4785..3805456 100644 --- a/documentation/version-history.md +++ b/documentation/version-history.md @@ -5,4 +5,5 @@ version history {#version_history} -------------- | ---------------------------------------------------- | --------------------------------------------------- 0.1.0 | | initial release 0.1.1 | [4](https://github.com/ZEISS/czicheck/pull/4) | update of metadata-schema (compression) - 0.1.2 | [9](https://github.com/ZEISS/czicheck/pull/9) | add checker "subblkbitmapvalid" \ No newline at end of file + 0.1.2 | [9](https://github.com/ZEISS/czicheck/pull/9) | add checker "subblkbitmapvalid" + 0.2.0 | [10](https://github.com/ZEISS/czicheck/pull/10) | add checker "topographymetadata"