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