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

adding ability to use a cache with accessors #84

Merged
merged 42 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
20f209e
draft
ptahmose Dec 2, 2023
a533f5a
cosmetic
ptahmose Dec 2, 2023
7f6c225
add subblock-cache to ISingleChannelScalingTileAccessor
ptahmose Dec 2, 2023
ed583b0
add caching to CSingleChannelPyramidLevelTileAccessor
ptahmose Dec 2, 2023
d5f7f9c
cosmetic
ptahmose Dec 2, 2023
e9880ac
update
ptahmose Dec 2, 2023
40c83e8
cosmetic
ptahmose Dec 2, 2023
2ba4c00
fix incompatibility with older GCC (8.3)
ptahmose Dec 2, 2023
eb0e357
update
ptahmose Dec 3, 2023
8503b5f
update
ptahmose Dec 3, 2023
8504141
update
ptahmose Dec 4, 2023
9362831
update
ptahmose Dec 4, 2023
53e5b6b
cosmetic
ptahmose Dec 4, 2023
3996d9f
cosmetic
ptahmose Dec 4, 2023
6d7254a
Merge branch 'main' into jbl/#77-caching
ptahmose Dec 4, 2023
4f4ea8d
bump version
ptahmose Dec 4, 2023
8033658
cosmetic, start with "plane-scan"
ptahmose Dec 4, 2023
27adf72
update
ptahmose Dec 5, 2023
3c9c4f4
update
ptahmose Dec 5, 2023
f594154
update
ptahmose Dec 5, 2023
a02b8ed
update - make option "cachesize" operational
ptahmose Dec 5, 2023
c3311b0
fix bug with parsing command line option "background"
ptahmose Nov 19, 2023
e1ee676
update
ptahmose Dec 5, 2023
8903ea7
cleanup
ptahmose Dec 5, 2023
74c0144
cosmetic
ptahmose Dec 5, 2023
9c87211
update
ptahmose Dec 5, 2023
57f9112
cosmetic
ptahmose Dec 5, 2023
4630017
review
ptahmose Dec 5, 2023
56d48b2
cosmetic
ptahmose Dec 5, 2023
b8f8bc5
cosmetic
ptahmose Dec 5, 2023
374c512
Merge branch 'main' into jbl/#77-caching
ptahmose Dec 5, 2023
a6aae3e
version-history
ptahmose Dec 5, 2023
a3d37bb
typo
ptahmose Dec 5, 2023
7903d4d
cosmetic
ptahmose Dec 5, 2023
94341a1
add unittest
ptahmose Dec 6, 2023
bcee426
linter
ptahmose Dec 6, 2023
a2cb3ed
documentation
ptahmose Dec 6, 2023
a9538f2
cosmetic
ptahmose Dec 6, 2023
14a1579
cosmetic
ptahmose Dec 6, 2023
5859a86
Update Src/libCZI/libCZI_Compositor.h
ptahmose Dec 6, 2023
2cdc5cf
REUSE
ptahmose Dec 6, 2023
5ebc905
review
ptahmose Dec 6, 2023
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.56.0
VERSION 0.57.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
8 changes: 6 additions & 2 deletions Src/CZICmd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ endif()
FetchContent_Declare(
cli11
GIT_REPOSITORY https://github.com/CLIUtils/CLI11
GIT_TAG v2.2.0
GIT_TAG v2.3.2
ptahmose marked this conversation as resolved.
Show resolved Hide resolved
)

if (NOT cli11_POPULATED)
Expand Down Expand Up @@ -94,7 +94,11 @@ set (CZICMDSRCFILES
inc_rapidjson.h
BitmapGenNull.h
CZIcmd.cpp
platform_defines.h)
platform_defines.h
executePlaneScan.h
executePlaneScan.cpp
executeBase.h
executeBase.cpp)

add_executable(CZIcmd ${CZICMDSRCFILES})

Expand Down
182 changes: 175 additions & 7 deletions Src/CZICmd/cmdlineoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <iostream>
#include <utility>
#include <cstring>
#include <cmath>
#if defined(LINUXENV)
#include <libgen.h>
#endif
Expand Down Expand Up @@ -428,6 +429,47 @@ struct GeneratorPixelTypeValidator : public CLI::Validator
}
};

/// CLI11-validator for the option "--cachesize".
struct CachesizeValidator : public CLI::Validator
{
CachesizeValidator()
{
this->name_ = "CachesizeValidator";
this->func_ = [](const std::string& str) -> string
{
const bool parsed_ok = CCmdLineOptions::TryParseSubBlockCacheSize(str, nullptr);
if (!parsed_ok)
{
ostringstream string_stream;
string_stream << "Invalid subblock-cache-size given \"" << str << "\"";
throw CLI::ValidationError(string_stream.str());
}

return {};
};
}
};

struct TileSizeForPlaneScanValidator : public CLI::Validator
{
TileSizeForPlaneScanValidator()
{
this->name_ = "TileSizeForPlaneScanValidator";
this->func_ = [](const std::string& str) -> string
{
const bool parsed_ok = CCmdLineOptions::TryParseCreateSize(str, nullptr);
if (!parsed_ok)
{
ostringstream string_stream;
string_stream << "Invalid tile-size-plane-scan given \"" << str << "\"";
throw CLI::ValidationError(string_stream.str());
}

return {};
};
}
};

/// A custom formatter for CLI11 - used to have nicely formatted descriptions.
class CustomFormatter : public CLI::Formatter
{
Expand Down Expand Up @@ -497,6 +539,7 @@ CCmdLineOptions::ParseResult CCmdLineOptions::Parse(int argc, char** argv)
{ "ScalingChannelComposite", Command::ScalingChannelComposite },
{ "ExtractAttachment", Command::ExtractAttachment},
{ "CreateCZI", Command::CreateCZI },
{ "PlaneScan", Command::PlaneScan },
};

const static PlaneCoordinateValidator plane_coordinate_validator;
Expand All @@ -518,6 +561,8 @@ CCmdLineOptions::ParseResult CCmdLineOptions::Parse(int argc, char** argv)
const static CreateSubblockMetadataValidator createsubblockmetadata_validator;
const static CompressionOptionsValidator compressionoptions_validator;
const static GeneratorPixelTypeValidator generatorpixeltype_validator;
const static CachesizeValidator cachesize_validator;
const static TileSizeForPlaneScanValidator tile_size_for_plane_scan_validator;

Command argument_command;
string argument_source_filename;
Expand Down Expand Up @@ -546,9 +591,12 @@ CCmdLineOptions::ParseResult CCmdLineOptions::Parse(int argc, char** argv)
string argument_createczisubblockmetadata;
string argument_compressionoptions;
string argument_generatorpixeltype;
string argument_subblock_cachesize;
string argument_tilesize_for_scan;
bool argument_versionflag = false;
string argument_source_stream_class;
string argument_source_stream_creation_propbag;
bool argument_use_visibility_check_optimization = false;

// editorconfig-checker-disable
cli_app.add_option("-c,--command", argument_command,
Expand All @@ -569,7 +617,12 @@ CCmdLineOptions::ParseResult CCmdLineOptions::Parse(int argc, char** argv)
\N'ScalingChannelComposite' operates like the previous command, but in addition gets all channels and creates a multi-channel-composite from them
using display-settings.
\N'ExtractAttachment' allows to extract (and save to a file) the contents of attachments.)
\N'CreateCZI' is used to demonstrate the CZI-creation capabilities of libCZI.)")
\N'CreateCZI' is used to demonstrate the CZI-creation capabilities of libCZI.)
\N'PlaneScan' does the following: over a ROI given with the --rect option a rectangle of size given with
ptahmose marked this conversation as resolved.
Show resolved Hide resolved
the --tilesize-for-plane-scan option is moved, and the image content of this rectangle is written out to
files. The operation takes place on a plane which is given with the --plane-coordinate option. The filenames of the
tile-bitmaps are generated from the filename given with the --output option, where a string _X[x-position]_Y[y-position]_W[width]_H[height]
is added.)")
->default_val(Command::Invalid)
->option_text("COMMAND")
->transform(CLI::CheckedTransformer(map_string_to_command, CLI::ignore_case));
Expand Down Expand Up @@ -708,6 +761,18 @@ CCmdLineOptions::ParseResult CCmdLineOptions::Parse(int argc, char** argv)
"'Bgr24' or 'Bgr48'. Default is 'Bgr24'.")
->option_text("PIXELTYPE")
->check(generatorpixeltype_validator);
cli_app.add_option("--cachesize", argument_subblock_cachesize,
"Only used for 'PlaneScan' - specify the size of the subblock-cache in bytes. The argument is to "
ptahmose marked this conversation as resolved.
Show resolved Hide resolved
"be given with a suffix k, M, G, ...")
->option_text("CACHESIZE")
->check(cachesize_validator);
cli_app.add_option("--tilesize-for-plane-scan", argument_tilesize_for_scan,
"Only used for 'PlaneScan' - specify the size of ROI which is used for scanning the plane in "
"units of pixels. Format is e.g. '1600x1200' and default is 512x512.")
->option_text("TILESIZE")
->check(tile_size_for_plane_scan_validator);
cli_app.add_flag("--use-visibility-check-optimization", argument_use_visibility_check_optimization,
"Whether to enable the experimental \"visibility check optimization\" for the accessors.");
cli_app.add_flag("--version", argument_versionflag,
"Print extended version-info and supported operations, then exit.");

Expand Down Expand Up @@ -742,6 +807,7 @@ CCmdLineOptions::ParseResult CCmdLineOptions::Parse(int argc, char** argv)
this->calcHashOfResult = argument_calc_hash;
this->drawTileBoundaries = argument_drawtileboundaries;
this->command = argument_command;
this->useVisibilityCheckOptimization = argument_use_visibility_check_optimization;

try
{
Expand Down Expand Up @@ -901,6 +967,18 @@ CCmdLineOptions::ParseResult CCmdLineOptions::Parse(int argc, char** argv)
const bool b = TryParseGeneratorPixeltype(argument_generatorpixeltype, &this->pixelTypeForBitmapGenerator);
ThrowIfFalse(b, "--generatorpixeltype", argument_generatorpixeltype);
}

if (!argument_subblock_cachesize.empty())
{
const bool b = TryParseSubBlockCacheSize(argument_subblock_cachesize, &this->subBlockCacheSize);
ThrowIfFalse(b, "--cachesize", argument_subblock_cachesize);
}

if (!argument_tilesize_for_scan.empty())
{
const bool b = TryParseCreateSize(argument_tilesize_for_scan, &this->tilesSizeForPlaneScan);
ThrowIfFalse(b, "--tilesize-for-plane-scan", argument_tilesize_for_scan);
}
}
catch (runtime_error& exception)
{
Expand Down Expand Up @@ -1027,14 +1105,17 @@ void CCmdLineOptions::Clear()
this->sbBlkMetadataKeyValue.clear();
this->rectX = this->rectY = 0;
this->rectW = this->rectH = -1;;
this->zoom = -1;
this->zoom = 1;
this->pyramidLayerNo = -1;
this->pyramidMinificationFactor = -1;
this->createTileInfo.rows = this->createTileInfo.columns = 1;
this->createTileInfo.overlap = 0;
this->compressionMode = libCZI::CompressionMode::Invalid;
this->compressionParameters = nullptr;
this->pixelTypeForBitmapGenerator = libCZI::PixelType::Bgr24;
this->subBlockCacheSize = 0;
this->tilesSizeForPlaneScan = make_tuple(512, 512);
this->useVisibilityCheckOptimization = false;
}

bool CCmdLineOptions::IsLogLevelEnabled(int level) const
Expand Down Expand Up @@ -1458,13 +1539,15 @@ bool CCmdLineOptions::TryParseDisplaySettings(const std::string& s, std::map<int
{
if (color != nullptr)
{
*color = libCZI::RgbFloatColor{ f[0],f[0],f[0] };
*color = libCZI::RgbFloatColor{ f[0], f[0], f[0] };
}
}

if (color != nullptr)
else
{
*color = libCZI::RgbFloatColor{ f[0],f[1],f[2] };
if (color != nullptr)
{
*color = libCZI::RgbFloatColor{ f[0], f[1], f[2] };
}
}

return true;
Expand Down Expand Up @@ -2182,7 +2265,7 @@ void CCmdLineOptions::PrintHelpStreamsObjects()
// Here we parse the JSON-formatted string that contains the property bag for the input stream and
// construct a map<int, libCZI::StreamsFactory::Property> from it.

static constexpr struct
static constexpr struct
{
const char* name;
int stream_property_id;
Expand Down Expand Up @@ -2278,3 +2361,88 @@ void CCmdLineOptions::PrintHelpStreamsObjects()

return true;
}

/*static*/bool CCmdLineOptions::TryParseSubBlockCacheSize(const std::string& text, std::uint64_t* size)
{
// This regular expression is used to match strings that represent sizes in bytes, kilobytes, megabytes, gigabytes, terabytes, kibibytes, mebibytes, gibibytes, and tebibytes.
//
// Here is a breakdown of the regular expression:
//
// - ^\s*: Matches the start of the string, followed by any amount of whitespace.
// - ([+]?(?:[0-9]+(?:[.][0-9]*)?|[.][0-9]+)): Matches a positive number, which can be an integer or a decimal. The number may optionally be preceded by a plus sign.
// - \s*: Matches any amount of whitespace following the number.
// - (k|m|g|t|ki|mi|gi|ti): Matches one of the following units of size: k (kilobytes), m (megabytes), g (gigabytes), t (terabytes), ki (kibibytes), mi (mebibytes), gi (gibibytes), ti (tebibytes).
// - (?:b?): Optionally matches a 'b', which can be used to explicitly specify that the size is in bytes.
// - \s*$: Matches any amount of whitespace at the end of the string, followed by the end of the string.
//
// This regular expression is case-insensitive.
regex regex(R"(^\s*([+]?(?:[0-9]+(?:[.][0-9]*)?|[.][0-9]+))\s*(k|m|g|t|ki|mi|gi|ti)(?:b?)\s*$)", regex_constants::icase);
ptahmose marked this conversation as resolved.
Show resolved Hide resolved
ptahmose marked this conversation as resolved.
Show resolved Hide resolved
smatch match;
regex_search(text, match, regex);
if (match.size() != 3)
{
return false;
}

double number;

try
{
number = stod(match[1].str());
}
catch (invalid_argument&)
{
return false;
}
catch (out_of_range&)
{
return false;
}

uint64_t factor;
string suffix_string = match[2].str();
if (icasecmp(suffix_string, "k"))
{
factor = 1000;
}
else if (icasecmp(suffix_string, "ki"))
{
factor = 1024;
}
else if (icasecmp(suffix_string, "m"))
{
factor = 1000 * 1000;
}
else if (icasecmp(suffix_string, "mi"))
{
factor = 1024 * 1024;
}
else if (icasecmp(suffix_string, "g"))
{
factor = 1000 * 1000 * 1000;
}
else if (icasecmp(suffix_string, "gi"))
{
factor = 1024 * 1024 * 1024;
}
else if (icasecmp(suffix_string, "t"))
{
factor = 1000ULL * 1000 * 1000 * 1000;
}
else if (icasecmp(suffix_string, "ti"))
{
factor = 1024ULL * 1024 * 1024 * 1024;
}
else
{
return false;
}

const uint64_t memory_size = llround(number * static_cast<double>(factor));
if (size != nullptr)
{
*size = memory_size;
}

return true;
}
15 changes: 14 additions & 1 deletion Src/CZICmd/cmdlineoptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ enum class Command

CreateCZI,

ReadWriteCZI
ReadWriteCZI,

PlaneScan,
};

enum class InfoLevel : std::uint32_t
Expand Down Expand Up @@ -190,6 +192,11 @@ class CCmdLineOptions
libCZI::CompressionMode compressionMode;
std::shared_ptr<libCZI::ICompressParameters> compressionParameters;
libCZI::PixelType pixelTypeForBitmapGenerator;

std::uint64_t subBlockCacheSize; ///< The size of the sub-block cache in bytes.
std::tuple<std::uint32_t, std::uint32_t> tilesSizeForPlaneScan; ///< The size of the tiles in pixels for the plane scan operation.

bool useVisibilityCheckOptimization;
public:
/// Values that represent the result of the "Parse"-operation.
enum class ParseResult
Expand Down Expand Up @@ -257,6 +264,9 @@ class CCmdLineOptions
libCZI::CompressionMode GetCompressionMode() const { return this->compressionMode; }
std::shared_ptr<libCZI::ICompressParameters> GetCompressionParameters() const { return this->compressionParameters; }
libCZI::PixelType GetPixelGeneratorPixeltype() const { return this->pixelTypeForBitmapGenerator; }
std::uint64_t GetSubBlockCacheSize() const { return this->subBlockCacheSize; }
const std::tuple<std::uint32_t, std::uint32_t>& GetTileSizeForPlaneScan() const { return this->tilesSizeForPlaneScan; }
bool GetUseVisibilityCheckOptimization() const { return this->useVisibilityCheckOptimization; }
private:
friend struct RegionOfInterestValidator;
friend struct DisplaySettingsValidator;
Expand All @@ -276,6 +286,8 @@ class CCmdLineOptions
friend struct CreateSubblockMetadataValidator;
friend struct CompressionOptionsValidator;
friend struct GeneratorPixelTypeValidator;
friend struct CachesizeValidator;
friend struct TileSizeForPlaneScanValidator;

bool CheckArgumentConsistency() const;
void SetOutputFilename(const std::wstring& s);
Expand Down Expand Up @@ -307,6 +319,7 @@ class CCmdLineOptions
static bool TryParseCompressionOptions(const std::string& s, libCZI::Utils::CompressionOption* compression_option);
static bool TryParseGeneratorPixeltype(const std::string& s, libCZI::PixelType* pixel_type);
static bool TryParseInputStreamCreationPropertyBag(const std::string& s, std::map<int, libCZI::StreamsFactory::Property>* property_bag);
static bool TryParseSubBlockCacheSize(const std::string& text, std::uint64_t* size);

static void ThrowIfFalse(bool b, const std::string& argument_switch, const std::string& argument);
};
Loading
Loading