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