1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // *       Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // *       Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // *       Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34 
35 #ifndef IMFDEEPFRAMEBUFFER_H_
36 #define IMFDEEPFRAMEBUFFER_H_
37 
38 #include "ImfFrameBuffer.h"
39 #include "ImfNamespace.h"
40 #include "ImfExport.h"
41 
42 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
43 
44 //--------------------------------------------------------
45 // Description of a single deep slice of the frame buffer:
46 //--------------------------------------------------------
47 
48 struct DeepSlice : public Slice
49 {
50     //---------------------------------------------------------------------
51     // The stride for each sample in this slice.
52     //
53     // Memory layout:  The address of sample i in pixel (x, y) is
54     //
55     //  base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
56     //       + i * sampleStride
57     //
58     // where xp and yp are computed as follows:
59     //
60     //  * If we are reading or writing a scanline-based file:
61     //
62     //      xp = x
63     //      yp = y
64     //
65     //  * If we are reading a tile whose upper left coorner is at (xt, yt):
66     //
67     //      if xTileCoords is true then xp = x - xt, else xp = x
68     //      if yTileCoords is true then yp = y - yt, else yp = y
69     //
70     //---------------------------------------------------------------------
71 
72     int sampleStride;
73 
74     //------------
75     // Constructor
76     //------------
77     IMF_EXPORT
78     DeepSlice (PixelType type = HALF,
79                char * base = 0,
80                size_t xStride = 0,
81                size_t yStride = 0,
82                size_t sampleStride = 0,
83                int xSampling = 1,
84                int ySampling = 1,
85                double fillValue = 0.0,
86                bool xTileCoords = false,
87                bool yTileCoords = false);
88 };
89 
90 //-----------------
91 // DeepFrameBuffer.
92 //-----------------
93 
94 class DeepFrameBuffer
95 {
96   public:
97 
98 
99     //------------
100     // Add a slice
101     //------------
102 
103     IMF_EXPORT
104     void                        insert (const char name[],
105                                         const DeepSlice &slice);
106 
107     IMF_EXPORT
108     void                        insert (const std::string &name,
109                                         const DeepSlice &slice);
110 
111     //----------------------------------------------------------------
112     // Access to existing slices:
113     //
114     // [n]              Returns a reference to the slice with name n.
115     //                  If no slice with name n exists, an IEX_NAMESPACE::ArgExc
116     //                  is thrown.
117     //
118     // findSlice(n)     Returns a pointer to the slice with name n,
119     //                  or 0 if no slice with name n exists.
120     //
121     //----------------------------------------------------------------
122 
123     IMF_EXPORT
124     DeepSlice &                 operator [] (const char name[]);
125     IMF_EXPORT
126     const DeepSlice &           operator [] (const char name[]) const;
127 
128     IMF_EXPORT
129     DeepSlice &                 operator [] (const std::string &name);
130     IMF_EXPORT
131     const DeepSlice &           operator [] (const std::string &name) const;
132 
133     IMF_EXPORT
134     DeepSlice *                 findSlice (const char name[]);
135     IMF_EXPORT
136     const DeepSlice *           findSlice (const char name[]) const;
137 
138     IMF_EXPORT
139     DeepSlice *                 findSlice (const std::string &name);
140     IMF_EXPORT
141     const DeepSlice *           findSlice (const std::string &name) const;
142 
143 
144     //-----------------------------------------
145     // Iterator-style access to existing slices
146     //-----------------------------------------
147 
148     typedef std::map <Name, DeepSlice> SliceMap;
149 
150     class Iterator;
151     class ConstIterator;
152 
153     IMF_EXPORT
154     Iterator                    begin ();
155     IMF_EXPORT
156     ConstIterator               begin () const;
157 
158     IMF_EXPORT
159     Iterator                    end ();
160     IMF_EXPORT
161     ConstIterator               end () const;
162 
163     IMF_EXPORT
164     Iterator                    find (const char name[]);
165     IMF_EXPORT
166     ConstIterator               find (const char name[]) const;
167 
168     IMF_EXPORT
169     Iterator                    find (const std::string &name);
170     IMF_EXPORT
171     ConstIterator               find (const std::string &name) const;
172 
173     //----------------------------------------------------
174     // Public function for accessing a sample count slice.
175     //----------------------------------------------------
176 
177     IMF_EXPORT
178     void                        insertSampleCountSlice(const Slice & slice);
179     IMF_EXPORT
180     const Slice &               getSampleCountSlice() const;
181 
182   private:
183 
184     SliceMap                    _map;
185     Slice                       _sampleCounts;
186 };
187 
188 //----------
189 // Iterators
190 //----------
191 
192 class DeepFrameBuffer::Iterator
193 {
194   public:
195 
196     IMF_EXPORT
197     Iterator ();
198     IMF_EXPORT
199     Iterator (const DeepFrameBuffer::SliceMap::iterator &i);
200 
201     IMF_EXPORT
202     Iterator &                  operator ++ ();
203     IMF_EXPORT
204     Iterator                    operator ++ (int);
205 
206     IMF_EXPORT
207     const char *                name () const;
208     IMF_EXPORT
209     DeepSlice &                 slice () const;
210 
211   private:
212 
213     friend class DeepFrameBuffer::ConstIterator;
214 
215     DeepFrameBuffer::SliceMap::iterator _i;
216 };
217 
218 
219 class DeepFrameBuffer::ConstIterator
220 {
221   public:
222 
223     IMF_EXPORT
224     ConstIterator ();
225     IMF_EXPORT
226     ConstIterator (const DeepFrameBuffer::SliceMap::const_iterator &i);
227     IMF_EXPORT
228     ConstIterator (const DeepFrameBuffer::Iterator &other);
229 
230     IMF_EXPORT
231     ConstIterator &             operator ++ ();
232     IMF_EXPORT
233     ConstIterator               operator ++ (int);
234 
235     IMF_EXPORT
236     const char *                name () const;
237     IMF_EXPORT
238     const DeepSlice &           slice () const;
239 
240   private:
241 
242     friend bool operator == (const ConstIterator &, const ConstIterator &);
243     friend bool operator != (const ConstIterator &, const ConstIterator &);
244 
245     DeepFrameBuffer::SliceMap::const_iterator _i;
246 };
247 
248 
249 //-----------------
250 // Inline Functions
251 //-----------------
252 
253 inline
Iterator()254 DeepFrameBuffer::Iterator::Iterator (): _i()
255 {
256     // empty
257 }
258 
259 
260 inline
Iterator(const DeepFrameBuffer::SliceMap::iterator & i)261 DeepFrameBuffer::Iterator::Iterator (const DeepFrameBuffer::SliceMap::iterator &i):
262     _i (i)
263 {
264     // empty
265 }
266 
267 
268 inline DeepFrameBuffer::Iterator &
269 DeepFrameBuffer::Iterator::operator ++ ()
270 {
271     ++_i;
272     return *this;
273 }
274 
275 
276 inline DeepFrameBuffer::Iterator
277 DeepFrameBuffer::Iterator::operator ++ (int)
278 {
279     Iterator tmp = *this;
280     ++_i;
281     return tmp;
282 }
283 
284 
285 inline const char *
name()286 DeepFrameBuffer::Iterator::name () const
287 {
288     return *_i->first;
289 }
290 
291 
292 inline DeepSlice &
slice()293 DeepFrameBuffer::Iterator::slice () const
294 {
295     return _i->second;
296 }
297 
298 
299 inline
ConstIterator()300 DeepFrameBuffer::ConstIterator::ConstIterator (): _i()
301 {
302     // empty
303 }
304 
305 inline
ConstIterator(const DeepFrameBuffer::SliceMap::const_iterator & i)306 DeepFrameBuffer::ConstIterator::ConstIterator
307     (const DeepFrameBuffer::SliceMap::const_iterator &i): _i (i)
308 {
309     // empty
310 }
311 
312 
313 inline
ConstIterator(const DeepFrameBuffer::Iterator & other)314 DeepFrameBuffer::ConstIterator::ConstIterator (const DeepFrameBuffer::Iterator &other):
315     _i (other._i)
316 {
317     // empty
318 }
319 
320 inline DeepFrameBuffer::ConstIterator &
321 DeepFrameBuffer::ConstIterator::operator ++ ()
322 {
323     ++_i;
324     return *this;
325 }
326 
327 
328 inline DeepFrameBuffer::ConstIterator
329 DeepFrameBuffer::ConstIterator::operator ++ (int)
330 {
331     ConstIterator tmp = *this;
332     ++_i;
333     return tmp;
334 }
335 
336 
337 inline const char *
name()338 DeepFrameBuffer::ConstIterator::name () const
339 {
340     return *_i->first;
341 }
342 
343 inline const DeepSlice &
slice()344 DeepFrameBuffer::ConstIterator::slice () const
345 {
346     return _i->second;
347 }
348 
349 
350 inline bool
351 operator == (const DeepFrameBuffer::ConstIterator &x,
352              const DeepFrameBuffer::ConstIterator &y)
353 {
354     return x._i == y._i;
355 }
356 
357 
358 inline bool
359 operator != (const DeepFrameBuffer::ConstIterator &x,
360              const DeepFrameBuffer::ConstIterator &y)
361 {
362     return !(x == y);
363 }
364 
365 
366 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
367 
368 
369 
370 
371 
372 
373 #endif /* IMFDEEPFRAMEBUFFER_H_ */
374