libCZI
Reading CZI documents made easy
libCZI_DimCoordinate.h
1 //******************************************************************************
2 //
3 // libCZI is a reader for the CZI fileformat written in C++
4 // Copyright (C) 2017 Zeiss Microscopy GmbH
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 // To obtain a commercial version please contact Zeiss Microscopy GmbH.
20 //
21 //******************************************************************************
22 
23 #pragma once
24 
25 #include "ImportExport.h"
26 #include "libCZI_exceptions.h"
27 #include <cstdint>
28 #include <functional>
29 #include <initializer_list>
30 
31 namespace libCZI
32 {
34  enum class DimensionIndex : std::uint8_t
35  {
36  invalid = 0,
37 
38  MinDim = 1,
39 
40  Z = 1,
41  C = 2,
42  T = 3,
43  R = 4,
44  S = 5,
45  I = 6,
46  H = 7,
47  V = 8,
48  B = 9,
49 
50  MaxDim = 9
51  };
52 
54  class LIBCZI_API IDimCoordinate
55  {
56  public:
57 
64  virtual bool TryGetPosition(DimensionIndex dim, int* coordinate) const = 0;
65 
71  inline bool IsValid(DimensionIndex dim) const
72  {
73  return this->TryGetPosition(dim, nullptr);
74  }
75 
79  inline int GetNumberOfValidDimensions() const
80  {
81  int cnt = 0;
82  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)
83  {
84  if (this->IsValid(static_cast<libCZI::DimensionIndex>(i)))
85  {
86  ++cnt;
87  }
88  }
89 
90  return cnt;
91  }
92  };
93 
95  class LIBCZI_API IDimBounds
96  {
97  public:
98 
104  virtual bool TryGetInterval(DimensionIndex dim, int* startIndex, int* size) const = 0;
105 
109  inline bool IsValid(DimensionIndex dim) const
110  {
111  return this->TryGetInterval(dim, nullptr, nullptr);
112  }
113  };
114 
117  class LIBCZI_API IIndexSet
118  {
119  public:
120 
126  virtual bool IsContained(int index) const = 0;
127  };
128 
131  {
133  int value;
134  };
135 
138  {
140  int start;
141  int size;
142  };
143 
145  class LIBCZI_API CDimBase
146  {
147  protected:
151  static std::underlying_type<libCZI::DimensionIndex>::type GetBitIndexForDimension(libCZI::DimensionIndex dim)
152  {
153  // TODO: add checks and asserts
154  auto i = ((std::underlying_type<libCZI::DimensionIndex>::type)dim) - 1;
155  return i;
156  }
157  };
158 
160  class LIBCZI_API CDimCoordinate : public CDimBase, public libCZI::IDimCoordinate
161  {
162  private:
163  std::uint32_t validDims;
164  int values[(int)(libCZI::DimensionIndex::MaxDim)];
165  public:
167  CDimCoordinate() : validDims(0) {}
168 
177  CDimCoordinate(std::initializer_list<DimensionAndValue> list) : CDimCoordinate()
178  {
179  for (auto d : list)
180  {
181  this->Set(d.dimension, d.value);
182  }
183  }
184 
189  {
190  if (other != nullptr)
191  {
192  for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
193  {
194  int coord;
195  if (other->TryGetPosition((libCZI::DimensionIndex)i, &coord))
196  {
197  this->Set((libCZI::DimensionIndex)i, coord);
198  }
199  }
200  }
201  }
202 
207  void Set(libCZI::DimensionIndex dimension, int value)
208  {
209  int index = CDimCoordinate::GetBitIndexForDimension(dimension);
210  this->values[index] = value;
211  this->validDims |= (1 << index);
212  }
213 
218  {
219  auto index = CDimCoordinate::GetBitIndexForDimension(dimension);
220  this->validDims &= ~(1 << index);
221  }
222 
224  void Clear()
225  {
226  this->validDims = 0;
227  }
228 
234  void EnumValidDimensions(std::function<bool(libCZI::DimensionIndex dim, int value)> func) const
235  {
236  for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
237  {
239  if ((this->validDims & (1 << bitIndex)) != 0)
240  {
241  if (func((libCZI::DimensionIndex) i, this->values[bitIndex]) != true)
242  break;
243  }
244  }
245  }
246 
249  {
250  int count = 0;
251  for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
252  {
254  if ((this->validDims & (1 << bitIndex)) != 0)
255  {
256  ++count;
257  }
258  }
259 
260  return count;
261  }
262 
279  static CDimCoordinate Parse(const char* str);
280  public: // IDimCoordinate
281  virtual bool TryGetPosition(libCZI::DimensionIndex dim, int* coordinate) const
282  {
283  auto index = CDimCoordinate::GetBitIndexForDimension(dim);
284  if ((this->validDims & (1 << index)) != 0)
285  {
286  if (coordinate != nullptr)
287  {
288  *coordinate = this->values[index];
289  }
290 
291  return true;
292  }
293 
294  return false;
295  }
296  };
297 
299  class LIBCZI_API CDimBounds : public CDimBase, public libCZI::IDimBounds
300  {
301  private:
302  std::uint32_t validDims;
303  int start[(int)(libCZI::DimensionIndex::MaxDim)];
304  int size[(int)(libCZI::DimensionIndex::MaxDim)];
305  public:
307  CDimBounds() : validDims(0) {};
308 
312  CDimBounds(const IDimBounds* other) : validDims(0)
313  {
314  if (other != nullptr)
315  {
316  for (int i = static_cast<int>(libCZI::DimensionIndex::MinDim); i <= static_cast<int>(libCZI::DimensionIndex::MaxDim); ++i)
317  {
318  int start, size;
319  if (other->TryGetInterval(static_cast<DimensionIndex>(i), &start, &size))
320  {
321  this->Set(static_cast<DimensionIndex>(i), start, size);
322  }
323  }
324  }
325  }
326 
329  CDimBounds(std::initializer_list<DimensionAndStartSize> list) : CDimBounds()
330  {
331  for (auto d : list)
332  {
333  this->Set(d.dimension, d.start, d.size);
334  }
335  }
336 
341  void Set(libCZI::DimensionIndex dimension, int start, int size)
342  {
343  int index = CDimBounds::GetBitIndexForDimension(dimension);
344  this->start[index] = start;
345  this->size[index] = size;
346  this->validDims |= (1 << index);
347  }
348 
351  void EnumValidDimensions(std::function<bool(libCZI::DimensionIndex dim, int start, int size)> func) const
352  {
353  for (int i = (int)(libCZI::DimensionIndex::MinDim); i <= (int)(libCZI::DimensionIndex::MaxDim); ++i)
354  {
356  if ((this->validDims & (1 << bitIndex)) != 0)
357  {
358  if (func((libCZI::DimensionIndex) i, this->start[bitIndex], this->size[bitIndex]) != true)
359  break;
360  }
361  }
362  }
363 
367  {
368  int index = CDimBounds::GetBitIndexForDimension(dimension);
369  this->validDims &= ~(1 << index);
370  }
371 
373  void Clear()
374  {
375  this->validDims = 0;
376  }
377 
381  bool IsEmpty() const
382  {
383  return this->validDims == 0;
384  }
385 
400  static CDimBounds Parse(const char* str);
401 
402  public: // IDimBounds
408  virtual bool TryGetInterval(libCZI::DimensionIndex dim, int* startIndex, int* size) const
409  {
410  int index = CDimBounds::GetBitIndexForDimension(dim);
411  if ((this->validDims & (1 << index)) != 0)
412  {
413  if (startIndex != nullptr)
414  {
415  *startIndex = this->start[index];
416  }
417 
418  if (size != nullptr)
419  {
420  *size = this->size[index];
421  }
422 
423  return true;
424  }
425 
426  return false;
427  }
428  };
429 }
The C-dimension ("channel").
bool IsEmpty() const
Definition: libCZI_DimCoordinate.h:381
CDimBounds(const IDimBounds *other)
Definition: libCZI_DimCoordinate.h:312
The B-dimension ("block") - its use is deprecated.
libCZI::DimensionIndex dimension
The dimension.
Definition: libCZI_DimCoordinate.h:132
Invalid dimension index.
Interface used to represent an interval (for several dimensions).
Definition: libCZI_DimCoordinate.h:95
CDimCoordinate(const libCZI::IDimCoordinate *other)
Definition: libCZI_DimCoordinate.h:188
void EnumValidDimensions(std::function< bool(libCZI::DimensionIndex dim, int start, int size)> func) const
Definition: libCZI_DimCoordinate.h:351
The Z-dimension.
Base class containing some commonly used methods.
Definition: libCZI_DimCoordinate.h:145
Implementation of a class representing a coordinate (and implementing the IDimCoordinate-interface).
Definition: libCZI_DimCoordinate.h:160
void Set(libCZI::DimensionIndex dimension, int value)
Definition: libCZI_DimCoordinate.h:207
bool IsValid(DimensionIndex dim) const
Definition: libCZI_DimCoordinate.h:71
bool IsValid(DimensionIndex dim) const
Definition: libCZI_DimCoordinate.h:109
This enum must be have the value of the lowest (valid) dimension index.
The S-dimension ("scene").
The V-dimension ("view").
void Clear(libCZI::DimensionIndex dimension)
Definition: libCZI_DimCoordinate.h:366
The I-dimension ("illumination").
void Clear()
Clears the validity of all dimensions.
Definition: libCZI_DimCoordinate.h:224
void EnumValidDimensions(std::function< bool(libCZI::DimensionIndex dim, int value)> func) const
Definition: libCZI_DimCoordinate.h:234
virtual bool TryGetInterval(libCZI::DimensionIndex dim, int *startIndex, int *size) const
Definition: libCZI_DimCoordinate.h:408
Interface used to represent a coordinate (in the space of the dimensions identified by DimensionIndex...
Definition: libCZI_DimCoordinate.h:54
CDimCoordinate()
Default constructor which constructs an empty coordinate (no valid dimensions).
Definition: libCZI_DimCoordinate.h:167
void Set(libCZI::DimensionIndex dimension, int start, int size)
Definition: libCZI_DimCoordinate.h:341
int GetNumberOfValidDimensions() const
Definition: libCZI_DimCoordinate.h:79
CDimBounds()
Default constructor - the object will contain no valid dimension.
Definition: libCZI_DimCoordinate.h:307
Implementation of a class representing an interval (and implementing the libCZI::IDimBounds-interface...
Definition: libCZI_DimCoordinate.h:299
A structure combining a dimension and an interval (defined by a start value and the size)...
Definition: libCZI_DimCoordinate.h:137
A structure combining a dimension and a value.
Definition: libCZI_DimCoordinate.h:130
This enum must be have the value of the highest (valid) dimension index.
libCZI::DimensionIndex dimension
The dimension.
Definition: libCZI_DimCoordinate.h:139
int GetValidDimensionsCount() const
Determine the number the valid dimensions contained in this coordinate.
Definition: libCZI_DimCoordinate.h:248
External interfaces, classes, functions and structs are found in the namespace "libCZI".
Definition: libCZI.h:45
void Clear()
Clears this object to its blank/initial state. All dimensions will be set to invalid.
Definition: libCZI_DimCoordinate.h:373
DimensionIndex
Values that represent dimension indexes.
Definition: libCZI_DimCoordinate.h:34
virtual bool TryGetPosition(DimensionIndex dim, int *coordinate) const =0
Definition: libCZI_DimCoordinate.h:117
static std::underlying_type< libCZI::DimensionIndex >::type GetBitIndexForDimension(libCZI::DimensionIndex dim)
Definition: libCZI_DimCoordinate.h:151
int value
The value (for this dimension).
Definition: libCZI_DimCoordinate.h:133
virtual bool TryGetInterval(DimensionIndex dim, int *startIndex, int *size) const =0
CDimCoordinate(std::initializer_list< DimensionAndValue > list)
Definition: libCZI_DimCoordinate.h:177
The H-dimension ("phase").
int size
The size.
Definition: libCZI_DimCoordinate.h:141
virtual bool TryGetPosition(libCZI::DimensionIndex dim, int *coordinate) const
Definition: libCZI_DimCoordinate.h:281
int start
The start value.
Definition: libCZI_DimCoordinate.h:140
void Clear(libCZI::DimensionIndex dimension)
Definition: libCZI_DimCoordinate.h:217
CDimBounds(std::initializer_list< DimensionAndStartSize > list)
Definition: libCZI_DimCoordinate.h:329
The T-dimension ("time").
The R-dimension ("rotation").