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 //-----------------------------------------------------------------------------
38 //
39 // class Channel
40 // class ChannelList
41 //
42 //-----------------------------------------------------------------------------
43
44 #include <ImfChannelList.h>
45 #include <Iex.h>
46
47
48 using std::string;
49 using std::set;
50 #include "ImfNamespace.h"
51
52 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
53
54
Channel(PixelType t,int xs,int ys,bool pl)55 Channel::Channel (PixelType t, int xs, int ys, bool pl):
56 type (t),
57 xSampling (xs),
58 ySampling (ys),
59 pLinear (pl)
60 {
61 // empty
62 }
63
64
65 bool
operator ==(const Channel & other) const66 Channel::operator == (const Channel &other) const
67 {
68 return type == other.type &&
69 xSampling == other.xSampling &&
70 ySampling == other.ySampling &&
71 pLinear == other.pLinear;
72 }
73
74
75 void
insert(const char name[],const Channel & channel)76 ChannelList::insert (const char name[], const Channel &channel)
77 {
78 if (name[0] == 0)
79 THROW (IEX_NAMESPACE::ArgExc, "Image channel name cannot be an empty string.");
80
81 _map[name] = channel;
82 }
83
84
85 void
insert(const string & name,const Channel & channel)86 ChannelList::insert (const string &name, const Channel &channel)
87 {
88 insert (name.c_str(), channel);
89 }
90
91
92 Channel &
operator [](const char name[])93 ChannelList::operator [] (const char name[])
94 {
95 ChannelMap::iterator i = _map.find (name);
96
97 if (i == _map.end())
98 THROW (IEX_NAMESPACE::ArgExc, "Cannot find image channel \"" << name << "\".");
99
100 return i->second;
101 }
102
103
104 const Channel &
operator [](const char name[]) const105 ChannelList::operator [] (const char name[]) const
106 {
107 ChannelMap::const_iterator i = _map.find (name);
108
109 if (i == _map.end())
110 THROW (IEX_NAMESPACE::ArgExc, "Cannot find image channel \"" << name << "\".");
111
112 return i->second;
113 }
114
115
116 Channel &
operator [](const string & name)117 ChannelList::operator [] (const string &name)
118 {
119 return this->operator[] (name.c_str());
120 }
121
122
123 const Channel &
operator [](const string & name) const124 ChannelList::operator [] (const string &name) const
125 {
126 return this->operator[] (name.c_str());
127 }
128
129
130 Channel *
findChannel(const char name[])131 ChannelList::findChannel (const char name[])
132 {
133 ChannelMap::iterator i = _map.find (name);
134 return (i == _map.end())? 0: &i->second;
135 }
136
137
138 const Channel *
findChannel(const char name[]) const139 ChannelList::findChannel (const char name[]) const
140 {
141 ChannelMap::const_iterator i = _map.find (name);
142 return (i == _map.end())? 0: &i->second;
143 }
144
145
146 Channel *
findChannel(const string & name)147 ChannelList::findChannel (const string &name)
148 {
149 return findChannel (name.c_str());
150 }
151
152
153 const Channel *
findChannel(const string & name) const154 ChannelList::findChannel (const string &name) const
155 {
156 return findChannel (name.c_str());
157 }
158
159
160 ChannelList::Iterator
begin()161 ChannelList::begin ()
162 {
163 return _map.begin();
164 }
165
166
167 ChannelList::ConstIterator
begin() const168 ChannelList::begin () const
169 {
170 return _map.begin();
171 }
172
173
174 ChannelList::Iterator
end()175 ChannelList::end ()
176 {
177 return _map.end();
178 }
179
180
181 ChannelList::ConstIterator
end() const182 ChannelList::end () const
183 {
184 return _map.end();
185 }
186
187
188 ChannelList::Iterator
find(const char name[])189 ChannelList::find (const char name[])
190 {
191 return _map.find (name);
192 }
193
194
195 ChannelList::ConstIterator
find(const char name[]) const196 ChannelList::find (const char name[]) const
197 {
198 return _map.find (name);
199 }
200
201
202 ChannelList::Iterator
find(const string & name)203 ChannelList::find (const string &name)
204 {
205 return find (name.c_str());
206 }
207
208
209 ChannelList::ConstIterator
find(const string & name) const210 ChannelList::find (const string &name) const
211 {
212 return find (name.c_str());
213 }
214
215
216 void
layers(set<string> & layerNames) const217 ChannelList::layers (set <string> &layerNames) const
218 {
219 layerNames.clear();
220
221 for (ConstIterator i = begin(); i != end(); ++i)
222 {
223 string layerName = i.name();
224 size_t pos = layerName.rfind ('.');
225
226 if (pos != string::npos && pos != 0 && pos + 1 < layerName.size())
227 {
228 layerName.erase (pos);
229 layerNames.insert (layerName);
230 }
231 }
232 }
233
234
235 void
channelsInLayer(const string & layerName,Iterator & first,Iterator & last)236 ChannelList::channelsInLayer (const string &layerName,
237 Iterator &first,
238 Iterator &last)
239 {
240 channelsWithPrefix (layerName + '.', first, last);
241 }
242
243
244 void
channelsInLayer(const string & layerName,ConstIterator & first,ConstIterator & last) const245 ChannelList::channelsInLayer (const string &layerName,
246 ConstIterator &first,
247 ConstIterator &last) const
248 {
249 channelsWithPrefix (layerName + '.', first, last);
250 }
251
252
253 void
channelsWithPrefix(const char prefix[],Iterator & first,Iterator & last)254 ChannelList::channelsWithPrefix (const char prefix[],
255 Iterator &first,
256 Iterator &last)
257 {
258 first = last = _map.lower_bound (prefix);
259 size_t n = int(strlen (prefix));
260
261 while (last != Iterator (_map.end()) &&
262 strncmp (last.name(), prefix, n) <= 0)
263 {
264 ++last;
265 }
266 }
267
268
269 void
channelsWithPrefix(const char prefix[],ConstIterator & first,ConstIterator & last) const270 ChannelList::channelsWithPrefix (const char prefix[],
271 ConstIterator &first,
272 ConstIterator &last) const
273 {
274 first = last = _map.lower_bound (prefix);
275 size_t n = strlen (prefix);
276
277 while (last != ConstIterator (_map.end()) &&
278 strncmp (last.name(), prefix, n) <= 0)
279 {
280 ++last;
281 }
282 }
283
284
285 void
channelsWithPrefix(const string & prefix,Iterator & first,Iterator & last)286 ChannelList::channelsWithPrefix (const string &prefix,
287 Iterator &first,
288 Iterator &last)
289 {
290 return channelsWithPrefix (prefix.c_str(), first, last);
291 }
292
293
294 void
channelsWithPrefix(const string & prefix,ConstIterator & first,ConstIterator & last) const295 ChannelList::channelsWithPrefix (const string &prefix,
296 ConstIterator &first,
297 ConstIterator &last) const
298 {
299 return channelsWithPrefix (prefix.c_str(), first, last);
300 }
301
302
303 bool
operator ==(const ChannelList & other) const304 ChannelList::operator == (const ChannelList &other) const
305 {
306 ConstIterator i = begin();
307 ConstIterator j = other.begin();
308
309 while (i != end() && j != other.end())
310 {
311 if (!(i.channel() == j.channel()))
312 return false;
313
314 ++i;
315 ++j;
316 }
317
318 return i == end() && j == other.end();
319 }
320
321
322 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
323