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