libCZI
Reading and Writing CZI documents made easy
Loading...
Searching...
No Matches
libCZI_DimCoordinate.h
1// SPDX-FileCopyrightText: 2017-2022 Carl Zeiss Microscopy GmbH
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
5#pragma once
6
7#include "ImportExport.h"
8#include "libCZI_exceptions.h"
9#include <cstdint>
10#include <functional>
11#include <initializer_list>
12
13namespace libCZI
14{
16 enum class DimensionIndex : std::uint8_t
17 {
18 invalid = 0,
19
20 MinDim = 1,
21
22 Z = 1,
23 C = 2,
24 T = 3,
25 R = 4,
26 S = 5,
27 I = 6,
28 H = 7,
29 V = 8,
30 B = 9,
31
32 MaxDim = 9
33 };
34
36 class LIBCZI_API IDimCoordinate
37 {
38 public:
39
46 virtual bool TryGetPosition(DimensionIndex dim, int* coordinate) const = 0;
47
48 virtual ~IDimCoordinate() = default;
49
55 inline bool IsValid(DimensionIndex dim) const
56 {
57 return this->TryGetPosition(dim, nullptr);
58 }
59
63 inline int GetNumberOfValidDimensions() const
64 {
65 int cnt = 0;
66 for (auto i = static_cast<std::underlying_type<libCZI::DimensionIndex>::type>(libCZI::DimensionIndex::MinDim); i <= static_cast<std::underlying_type<libCZI::DimensionIndex>::type>(libCZI::DimensionIndex::MaxDim); ++i)
67 {
68 if (this->IsValid(static_cast<libCZI::DimensionIndex>(i)))
69 {
70 ++cnt;
71 }
72 }
73
74 return cnt;
75 }
76 };
77
79 class LIBCZI_API IDimBounds
80 {
81 public:
82
88 virtual bool TryGetInterval(DimensionIndex dim, int* startIndex, int* size) const = 0;
89
90 virtual ~IDimBounds() = default;
91
95 inline bool IsValid(DimensionIndex dim) const
96 {
97 return this->TryGetInterval(dim, nullptr, nullptr);
98 }
99 };
100
103 class LIBCZI_API IIndexSet
104 {
105 public:
106
112 virtual bool IsContained(int index) const = 0;
113
114 virtual ~IIndexSet() = default;
115 };
116
123
131
133 class LIBCZI_API CDimBase
134 {
135 protected:
139 static std::underlying_type<libCZI::DimensionIndex>::type GetBitIndexForDimension(libCZI::DimensionIndex dim)
140 {
141 // TODO: add checks and asserts
142 auto i = ((std::underlying_type<libCZI::DimensionIndex>::type)dim) - 1;
143 return i;
144 }
145 };
146
148 class LIBCZI_API CDimCoordinate : public CDimBase, public libCZI::IDimCoordinate
149 {
150 private:
151 std::uint32_t validDims;
152 int values[static_cast<int>(libCZI::DimensionIndex::MaxDim)];
153 public:
155 CDimCoordinate() : validDims(0) {}
156
165 CDimCoordinate(std::initializer_list<DimensionAndValue> list) : CDimCoordinate()
166 {
167 for (const auto& d : list)
168 {
169 this->Set(d.dimension, d.value);
170 }
171 }
172
177 {
178 if (other != nullptr)
179 {
180 for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
181 {
182 int coord;
183 if (other->TryGetPosition((libCZI::DimensionIndex)i, &coord))
184 {
185 this->Set((libCZI::DimensionIndex)i, coord);
186 }
187 }
188 }
189 }
190
195 void Set(libCZI::DimensionIndex dimension, int value)
196 {
197 int index = CDimCoordinate::GetBitIndexForDimension(dimension);
198 this->values[index] = value;
199 this->validDims |= (1 << index);
200 }
201
206 {
207 int index = CDimCoordinate::GetBitIndexForDimension(dimension);
208 this->validDims &= ~(1 << index);
209 }
210
212 void Clear()
213 {
214 this->validDims = 0;
215 }
216
222 void EnumValidDimensions(const std::function<bool(libCZI::DimensionIndex dim, int value)>& func) const
223 {
224 for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
225 {
226 int bitIndex = CDimCoordinate::GetBitIndexForDimension((libCZI::DimensionIndex)i);
227 if ((this->validDims & (1 << bitIndex)) != 0)
228 {
229 if (func((libCZI::DimensionIndex)i, this->values[bitIndex]) != true)
230 break;
231 }
232 }
233 }
234
237 {
238 int count = 0;
239 for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
240 {
241 int bitIndex = CDimCoordinate::GetBitIndexForDimension((libCZI::DimensionIndex)i);
242 if ((this->validDims & (1 << bitIndex)) != 0)
243 {
244 ++count;
245 }
246 }
247
248 return count;
249 }
250
267 static CDimCoordinate Parse(const char* str);
268 public: // IDimCoordinate
269 bool TryGetPosition(libCZI::DimensionIndex dim, int* coordinate) const override
270 {
271 const int index = CDimCoordinate::GetBitIndexForDimension(dim);
272 if ((this->validDims & (1 << index)) != 0)
273 {
274 if (coordinate != nullptr)
275 {
276 *coordinate = this->values[index];
277 }
278
279 return true;
280 }
281
282 return false;
283 }
284 };
285
287 class LIBCZI_API CDimBounds : public CDimBase, public libCZI::IDimBounds
288 {
289 private:
290 std::uint32_t validDims;
291 int start[static_cast<int>(libCZI::DimensionIndex::MaxDim)];
292 int size[static_cast<int>(libCZI::DimensionIndex::MaxDim)];
293 public:
295 CDimBounds() : validDims(0) {}
296
300 explicit CDimBounds(const IDimBounds* other) : validDims(0)
301 {
302 if (other != nullptr)
303 {
304 for (int i = static_cast<int>(libCZI::DimensionIndex::MinDim); i <= static_cast<int>(libCZI::DimensionIndex::MaxDim); ++i)
305 {
306 int start, size;
307 if (other->TryGetInterval(static_cast<DimensionIndex>(i), &start, &size))
308 {
309 this->Set(static_cast<DimensionIndex>(i), start, size);
310 }
311 }
312 }
313 }
314
317 CDimBounds(std::initializer_list<DimensionAndStartSize> list) : CDimBounds()
318 {
319 for (auto d : list)
320 {
321 this->Set(d.dimension, d.start, d.size);
322 }
323 }
324
329 void Set(libCZI::DimensionIndex dimension, int start, int size)
330 {
331 const int index = CDimBounds::GetBitIndexForDimension(dimension);
332 this->start[index] = start;
333 this->size[index] = size;
334 this->validDims |= (1 << index);
335 }
336
339 void EnumValidDimensions(const std::function<bool(libCZI::DimensionIndex dim, int start, int size)>& func) const
340 {
341 for (int i = static_cast<int>(libCZI::DimensionIndex::MinDim); i <= static_cast<int>(libCZI::DimensionIndex::MaxDim); ++i)
342 {
343 const int bitIndex = CDimBase::GetBitIndexForDimension(static_cast<libCZI::DimensionIndex>(i));
344 if ((this->validDims & (1 << bitIndex)) != 0)
345 {
346 if (func(static_cast<libCZI::DimensionIndex>(i), this->start[bitIndex], this->size[bitIndex]) != true)
347 {
348 break;
349 }
350 }
351 }
352 }
353
357 {
358 int index = CDimBounds::GetBitIndexForDimension(dimension);
359 this->validDims &= ~(1 << index);
360 }
361
363 void Clear()
364 {
365 this->validDims = 0;
366 }
367
371 bool IsEmpty() const
372 {
373 return this->validDims == 0;
374 }
375
390 static CDimBounds Parse(const char* str);
391
392 public: // IDimBounds
398 bool TryGetInterval(libCZI::DimensionIndex dim, int* startIndex, int* size) const override
399 {
400 const int index = CDimBounds::GetBitIndexForDimension(dim);
401 if ((this->validDims & (1 << index)) != 0)
402 {
403 if (startIndex != nullptr)
404 {
405 *startIndex = this->start[index];
406 }
407
408 if (size != nullptr)
409 {
410 *size = this->size[index];
411 }
412
413 return true;
414 }
415
416 return false;
417 }
418 };
419}
Base class containing some commonly used methods.
Definition libCZI_DimCoordinate.h:134
static std::underlying_type< libCZI::DimensionIndex >::type GetBitIndexForDimension(libCZI::DimensionIndex dim)
Definition libCZI_DimCoordinate.h:139
Implementation of a class representing an interval (and implementing the libCZI::IDimBounds-interface...
Definition libCZI_DimCoordinate.h:288
static CDimBounds Parse(const char *str)
CDimBounds(const IDimBounds *other)
Definition libCZI_DimCoordinate.h:300
void EnumValidDimensions(const std::function< bool(libCZI::DimensionIndex dim, int start, int size)> &func) const
Definition libCZI_DimCoordinate.h:339
bool TryGetInterval(libCZI::DimensionIndex dim, int *startIndex, int *size) const override
Definition libCZI_DimCoordinate.h:398
void Set(libCZI::DimensionIndex dimension, int start, int size)
Definition libCZI_DimCoordinate.h:329
void Clear()
Clears this object to its blank/initial state. All dimensions will be set to invalid.
Definition libCZI_DimCoordinate.h:363
CDimBounds()
Default constructor - the object will contain no valid dimension.
Definition libCZI_DimCoordinate.h:295
bool IsEmpty() const
Definition libCZI_DimCoordinate.h:371
void Clear(libCZI::DimensionIndex dimension)
Definition libCZI_DimCoordinate.h:356
CDimBounds(std::initializer_list< DimensionAndStartSize > list)
Definition libCZI_DimCoordinate.h:317
Implementation of a class representing a coordinate (and implementing the IDimCoordinate-interface).
Definition libCZI_DimCoordinate.h:149
CDimCoordinate(std::initializer_list< DimensionAndValue > list)
Definition libCZI_DimCoordinate.h:165
CDimCoordinate()
Default constructor which constructs an empty coordinate (no valid dimensions).
Definition libCZI_DimCoordinate.h:155
static CDimCoordinate Parse(const char *str)
int GetValidDimensionsCount() const
Determine the number the valid dimensions contained in this coordinate.
Definition libCZI_DimCoordinate.h:236
CDimCoordinate(const libCZI::IDimCoordinate *other)
Definition libCZI_DimCoordinate.h:176
void Set(libCZI::DimensionIndex dimension, int value)
Definition libCZI_DimCoordinate.h:195
void EnumValidDimensions(const std::function< bool(libCZI::DimensionIndex dim, int value)> &func) const
Definition libCZI_DimCoordinate.h:222
void Clear(libCZI::DimensionIndex dimension)
Definition libCZI_DimCoordinate.h:205
bool TryGetPosition(libCZI::DimensionIndex dim, int *coordinate) const override
Definition libCZI_DimCoordinate.h:269
void Clear()
Clears the validity of all dimensions.
Definition libCZI_DimCoordinate.h:212
Interface used to represent an interval (for several dimensions).
Definition libCZI_DimCoordinate.h:80
virtual bool TryGetInterval(DimensionIndex dim, int *startIndex, int *size) const =0
bool IsValid(DimensionIndex dim) const
Definition libCZI_DimCoordinate.h:95
Interface used to represent a coordinate (in the space of the dimensions identified by DimensionIndex...
Definition libCZI_DimCoordinate.h:37
virtual bool TryGetPosition(DimensionIndex dim, int *coordinate) const =0
bool IsValid(DimensionIndex dim) const
Definition libCZI_DimCoordinate.h:55
int GetNumberOfValidDimensions() const
Definition libCZI_DimCoordinate.h:63
Definition libCZI_DimCoordinate.h:104
virtual bool IsContained(int index) const =0
External interfaces, classes, functions and structs are found in the namespace "libCZI".
Definition libCZI.h:31
DimensionIndex
Values that represent dimension indexes.
Definition libCZI_DimCoordinate.h:17
@ C
The C-dimension ("channel").
@ MaxDim
This enum must be have the value of the highest (valid) dimension index.
@ Z
The Z-dimension.
@ MinDim
This enum must be have the value of the lowest (valid) dimension index.
@ V
The V-dimension ("view").
@ S
The S-dimension ("scene").
@ B
The B-dimension ("block") - its use is deprecated.
@ T
The T-dimension ("time").
@ H
The H-dimension ("phase").
@ I
The I-dimension ("illumination").
@ R
The R-dimension ("rotation").
@ invalid
Invalid dimension index.
A structure combining a dimension and an interval (defined by a start value and the size).
Definition libCZI_DimCoordinate.h:126
libCZI::DimensionIndex dimension
The dimension.
Definition libCZI_DimCoordinate.h:127
int start
The start value.
Definition libCZI_DimCoordinate.h:128
int size
The size.
Definition libCZI_DimCoordinate.h:129
A structure combining a dimension and a value.
Definition libCZI_DimCoordinate.h:119
libCZI::DimensionIndex dimension
The dimension.
Definition libCZI_DimCoordinate.h:120
int value
The value (for this dimension).
Definition libCZI_DimCoordinate.h:121