1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5
6 #ifndef INCLUDED_IMF_DEEP_IMAGE_LEVEL_H
7 #define INCLUDED_IMF_DEEP_IMAGE_LEVEL_H
8
9 //----------------------------------------------------------------------------
10 //
11 // class DeepImageLevel
12 // class DeepImageLevel::Iterator
13 // class DeepImageLevel::ConstIterator
14 //
15 // For an explanation of images, levels and channels,
16 // see the comments in header file Image.h.
17 //
18 //----------------------------------------------------------------------------
19
20 #include "ImfUtilExport.h"
21 #include "ImfNamespace.h"
22
23 #include "ImfDeepImageChannel.h"
24 #include "ImfSampleCountChannel.h"
25 #include "ImfImageLevel.h"
26
27 #include <string>
28 #include <map>
29
30 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
31
32 class DeepImage;
33
34 class IMFUTIL_EXPORT_TYPE DeepImageLevel : public ImageLevel
35 {
36 public:
37
38 //
39 // Access to the image to which the level belongs.
40 //
41
42 IMFUTIL_EXPORT
43 DeepImage & deepImage ();
44 IMFUTIL_EXPORT
45 const DeepImage & deepImage () const;
46
47
48 //
49 // Access to deep channels by name:
50 //
51 // findChannel(n) returns a pointer to the image channel with
52 // name n, or 0 if no such channel exists.
53 //
54 // channel(n) returns a reference to the image channel with
55 // name n, or throws an Iex::ArgExc exception if
56 // no such channel exists.
57 //
58 // findTypedChannel<T>(n) returns a pointer to the image channel with
59 // name n and type T, or 0 if no such channel
60 // exists.
61 //
62 // typedChannel(n) returns a reference to the image channel with
63 // name n and type T, or throws an Iex::ArgExc
64 // exception if no such channel exists.
65 //
66
67
68 IMFUTIL_EXPORT
69 DeepImageChannel * findChannel (const std::string& name);
70 IMFUTIL_EXPORT
71 const DeepImageChannel * findChannel (const std::string& name) const;
72
73 IMFUTIL_EXPORT
74 DeepImageChannel & channel (const std::string& name);
75 IMFUTIL_EXPORT
76 const DeepImageChannel & channel (const std::string& name) const;
77
78 template <class T>
79 TypedDeepImageChannel<T> * findTypedChannel
80 (const std::string& name);
81
82 template <class T>
83 const TypedDeepImageChannel<T> * findTypedChannel
84 (const std::string& name) const;
85
86 template <class T>
87 TypedDeepImageChannel<T> & typedChannel
88 (const std::string& name);
89
90 template <class T>
91 const TypedDeepImageChannel<T> & typedChannel
92 (const std::string& name) const;
93
94 //
95 // Iterator-style access to deep channels
96 //
97
98 typedef std::map <std::string, DeepImageChannel *> ChannelMap;
99
100 class Iterator;
101 class ConstIterator;
102
103 IMFUTIL_EXPORT
104 Iterator begin();
105 IMFUTIL_EXPORT
106 ConstIterator begin() const;
107
108 IMFUTIL_EXPORT
109 Iterator end();
110 IMFUTIL_EXPORT
111 ConstIterator end() const;
112
113 //
114 // Access to the sample count channel
115 //
116
117 IMFUTIL_EXPORT
118 SampleCountChannel & sampleCounts();
119 IMFUTIL_EXPORT
120 const SampleCountChannel & sampleCounts() const;
121
122 private:
123
124 friend class DeepImage;
125 friend class SampleCountChannel;
126
127 //
128 // The constructor and destructor are private.
129 // Deep image levels exist only as part of a deep image.
130 //
131 IMF_HIDDEN
132 DeepImageLevel (DeepImage& image,
133 int xLevelNumber,
134 int yLevelNumber,
135 const IMATH_NAMESPACE::Box2i& dataWindow);
136
137 IMF_HIDDEN
138 ~DeepImageLevel ();
139
140 IMF_HIDDEN
141 void setSamplesToZero (size_t i,
142 unsigned int oldNumSamples,
143 unsigned int newNumSamples);
144
145 IMF_HIDDEN
146 void moveSampleList (size_t i,
147 unsigned int oldNumSamples,
148 unsigned int newNumSamples,
149 size_t newSampleListPosition);
150
151 IMF_HIDDEN
152 void moveSamplesToNewBuffer (const unsigned int * oldNumSamples,
153 const unsigned int * newNumSamples,
154 const size_t * newSampleListPositions);
155
156 IMF_HIDDEN
157 void initializeSampleLists ();
158
159 IMF_HIDDEN
160 virtual void resize (const IMATH_NAMESPACE::Box2i& dataWindow);
161
162 IMF_HIDDEN
163 virtual void shiftPixels (int dx, int dy);
164
165 IMF_HIDDEN
166 virtual void insertChannel (const std::string& name,
167 PixelType type,
168 int xSampling,
169 int ySampling,
170 bool pLinear);
171
172 IMF_HIDDEN
173 virtual void eraseChannel (const std::string& name);
174
175 IMF_HIDDEN
176 virtual void clearChannels ();
177
178 IMF_HIDDEN
179 virtual void renameChannel (const std::string &oldName,
180 const std::string &newName);
181
182 IMF_HIDDEN
183 virtual void renameChannels (const RenamingMap &oldToNewNames);
184
185 ChannelMap _channels;
186 SampleCountChannel _sampleCounts;
187 };
188
189
190 class IMFUTIL_EXPORT_TYPE DeepImageLevel::Iterator
191 {
192 public:
193
194 IMFUTIL_EXPORT
195 Iterator ();
196 IMFUTIL_EXPORT
197 Iterator (const DeepImageLevel::ChannelMap::iterator& i);
198
199
200 //
201 // Advance the iterator
202 //
203
204 IMFUTIL_EXPORT
205 Iterator & operator ++ ();
206 IMFUTIL_EXPORT
207 Iterator operator ++ (int);
208
209
210 //
211 // Access to the channel to which the iterator points,
212 // and to the name of that channel.
213 //
214
215 IMFUTIL_EXPORT
216 const std::string & name () const;
217 IMFUTIL_EXPORT
218 DeepImageChannel & channel () const;
219
220 private:
221
222 friend class DeepImageLevel::ConstIterator;
223
224 DeepImageLevel::ChannelMap::iterator _i;
225 };
226
227
228 class IMFUTIL_EXPORT_TYPE DeepImageLevel::ConstIterator
229 {
230 public:
231
232 IMFUTIL_EXPORT
233 ConstIterator ();
234 IMFUTIL_EXPORT
235 ConstIterator (const DeepImageLevel::ChannelMap::const_iterator& i);
236 IMFUTIL_EXPORT
237 ConstIterator (const DeepImageLevel::Iterator& other);
238
239
240 //
241 // Advance the iterator
242 //
243
244 IMFUTIL_EXPORT
245 ConstIterator & operator ++ ();
246 IMFUTIL_EXPORT
247 ConstIterator operator ++ (int);
248
249
250 //
251 // Access to the channel to which the iterator points,
252 // and to the name of that channel.
253 //
254
255 IMFUTIL_EXPORT
256 const std::string & name () const;
257 IMFUTIL_EXPORT
258 const DeepImageChannel & channel () const;
259
260 private:
261
262 friend bool operator ==
263 (const ConstIterator &, const ConstIterator &);
264
265 friend bool operator !=
266 (const ConstIterator &, const ConstIterator &);
267
268 DeepImageLevel::ChannelMap::const_iterator _i;
269 };
270
271
272 //-----------------------------------------------------------------------------
273 // Implementation of inline functions
274 //-----------------------------------------------------------------------------
275
276 template <class T>
277 TypedDeepImageChannel<T> *
findTypedChannel(const std::string & name)278 DeepImageLevel::findTypedChannel (const std::string& name)
279 {
280 return dynamic_cast <TypedDeepImageChannel<T> *> (findChannel (name));
281 }
282
283
284 template <class T>
285 const TypedDeepImageChannel<T> *
findTypedChannel(const std::string & name)286 DeepImageLevel::findTypedChannel (const std::string& name) const
287 {
288 return dynamic_cast <const TypedDeepImageChannel<T> *> (findChannel (name));
289 }
290
291
292 template <class T>
293 TypedDeepImageChannel<T> &
typedChannel(const std::string & name)294 DeepImageLevel::typedChannel (const std::string& name)
295 {
296 TypedDeepImageChannel<T> * ptr = findTypedChannel<T> (name);
297
298 if (ptr == 0)
299 throwBadChannelNameOrType (name);
300
301 return *ptr;
302 }
303
304
305 template <class T>
306 const TypedDeepImageChannel<T> &
typedChannel(const std::string & name)307 DeepImageLevel::typedChannel (const std::string& name) const
308 {
309 const TypedDeepImageChannel<T> * ptr = findTypedChannel<T> (name);
310
311 if (ptr == 0)
312 throwBadChannelNameOrType (name);
313
314 return *ptr;
315 }
316
317
318 inline SampleCountChannel &
sampleCounts()319 DeepImageLevel::sampleCounts ()
320 {
321 return _sampleCounts;
322 }
323
324
325 inline const SampleCountChannel &
sampleCounts()326 DeepImageLevel::sampleCounts () const
327 {
328 return _sampleCounts;
329 }
330
331
332 inline
Iterator()333 DeepImageLevel::Iterator::Iterator (): _i()
334 {
335 // empty
336 }
337
338
339 inline
Iterator(const DeepImageLevel::ChannelMap::iterator & i)340 DeepImageLevel::Iterator::Iterator
341 (const DeepImageLevel::ChannelMap::iterator& i)
342 :
343 _i (i)
344 {
345 // empty
346 }
347
348
349 inline DeepImageLevel::Iterator &
350 DeepImageLevel::Iterator::operator ++ ()
351 {
352 ++_i;
353 return *this;
354 }
355
356
357 inline DeepImageLevel::Iterator
358 DeepImageLevel::Iterator::operator ++ (int)
359 {
360 Iterator tmp = *this;
361 ++_i;
362 return tmp;
363 }
364
365
366 inline const std::string &
name()367 DeepImageLevel::Iterator::name () const
368 {
369 return _i->first;
370 }
371
372
373 inline DeepImageChannel &
channel()374 DeepImageLevel::Iterator::channel () const
375 {
376 return *_i->second;
377 }
378
379
380 inline
ConstIterator()381 DeepImageLevel::ConstIterator::ConstIterator (): _i()
382 {
383 // empty
384 }
385
386 inline
ConstIterator(const DeepImageLevel::ChannelMap::const_iterator & i)387 DeepImageLevel::ConstIterator::ConstIterator
388 (const DeepImageLevel::ChannelMap::const_iterator& i): _i (i)
389 {
390 // empty
391 }
392
393
394 inline
ConstIterator(const DeepImageLevel::Iterator & other)395 DeepImageLevel::ConstIterator::ConstIterator
396 (const DeepImageLevel::Iterator& other): _i (other._i)
397 {
398 // empty
399 }
400
401 inline DeepImageLevel::ConstIterator &
402 DeepImageLevel::ConstIterator::operator ++ ()
403 {
404 ++_i;
405 return *this;
406 }
407
408
409 inline DeepImageLevel::ConstIterator
410 DeepImageLevel::ConstIterator::operator ++ (int)
411 {
412 ConstIterator tmp = *this;
413 ++_i;
414 return tmp;
415 }
416
417
418 inline const std::string &
name()419 DeepImageLevel::ConstIterator::name () const
420 {
421 return _i->first;
422 }
423
424 inline const DeepImageChannel &
channel()425 DeepImageLevel::ConstIterator::channel () const
426 {
427 return *_i->second;
428 }
429
430
431 inline bool
432 operator == (const DeepImageLevel::ConstIterator& x,
433 const DeepImageLevel::ConstIterator& y)
434 {
435 return x._i == y._i;
436 }
437
438
439 inline bool
440 operator != (const DeepImageLevel::ConstIterator& x,
441 const DeepImageLevel::ConstIterator& y)
442 {
443 return !(x == y);
444 }
445
446 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
447
448 #endif
449