From 1c373e41cac547b991897e84d65d96fa00314c9c Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 20 Oct 2023 12:40:33 +0200 Subject: [PATCH 1/9] draft --- CMakeLists.txt | 8 +++++--- app/CZIcompress.cpp | 6 ++++-- capi/capi.cpp | 2 +- tests/test_copyoperation.cpp | 10 +++++----- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78a3dbf..7313107 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ cmake_policy(SET CMP0091 NEW) # enable new "MSVC runtime library selection" (htt # Note that the CMake-variables _VERSION_MAJOR, _VERSION_MINOR, ... are defined by this statement, # which are used in the build (so that - if changing the name here, change also the usage of those variables). project ("czicompress" - VERSION 0.4.1) + VERSION 0.4.2) set(czicompress_VERSION_PATCH_FLAGS "-alpha") set(czicompress_VERSION_TWEAK_FLAGS "") @@ -28,8 +28,10 @@ message (STATUS "[${PROJECT_NAME}] Processing ${CMAKE_CURRENT_LIST_FILE}") include(FetchContent) FetchContent_Declare( libczi - GIT_REPOSITORY https://github.com/ZEISS/libczi.git - GIT_TAG c9954d58759ef6dd7d7c6a53c163ea8349855392 + #GIT_REPOSITORY https://github.com/ZEISS/libczi.git + GIT_REPOSITORY https://github.com/ptahmose/libczi-zeiss + GIT_TAG jbl/1036970-more_lax_checking_for_duplicte_subblocks + #GIT_TAG c9954d58759ef6dd7d7c6a53c163ea8349855392 ) if(NOT libCZI_POPULATED) diff --git a/app/CZIcompress.cpp b/app/CZIcompress.cpp index 0d7f1ec..6653524 100644 --- a/app/CZIcompress.cpp +++ b/app/CZIcompress.cpp @@ -98,10 +98,12 @@ int main(int argc, char** argv) libCZI::CreateOutputStreamForFile(utils::utf8::WidenUtf8(command_line_options.GetOutputFileName()).c_str(), false); // create the "CZI-writer"-object - const auto writer = libCZI::CreateCZIWriter(); + libCZI::CZIWriterOptions czi_writer_options; + czi_writer_options.allow_duplicate_subblocks = true; + const auto writer = libCZI::CreateCZIWriter(&czi_writer_options); // GUID_NULL here means that a new Guid is created - const auto czi_writer_info = std::make_shared(GUID{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}); + const auto czi_writer_info = std::make_shared(libCZI::GUID{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}); // TODO(JBL): it might be desirable to make reservations for the // subblock-directory-/attachments-directory-/metadata-segment diff --git a/capi/capi.cpp b/capi/capi.cpp index 062e30c..85c4d2d 100644 --- a/capi/capi.cpp +++ b/capi/capi.cpp @@ -53,7 +53,7 @@ class FileProcessor final const auto writer = libCZI::CreateCZIWriter(); // GUID_NULL here means that a new Guid is created - const auto czi_writer_info = std::make_shared(GUID{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}); + const auto czi_writer_info = std::make_shared(libCZI::GUID{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}); // TODO(JBL): it might be desirable to make reservations for the // subblock-directory-/attachments-directory-/metadata-segment diff --git a/tests/test_copyoperation.cpp b/tests/test_copyoperation.cpp index 0f05444..a6547c4 100644 --- a/tests/test_copyoperation.cpp +++ b/tests/test_copyoperation.cpp @@ -40,7 +40,7 @@ static tuple, size_t> CreateCziWithFourSubblockInMosaicArrangem auto writer = libCZI::CreateCZIWriter(); auto outStream = make_shared(0); - auto spWriterInfo = make_shared(GUID{0x1234567, 0x89ab, 0xcdef, {1, 2, 3, 4, 5, 6, 7, 8}}, // NOLINT + auto spWriterInfo = make_shared(libCZI::GUID{0x1234567, 0x89ab, 0xcdef, {1, 2, 3, 4, 5, 6, 7, 8}}, // NOLINT libCZI::CDimBounds{{libCZI::DimensionIndex::C, 0, 1}}, // set a bounds for C 0, 3); // set a bounds M : 0<=m<=0 writer->Create(outStream, spWriterInfo); @@ -162,7 +162,7 @@ TEST_CASE("copyczi.1: run compression on simple synthetic document", "[copyczi]" // create a CZI-writer object on a new memory stream auto writer = libCZI::CreateCZIWriter(); const auto memory_backed_stream_destination_document = make_shared(0); - const auto writer_info = make_shared(GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); + const auto writer_info = make_shared(libCZI::GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); writer->Create(memory_backed_stream_destination_document, writer_info); // act @@ -218,7 +218,7 @@ TEST_CASE("copyczi.2: run compression on simple synthetic document changes compr // create a CZI-writer object on a new memory stream auto writer = libCZI::CreateCZIWriter(); const auto memory_backed_stream_destination_document = make_shared(0); - const auto writer_info = make_shared(GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); + const auto writer_info = make_shared(libCZI::GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); writer->Create(memory_backed_stream_destination_document, writer_info); // act @@ -280,7 +280,7 @@ TEST_CASE("copyczi.3: run decompression on simple synthetically compressed docum // create a CZI-writer object on a new memory stream auto writer = libCZI::CreateCZIWriter(); const auto memory_backed_stream_destination_document = make_shared(0); - const auto writer_info = make_shared(GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); + const auto writer_info = make_shared(libCZI::GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); writer->Create(memory_backed_stream_destination_document, writer_info); // act @@ -309,7 +309,7 @@ TEST_CASE("copyczi.3: run decompression on simple synthetically compressed docum // create a CZI-writer object on a new memory stream auto writer_2 = libCZI::CreateCZIWriter(); const auto memory_backed_stream_destination_document_2 = make_shared(0); - const auto writer_info_2 = make_shared(GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); + const auto writer_info_2 = make_shared(libCZI::GUID{0x0, 0x0, 0x0, {0, 0, 0, 0, 0, 0, 0, 0}}); writer_2->Create(memory_backed_stream_destination_document_2, writer_info_2); // act From fd8b4ea91a9171ebe9f342b5cfeb99009e855b14 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 20 Oct 2023 23:08:10 +0200 Subject: [PATCH 2/9] add option "--overwrite" and "--ignore_duplicate_subblocks" --- app/CZIcompress.cpp | 6 +++--- lib/include/commandlineoptions.h | 7 ++++++- lib/src/commandlineoptions.cpp | 28 ++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/app/CZIcompress.cpp b/app/CZIcompress.cpp index 6653524..43f72dd 100644 --- a/app/CZIcompress.cpp +++ b/app/CZIcompress.cpp @@ -95,11 +95,11 @@ int main(int argc, char** argv) // Create an "output-stream-object" const auto output_stream = - libCZI::CreateOutputStreamForFile(utils::utf8::WidenUtf8(command_line_options.GetOutputFileName()).c_str(), false); + libCZI::CreateOutputStreamForFile(utils::utf8::WidenUtf8(command_line_options.GetOutputFileName()).c_str(), command_line_options.GetOverwriteExistingFile()); - // create the "CZI-writer"-object + // create (and configure) the "CZI-writer"-object libCZI::CZIWriterOptions czi_writer_options; - czi_writer_options.allow_duplicate_subblocks = true; + czi_writer_options.allow_duplicate_subblocks = command_line_options.GetIgnoreDuplicateSubblocks(); const auto writer = libCZI::CreateCZIWriter(&czi_writer_options); // GUID_NULL here means that a new Guid is created diff --git a/lib/include/commandlineoptions.h b/lib/include/commandlineoptions.h index e16f982..64cdc1b 100644 --- a/lib/include/commandlineoptions.h +++ b/lib/include/commandlineoptions.h @@ -29,7 +29,8 @@ class CommandLineOptions std::string output_filename_; CompressionStrategy compression_strategy_{CompressionStrategy::kInvalid}; libCZI::Utils::CompressionOption compression_option_; - + bool overwrite_existing_file_{false}; + bool ignore_duplicate_subblocks_{true}; public: /// Values that represent the result of the "Parse"-operation. enum class ParseResult @@ -91,6 +92,10 @@ class CommandLineOptions /// \returns The compression option. const libCZI::Utils::CompressionOption& GetCompressionOption() const { return this->compression_option_; } + bool GetOverwriteExistingFile() const { return this->overwrite_existing_file_; } + + bool GetIgnoreDuplicateSubblocks() const { return this->ignore_duplicate_subblocks_; } + private: static std::string GetFooterText(); }; diff --git a/lib/src/commandlineoptions.cpp b/lib/src/commandlineoptions.cpp index dd4f343..07e9169 100644 --- a/lib/src/commandlineoptions.cpp +++ b/lib/src/commandlineoptions.cpp @@ -42,8 +42,9 @@ class CustomFormatter : public CLI::Formatter usage << result_from_stock_implementation << endl << " version: " << CZICOMPRESS_VERSION_MAJOR << "." << CZICOMPRESS_VERSION_MINOR << "." << CZICOMPRESS_VERSION_PATCH; std::string tweak(CZICOMPRESS_VERSION_TWEAK); - if (!tweak.empty()) { - usage << "." << tweak; + if (!tweak.empty()) + { + usage << "." << tweak; } usage << endl; return usage.str(); @@ -144,6 +145,18 @@ CommandLineOptions::ParseResult CommandLineOptions::Parse(int argc, const char* string source_filename; // NOLINT(misc-const-correctness) string destination_filename; // NOLINT(misc-const-correctness) string compression_options_text; // NOLINT(misc-const-correctness) + bool overwrite_existing_file{false}; + bool ignore_duplicate_subblocks{false}; + + // specify the string-to-enum-mapping for a boolean option + std::map map_string_to_boolean{ + {"0", false}, + {"false", false}, + {"no", false}, + {"1", true}, + {"true", true}, + {"yes", true}, + }; // specify the string-to-enum-mapping for "command" const std::map map_string_to_command{{"compress", Command::kCompress}, {"decompress", Command::kDecompress}}; @@ -188,6 +201,14 @@ CommandLineOptions::ParseResult CommandLineOptions::Parse(int argc, const char* ->option_text("COMPRESSION_OPTIONS") ->default_val(CommandLineOptions::kDefaultCompressionOptions); + app.add_flag("-w,--overwrite", overwrite_existing_file, "If the output file exists, try to overwrite it."); + app.add_option("--ignore_duplicate_subblocks", ignore_duplicate_subblocks, + "If this option is enabled, the operation will ignore if duplicate subblocks are encountered in the source document. " + "Otherwise, an error will be reported. The default is 'on'.") + ->option_text("BOOLEAN") + ->default_val(true) + ->transform(CLI::CheckedTransformer(map_string_to_boolean, CLI::ignore_case)); + const auto formatter = make_shared(); app.formatter(formatter); app.footer(CommandLineOptions::GetFooterText()); @@ -217,6 +238,9 @@ CommandLineOptions::ParseResult CommandLineOptions::Parse(int argc, const char* this->compression_option_ = libCZI::Utils::ParseCompressionOptions(compression_options_text); } + this->overwrite_existing_file_ = overwrite_existing_file; + this->ignore_duplicate_subblocks_ = ignore_duplicate_subblocks; + return CommandLineOptions::ParseResult::kOk; } From 0f4a2cd4589ec671415ffd421a3d0c9a09f56638 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 20 Oct 2023 23:10:53 +0200 Subject: [PATCH 3/9] readme --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c408332..62c4af3 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,9 @@ Clicking on these artifacts will download a ZIP file with the executable. The ex Start the executable from the command line, providing the required command line arguments. ``` -Usage: czicompress [OPTIONS] +Usage: czicompress.exe [OPTIONS] + + version: 0.4.2.0 Options: -h,--help Print this help message and exit @@ -72,6 +74,13 @@ Options: Specify compression parameters. The default is 'zstd1:ExplicitLevel=1;PreProcess=HiLoByteUnpack'. + -w,--overwrite If the output file exists, try to overwrite it. + + --ignore_duplicate_subblocks BOOLEAN + If this option is enabled, the operation will ignore if + duplicate subblocks are encountered in the source document. + Otherwise, an error will be reported. The default is 'on'. + Copies the content of a CZI-file into another CZI-file changing the compression of the image data. From 2594f27ace17d44ef3232b09e9dd558d343766e8 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 20 Oct 2023 23:14:27 +0200 Subject: [PATCH 4/9] for the CAPI, enable "allow_duplicate_subblocks" --- capi/capi.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/capi/capi.cpp b/capi/capi.cpp index 85c4d2d..c6e276a 100644 --- a/capi/capi.cpp +++ b/capi/capi.cpp @@ -46,10 +46,12 @@ class FileProcessor final open_options.ignore_sizem_for_pyramid_subblocks = true; reader->Open(stream, &open_options); - // create the "CZI-writer"-object + // create (and configure) the "CZI-writer"-object const std::string output_string(output_path); const auto output_stream = libCZI::CreateOutputStreamForFile(utils::utf8::WidenUtf8(output_string).c_str(), false); + libCZI::CZIWriterOptions czi_writer_options; + czi_writer_options.allow_duplicate_subblocks = true; const auto writer = libCZI::CreateCZIWriter(); // GUID_NULL here means that a new Guid is created From 43e29e95d440996d608c0440153141f920e7ae51 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 20 Oct 2023 23:23:48 +0200 Subject: [PATCH 5/9] cosmetic --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7313107..c470247 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ cmake_policy(SET CMP0091 NEW) # enable new "MSVC runtime library selection" (htt # Note that the CMake-variables _VERSION_MAJOR, _VERSION_MINOR, ... are defined by this statement, # which are used in the build (so that - if changing the name here, change also the usage of those variables). project ("czicompress" - VERSION 0.4.2) + VERSION 0.5.0) set(czicompress_VERSION_PATCH_FLAGS "-alpha") set(czicompress_VERSION_TWEAK_FLAGS "") @@ -28,9 +28,10 @@ message (STATUS "[${PROJECT_NAME}] Processing ${CMAKE_CURRENT_LIST_FILE}") include(FetchContent) FetchContent_Declare( libczi - #GIT_REPOSITORY https://github.com/ZEISS/libczi.git GIT_REPOSITORY https://github.com/ptahmose/libczi-zeiss GIT_TAG jbl/1036970-more_lax_checking_for_duplicte_subblocks + # ***** CHANGE BEFORE MERGING INTO MAINLINE ***** + #GIT_REPOSITORY https://github.com/ZEISS/libczi.git #GIT_TAG c9954d58759ef6dd7d7c6a53c163ea8349855392 ) From 5cdceb4d8b53807c8653282c2258ed2fd3e5ca94 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Fri, 20 Oct 2023 23:28:02 +0200 Subject: [PATCH 6/9] cosmetic --- lib/include/commandlineoptions.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/include/commandlineoptions.h b/lib/include/commandlineoptions.h index 64cdc1b..5cee293 100644 --- a/lib/include/commandlineoptions.h +++ b/lib/include/commandlineoptions.h @@ -92,8 +92,14 @@ class CommandLineOptions /// \returns The compression option. const libCZI::Utils::CompressionOption& GetCompressionOption() const { return this->compression_option_; } + /// Gets a boolean indicating whether when creating the output file, it is to be overwritten if it already exists. + /// + /// \returns True if an existing file is to be overwritten (if it exists); false otherwise. bool GetOverwriteExistingFile() const { return this->overwrite_existing_file_; } + /// Gets a boolean indicating whether the CZIWriter object should be configured to ignore duplicate subblocks. + /// + /// \returns True if duplicate subblocks are to be ignore (with the CZIWriter object); false otherwise. bool GetIgnoreDuplicateSubblocks() const { return this->ignore_duplicate_subblocks_; } private: From 7dba4db766952ae2248c1849131b2b42bcd79433 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 23 Oct 2023 10:57:43 +0200 Subject: [PATCH 7/9] use latest upstream-libCZI (which includes the option-for-lax-duplicate-check) --- CMakeLists.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c470247..11ac7db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,11 +28,8 @@ message (STATUS "[${PROJECT_NAME}] Processing ${CMAKE_CURRENT_LIST_FILE}") include(FetchContent) FetchContent_Declare( libczi - GIT_REPOSITORY https://github.com/ptahmose/libczi-zeiss - GIT_TAG jbl/1036970-more_lax_checking_for_duplicte_subblocks - # ***** CHANGE BEFORE MERGING INTO MAINLINE ***** - #GIT_REPOSITORY https://github.com/ZEISS/libczi.git - #GIT_TAG c9954d58759ef6dd7d7c6a53c163ea8349855392 + GIT_REPOSITORY https://github.com/ZEISS/libczi.git + GIT_TAG 05bc1ebdca520ba2c5bfc3b9fcde76c548e98545 ) if(NOT libCZI_POPULATED) From 1e24186b9832c6d1b3222ffdbe5dfb26dc5691ad Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 23 Oct 2023 11:26:28 +0200 Subject: [PATCH 8/9] review --- capi/capi.cpp | 5 +++-- lib/include/commandlineoptions.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/capi/capi.cpp b/capi/capi.cpp index c6e276a..ad311c5 100644 --- a/capi/capi.cpp +++ b/capi/capi.cpp @@ -46,13 +46,14 @@ class FileProcessor final open_options.ignore_sizem_for_pyramid_subblocks = true; reader->Open(stream, &open_options); - // create (and configure) the "CZI-writer"-object + // create the stream-object representing the destination file const std::string output_string(output_path); const auto output_stream = libCZI::CreateOutputStreamForFile(utils::utf8::WidenUtf8(output_string).c_str(), false); + // create (and configure) the "CZI-writer"-object - it is configured to ignore "duplicate subblocks" libCZI::CZIWriterOptions czi_writer_options; czi_writer_options.allow_duplicate_subblocks = true; - const auto writer = libCZI::CreateCZIWriter(); + const auto writer = libCZI::CreateCZIWriter(&czi_writer_options); // GUID_NULL here means that a new Guid is created const auto czi_writer_info = std::make_shared(libCZI::GUID{0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}); diff --git a/lib/include/commandlineoptions.h b/lib/include/commandlineoptions.h index 5cee293..b238b82 100644 --- a/lib/include/commandlineoptions.h +++ b/lib/include/commandlineoptions.h @@ -99,7 +99,7 @@ class CommandLineOptions /// Gets a boolean indicating whether the CZIWriter object should be configured to ignore duplicate subblocks. /// - /// \returns True if duplicate subblocks are to be ignore (with the CZIWriter object); false otherwise. + /// \returns True if duplicate subblocks are to be ignored (with the CZIWriter object); false otherwise. bool GetIgnoreDuplicateSubblocks() const { return this->ignore_duplicate_subblocks_; } private: From 94f130292bbd28914f469986c04595ab9abc9911 Mon Sep 17 00:00:00 2001 From: ptahmose Date: Mon, 23 Oct 2023 11:27:09 +0200 Subject: [PATCH 9/9] review --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 62c4af3..e4edf96 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,6 @@ Start the executable from the command line, providing the required command line ``` Usage: czicompress.exe [OPTIONS] - version: 0.4.2.0 - Options: -h,--help Print this help message and exit