1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2002, 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
36
37 #ifndef INCLUDED_IMF_FRAME_BUFFER_H
38 #define INCLUDED_IMF_FRAME_BUFFER_H
39
40 //-----------------------------------------------------------------------------
41 //
42 // class Slice
43 // class FrameBuffer
44 //
45 //-----------------------------------------------------------------------------
46
47 #include <ImfName.h>
48 #include <ImfPixelType.h>
49 #include <map>
50 #include <string>
51
52
53 namespace Imf {
54
55
56 //-------------------------------------------------------
57 // Description of a single slice of the frame buffer:
58 //
59 // Note -- terminology: as part of a file, a component of
60 // an image (e.g. red, green, blue, depth etc.) is called
61 // a "channel". As part of a frame buffer, an image
62 // component is called a "slice".
63 //-------------------------------------------------------
64
65 struct Slice
66 {
67 //------------------------------
68 // Data type; see ImfPixelType.h
69 //------------------------------
70
71 PixelType type;
72
73
74 //---------------------------------------------------------------------
75 // Memory layout: The address of pixel (x, y) is
76 //
77 // base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
78 //
79 // where xp and yp are computed as follows:
80 //
81 // * If we are reading or writing a scanline-based file:
82 //
83 // xp = x
84 // yp = y
85 //
86 // * If we are reading a tile whose upper left coorner is at (xt, yt):
87 //
88 // if xTileCoords is true then xp = x - xt, else xp = x
89 // if yTileCoords is true then yp = y - yt, else yp = y
90 //
91 //---------------------------------------------------------------------
92
93 char * base;
94 size_t xStride;
95 size_t yStride;
96
97
98 //--------------------------------------------
99 // Subsampling: pixel (x, y) is present in the
100 // slice only if
101 //
102 // x % xSampling == 0 && y % ySampling == 0
103 //
104 //--------------------------------------------
105
106 int xSampling;
107 int ySampling;
108
109
110 //----------------------------------------------------------
111 // Default value, used to fill the slice when a file without
112 // a channel that corresponds to this slice is read.
113 //----------------------------------------------------------
114
115 double fillValue;
116
117
118 //-------------------------------------------------------
119 // For tiled files, the xTileCoords and yTileCoords flags
120 // determine whether pixel addressing is performed using
121 // absolute coordinates or coordinates relative to a
122 // tile's upper left corner. (See the comment on base,
123 // xStride and yStride, above.)
124 //
125 // For scanline-based files these flags have no effect;
126 // pixel addressing is always done using absolute
127 // coordinates.
128 //-------------------------------------------------------
129
130 bool xTileCoords;
131 bool yTileCoords;
132
133
134 //------------
135 // Constructor
136 //------------
137
138 Slice (PixelType type = HALF,
139 char * base = 0,
140 size_t xStride = 0,
141 size_t yStride = 0,
142 int xSampling = 1,
143 int ySampling = 1,
144 double fillValue = 0.0,
145 bool xTileCoords = false,
146 bool yTileCoords = false);
147 };
148
149
150 class FrameBuffer
151 {
152 public:
153
154 //------------
155 // Add a slice
156 //------------
157
158 void insert (const char name[],
159 const Slice &slice);
160
161 void insert (const std::string &name,
162 const Slice &slice);
163
164 //----------------------------------------------------------------
165 // Access to existing slices:
166 //
167 // [n] Returns a reference to the slice with name n.
168 // If no slice with name n exists, an Iex::ArgExc
169 // is thrown.
170 //
171 // findSlice(n) Returns a pointer to the slice with name n,
172 // or 0 if no slice with name n exists.
173 //
174 //----------------------------------------------------------------
175
176 Slice & operator [] (const char name[]);
177 const Slice & operator [] (const char name[]) const;
178
179 Slice & operator [] (const std::string &name);
180 const Slice & operator [] (const std::string &name) const;
181
182 Slice * findSlice (const char name[]);
183 const Slice * findSlice (const char name[]) const;
184
185 Slice * findSlice (const std::string &name);
186 const Slice * findSlice (const std::string &name) const;
187
188
189 //-----------------------------------------
190 // Iterator-style access to existing slices
191 //-----------------------------------------
192
193 typedef std::map <Name, Slice> SliceMap;
194
195 class Iterator;
196 class ConstIterator;
197
198 Iterator begin ();
199 ConstIterator begin () const;
200
201 Iterator end ();
202 ConstIterator end () const;
203
204 Iterator find (const char name[]);
205 ConstIterator find (const char name[]) const;
206
207 Iterator find (const std::string &name);
208 ConstIterator find (const std::string &name) const;
209
210 private:
211
212 SliceMap _map;
213 };
214
215
216 //----------
217 // Iterators
218 //----------
219
220 class FrameBuffer::Iterator
221 {
222 public:
223
224 Iterator ();
225 Iterator (const FrameBuffer::SliceMap::iterator &i);
226
227 Iterator & operator ++ ();
228 Iterator operator ++ (int);
229
230 const char * name () const;
231 Slice & slice () const;
232
233 private:
234
235 friend class FrameBuffer::ConstIterator;
236
237 FrameBuffer::SliceMap::iterator _i;
238 };
239
240
241 class FrameBuffer::ConstIterator
242 {
243 public:
244
245 ConstIterator ();
246 ConstIterator (const FrameBuffer::SliceMap::const_iterator &i);
247 ConstIterator (const FrameBuffer::Iterator &other);
248
249 ConstIterator & operator ++ ();
250 ConstIterator operator ++ (int);
251
252 const char * name () const;
253 const Slice & slice () const;
254
255 private:
256
257 friend bool operator == (const ConstIterator &, const ConstIterator &);
258 friend bool operator != (const ConstIterator &, const ConstIterator &);
259
260 FrameBuffer::SliceMap::const_iterator _i;
261 };
262
263
264 //-----------------
265 // Inline Functions
266 //-----------------
267
268 inline
Iterator()269 FrameBuffer::Iterator::Iterator (): _i()
270 {
271 // empty
272 }
273
274
275 inline
Iterator(const FrameBuffer::SliceMap::iterator & i)276 FrameBuffer::Iterator::Iterator (const FrameBuffer::SliceMap::iterator &i):
277 _i (i)
278 {
279 // empty
280 }
281
282
283 inline FrameBuffer::Iterator &
284 FrameBuffer::Iterator::operator ++ ()
285 {
286 ++_i;
287 return *this;
288 }
289
290
291 inline FrameBuffer::Iterator
292 FrameBuffer::Iterator::operator ++ (int)
293 {
294 Iterator tmp = *this;
295 ++_i;
296 return tmp;
297 }
298
299
300 inline const char *
name()301 FrameBuffer::Iterator::name () const
302 {
303 return *_i->first;
304 }
305
306
307 inline Slice &
slice()308 FrameBuffer::Iterator::slice () const
309 {
310 return _i->second;
311 }
312
313
314 inline
ConstIterator()315 FrameBuffer::ConstIterator::ConstIterator (): _i()
316 {
317 // empty
318 }
319
320 inline
ConstIterator(const FrameBuffer::SliceMap::const_iterator & i)321 FrameBuffer::ConstIterator::ConstIterator
322 (const FrameBuffer::SliceMap::const_iterator &i): _i (i)
323 {
324 // empty
325 }
326
327
328 inline
ConstIterator(const FrameBuffer::Iterator & other)329 FrameBuffer::ConstIterator::ConstIterator (const FrameBuffer::Iterator &other):
330 _i (other._i)
331 {
332 // empty
333 }
334
335 inline FrameBuffer::ConstIterator &
336 FrameBuffer::ConstIterator::operator ++ ()
337 {
338 ++_i;
339 return *this;
340 }
341
342
343 inline FrameBuffer::ConstIterator
344 FrameBuffer::ConstIterator::operator ++ (int)
345 {
346 ConstIterator tmp = *this;
347 ++_i;
348 return tmp;
349 }
350
351
352 inline const char *
name()353 FrameBuffer::ConstIterator::name () const
354 {
355 return *_i->first;
356 }
357
358 inline const Slice &
slice()359 FrameBuffer::ConstIterator::slice () const
360 {
361 return _i->second;
362 }
363
364
365 inline bool
366 operator == (const FrameBuffer::ConstIterator &x,
367 const FrameBuffer::ConstIterator &y)
368 {
369 return x._i == y._i;
370 }
371
372
373 inline bool
374 operator != (const FrameBuffer::ConstIterator &x,
375 const FrameBuffer::ConstIterator &y)
376 {
377 return !(x == y);
378 }
379
380
381 } // namespace Imf
382
383 #endif
384