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  };
76 
78  class LIBCZI_API IDimBounds
79  {
80  public:
81 
87  virtual bool TryGetInterval(DimensionIndex dim, int* startIndex, int* size) const = 0;
88 
92  inline bool IsValid(DimensionIndex dim)
93  {
94  return this->TryGetInterval(dim, nullptr, nullptr);
95  }
96  };
97 
100  class LIBCZI_API IIndexSet
101  {
102  public:
103 
109  virtual bool IsContained(int index) const = 0;
110  };
111 
114  {
116  int value;
117  };
118 
121  {
123  int start;
124  int size;
125  };
126 
128  class LIBCZI_API CDimBase
129  {
130  protected:
134  static std::underlying_type<libCZI::DimensionIndex>::type GetBitIndexForDimension(libCZI::DimensionIndex dim)
135  {
136  // TODO: add checks and asserts
137  auto i = ((std::underlying_type<libCZI::DimensionIndex>::type)dim) - 1;
138  return i;
139  }
140  };
141 
143  class LIBCZI_API CDimCoordinate : public CDimBase, public libCZI::IDimCoordinate
144  {
145  private:
146  std::uint32_t validDims;
147  int values[(int)(libCZI::DimensionIndex::MaxDim)];
148  public:
150  CDimCoordinate() : validDims(0) {}
151 
160  CDimCoordinate(std::initializer_list<DimensionAndValue> list) : CDimCoordinate()
161  {
162  for (auto d : list)
163  {
164  this->Set(d.dimension, d.value);
165  }
166  }
167 
172  {
173  if (other != nullptr)
174  {
175  for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
176  {
177  int coord;
178  if (other->TryGetPosition((libCZI::DimensionIndex)i, &coord))
179  {
180  this->Set((libCZI::DimensionIndex)i, coord);
181  }
182  }
183  }
184  }
185 
190  void Set(libCZI::DimensionIndex dimension, int value)
191  {
192  int index = CDimCoordinate::GetBitIndexForDimension(dimension);
193  this->values[index] = value;
194  this->validDims |= (1 << index);
195  }
196 
201  {
202  auto index = CDimCoordinate::GetBitIndexForDimension(dimension);
203  this->validDims &= ~(1 << index);
204  }
205 
211  void EnumValidDimensions(std::function<bool(libCZI::DimensionIndex dim, int value)> func) const
212  {
213  for (auto i = (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MinDim); i <= (std::underlying_type<libCZI::DimensionIndex>::type)(libCZI::DimensionIndex::MaxDim); ++i)
214  {
216  if ((this->validDims & (1 << bitIndex)) != 0)
217  {
218  if (func((libCZI::DimensionIndex) i, this->values[bitIndex]) != true)
219  break;
220  }
221  }
222  }
223 
234  static CDimCoordinate Parse(const char* str);
235  public: // IDimCoordinate
236  virtual bool TryGetPosition(libCZI::DimensionIndex dim, int* coordinate) const
237  {
238  auto index = CDimCoordinate::GetBitIndexForDimension(dim);
239  if ((this->validDims & (1 << index)) != 0)
240  {
241  if (coordinate != nullptr)
242  {
243  *coordinate = this->values[index];
244  }
245 
246  return true;
247  }
248 
249  return false;
250  }
251  };
252 
254  class LIBCZI_API CDimBounds : public CDimBase, public libCZI::IDimBounds
255  {
256  private:
257  std::uint32_t validDims;
258  int start[(int)(libCZI::DimensionIndex::MaxDim)];
259  int size[(int)(libCZI::DimensionIndex::MaxDim)];
260  public:
262  CDimBounds() : validDims(0) {};
263 
266  CDimBounds(std::initializer_list<DimensionAndStartSize> list) : CDimBounds()
267  {
268  for (auto d : list)
269  {
270  this->Set(d.dimension, d.start, d.size);
271  }
272  }
273 
278  void Set(libCZI::DimensionIndex dimension, int start, int size)
279  {
280  int index = CDimBounds::GetBitIndexForDimension(dimension);
281  this->start[index] = start;
282  this->size[index] = size;
283  this->validDims |= (1 << index);
284  }
285 
288  void EnumValidDimensions(std::function<bool(libCZI::DimensionIndex dim, int start, int size)> func) const
289  {
290  for (int i = (int)(libCZI::DimensionIndex::MinDim); i <= (int)(libCZI::DimensionIndex::MaxDim); ++i)
291  {
293  if ((this->validDims & (1 << bitIndex)) != 0)
294  {
295  if (func((libCZI::DimensionIndex) i, this->start[bitIndex], this->size[bitIndex]) != true)
296  break;
297  }
298  }
299  }
300 
304  {
305  int index = CDimBounds::GetBitIndexForDimension(dimension);
306  this->validDims &= ~(1 << index);
307  }
308 
310  void Clear()
311  {
312  this->validDims = 0;
313  }
314  public:
315 
321  virtual bool TryGetInterval(libCZI::DimensionIndex dim, int* startIndex, int* size) const
322  {
323  int index = CDimBounds::GetBitIndexForDimension(dim);
324  if ((this->validDims & (1 << index)) != 0)
325  {
326  if (startIndex != nullptr)
327  {
328  *startIndex = this->start[index];
329  }
330 
331  if (size != nullptr)
332  {
333  *size = this->size[index];
334  }
335 
336  return true;
337  }
338 
339  return false;
340  }
341  };
342 }
The C-dimension ("channel").
bool IsValid(DimensionIndex dim)
Definition: libCZI_DimCoordinate.h:92
The B-dimension ("block") - its use is deprecated.
libCZI::DimensionIndex dimension
The dimension.
Definition: libCZI_DimCoordinate.h:115
Invalid dimension index.
Interface used to represent an interval (for several dimensions).
Definition: libCZI_DimCoordinate.h:78
CDimCoordinate(const libCZI::IDimCoordinate *other)
Definition: libCZI_DimCoordinate.h:171
void EnumValidDimensions(std::function< bool(libCZI::DimensionIndex dim, int start, int size)> func) const
Definition: libCZI_DimCoordinate.h:288
The Z-dimension.
Base class containing some commonly used methods.
Definition: libCZI_DimCoordinate.h:128
Implementation of a class representing a coordinate (and implementing the IDimCoordinate-interface).
Definition: libCZI_DimCoordinate.h:143
void Set(libCZI::DimensionIndex dimension, int value)
Definition: libCZI_DimCoordinate.h:190
bool IsValid(DimensionIndex dim) const
Definition: libCZI_DimCoordinate.h:71
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:303
The I-dimension ("illumination").
void EnumValidDimensions(std::function< bool(libCZI::DimensionIndex dim, int value)> func) const
Definition: libCZI_DimCoordinate.h:211
virtual bool TryGetInterval(libCZI::DimensionIndex dim, int *startIndex, int *size) const
Definition: libCZI_DimCoordinate.h:321
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:150
void Set(libCZI::DimensionIndex dimension, int start, int size)
Definition: libCZI_DimCoordinate.h:278
CDimBounds()
Default constructor - the object will contain no valid dimension.
Definition: libCZI_DimCoordinate.h:262
Implementation of a class representing an interval (and implementing the libCZI::IDimBounds-interface...
Definition: libCZI_DimCoordinate.h:254
A structure combining a dimension and an interval (defined by a start value and the size)...
Definition: libCZI_DimCoordinate.h:120
A structure combining a dimension and a value.
Definition: libCZI_DimCoordinate.h:113
This enum must be have the value of the highest (valid) dimension index.
libCZI::DimensionIndex dimension
The dimension.
Definition: libCZI_DimCoordinate.h:122
External interfaces, classes, functions and structs are found in the namespace "libCZI".
Definition: libCZI.h:44
void Clear()
Clears this object to its blank/initial state. All dimensions will be set to invalid.
Definition: libCZI_DimCoordinate.h:310
DimensionIndex
Values that represent dimension indexes.
Definition: libCZI_DimCoordinate.h:34
virtual bool TryGetPosition(DimensionIndex dim, int *coordinate) const =0
Definition: libCZI_DimCoordinate.h:100
static std::underlying_type< libCZI::DimensionIndex >::type GetBitIndexForDimension(libCZI::DimensionIndex dim)
Definition: libCZI_DimCoordinate.h:134
int value
The value (for this dimension).
Definition: libCZI_DimCoordinate.h:116
CDimCoordinate(std::initializer_list< DimensionAndValue > list)
Definition: libCZI_DimCoordinate.h:160
The H-dimension ("phase").
int size
The size.
Definition: libCZI_DimCoordinate.h:124
virtual bool TryGetPosition(libCZI::DimensionIndex dim, int *coordinate) const
Definition: libCZI_DimCoordinate.h:236
int start
The start value.
Definition: libCZI_DimCoordinate.h:123
void Clear(libCZI::DimensionIndex dimension)
Definition: libCZI_DimCoordinate.h:200
CDimBounds(std::initializer_list< DimensionAndStartSize > list)
Definition: libCZI_DimCoordinate.h:266
The T-dimension ("time").
The R-dimension ("rotation").