1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2004, 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 // class TimeCode
39 //
40 //-----------------------------------------------------------------------------
41
42 #include <ImfTimeCode.h>
43 #include "Iex.h"
44 #include "ImfNamespace.h"
45
46 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
47
48
TimeCode()49 TimeCode::TimeCode ()
50 {
51 _time = 0;
52 _user = 0;
53 }
54
55
TimeCode(int hours,int minutes,int seconds,int frame,bool dropFrame,bool colorFrame,bool fieldPhase,bool bgf0,bool bgf1,bool bgf2,int binaryGroup1,int binaryGroup2,int binaryGroup3,int binaryGroup4,int binaryGroup5,int binaryGroup6,int binaryGroup7,int binaryGroup8)56 TimeCode::TimeCode
57 (int hours,
58 int minutes,
59 int seconds,
60 int frame,
61 bool dropFrame,
62 bool colorFrame,
63 bool fieldPhase,
64 bool bgf0,
65 bool bgf1,
66 bool bgf2,
67 int binaryGroup1,
68 int binaryGroup2,
69 int binaryGroup3,
70 int binaryGroup4,
71 int binaryGroup5,
72 int binaryGroup6,
73 int binaryGroup7,
74 int binaryGroup8)
75 {
76 setHours (hours);
77 setMinutes (minutes);
78 setSeconds (seconds);
79 setFrame (frame);
80 setDropFrame (dropFrame);
81 setColorFrame (colorFrame);
82 setFieldPhase (fieldPhase);
83 setBgf0 (bgf0);
84 setBgf1 (bgf1);
85 setBgf2 (bgf2);
86 setBinaryGroup (1, binaryGroup1);
87 setBinaryGroup (2, binaryGroup2);
88 setBinaryGroup (3, binaryGroup3);
89 setBinaryGroup (4, binaryGroup4);
90 setBinaryGroup (5, binaryGroup5);
91 setBinaryGroup (6, binaryGroup6);
92 setBinaryGroup (7, binaryGroup7);
93 setBinaryGroup (8, binaryGroup8);
94 }
95
96
TimeCode(unsigned int timeAndFlags,unsigned int userData,Packing packing)97 TimeCode::TimeCode
98 (unsigned int timeAndFlags,
99 unsigned int userData,
100 Packing packing)
101 {
102 setTimeAndFlags (timeAndFlags, packing);
103 setUserData (userData);
104 }
105
106
TimeCode(const TimeCode & other)107 TimeCode::TimeCode (const TimeCode &other)
108 {
109 _time = other._time;
110 _user = other._user;
111 }
112
113
114 TimeCode &
operator =(const TimeCode & other)115 TimeCode::operator = (const TimeCode &other)
116 {
117 _time = other._time;
118 _user = other._user;
119 return *this;
120 }
121
122
123 bool
operator ==(const TimeCode & c) const124 TimeCode::operator == (const TimeCode & c) const
125 {
126 return (_time == c._time && _user == c._user);
127 }
128
129
130 bool
operator !=(const TimeCode & c) const131 TimeCode::operator != (const TimeCode & c) const
132 {
133 return (_time != c._time || _user != c._user);
134 }
135
136
137
138 namespace {
139
140 unsigned int
bitField(unsigned int value,int minBit,int maxBit)141 bitField (unsigned int value, int minBit, int maxBit)
142 {
143 int shift = minBit;
144 unsigned int mask = (~(~0U << (maxBit - minBit + 1)) << minBit);
145 return (value & mask) >> shift;
146 }
147
148
149 void
setBitField(unsigned int & value,int minBit,int maxBit,unsigned int field)150 setBitField (unsigned int &value, int minBit, int maxBit, unsigned int field)
151 {
152 int shift = minBit;
153 unsigned int mask = (~(~0U << (maxBit - minBit + 1)) << minBit);
154 value = ((value & ~mask) | ((field << shift) & mask));
155 }
156
157
158 int
bcdToBinary(unsigned int bcd)159 bcdToBinary (unsigned int bcd)
160 {
161 return int ((bcd & 0x0f) + 10 * ((bcd >> 4) & 0x0f));
162 }
163
164
165 unsigned int
binaryToBcd(int binary)166 binaryToBcd (int binary)
167 {
168 int units = binary % 10;
169 int tens = (binary / 10) % 10;
170 return (unsigned int) (units | (tens << 4));
171 }
172
173
174 } // namespace
175
176
177 int
hours() const178 TimeCode::hours () const
179 {
180 return bcdToBinary (bitField (_time, 24, 29));
181 }
182
183
184 void
setHours(int value)185 TimeCode::setHours (int value)
186 {
187 if (value < 0 || value > 23)
188 throw IEX_NAMESPACE::ArgExc ("Cannot set hours field in time code. "
189 "New value is out of range.");
190
191 setBitField (_time, 24, 29, binaryToBcd (value));
192 }
193
194
195 int
minutes() const196 TimeCode::minutes () const
197 {
198 return bcdToBinary (bitField (_time, 16, 22));
199 }
200
201
202 void
setMinutes(int value)203 TimeCode::setMinutes (int value)
204 {
205 if (value < 0 || value > 59)
206 throw IEX_NAMESPACE::ArgExc ("Cannot set minutes field in time code. "
207 "New value is out of range.");
208
209 setBitField (_time, 16, 22, binaryToBcd (value));
210 }
211
212
213 int
seconds() const214 TimeCode::seconds () const
215 {
216 return bcdToBinary (bitField (_time, 8, 14));
217 }
218
219
220 void
setSeconds(int value)221 TimeCode::setSeconds (int value)
222 {
223 if (value < 0 || value > 59)
224 throw IEX_NAMESPACE::ArgExc ("Cannot set seconds field in time code. "
225 "New value is out of range.");
226
227 setBitField (_time, 8, 14, binaryToBcd (value));
228 }
229
230
231 int
frame() const232 TimeCode::frame () const
233 {
234 return bcdToBinary (bitField (_time, 0, 5));
235 }
236
237
238 void
setFrame(int value)239 TimeCode::setFrame (int value)
240 {
241 if (value < 0 || value > 59)
242 throw IEX_NAMESPACE::ArgExc ("Cannot set frame field in time code. "
243 "New value is out of range.");
244
245 setBitField (_time, 0, 5, binaryToBcd (value));
246 }
247
248
249 bool
dropFrame() const250 TimeCode::dropFrame () const
251 {
252 return !!bitField (_time, 6, 6);
253 }
254
255
256 void
setDropFrame(bool value)257 TimeCode::setDropFrame (bool value)
258 {
259 setBitField (_time, 6, 6, (unsigned int) !!value);
260 }
261
262
263 bool
colorFrame() const264 TimeCode::colorFrame () const
265 {
266 return !!bitField (_time, 7, 7);
267 }
268
269
270 void
setColorFrame(bool value)271 TimeCode::setColorFrame (bool value)
272 {
273 setBitField (_time, 7, 7, (unsigned int) !!value);
274 }
275
276
277 bool
fieldPhase() const278 TimeCode::fieldPhase () const
279 {
280 return !!bitField (_time, 15, 15);
281 }
282
283
284 void
setFieldPhase(bool value)285 TimeCode::setFieldPhase (bool value)
286 {
287 setBitField (_time, 15, 15, (unsigned int) !!value);
288 }
289
290
291 bool
bgf0() const292 TimeCode::bgf0 () const
293 {
294 return !!bitField (_time, 23, 23);
295 }
296
297
298 void
setBgf0(bool value)299 TimeCode::setBgf0 (bool value)
300 {
301 setBitField (_time, 23, 23, (unsigned int) !!value);
302 }
303
304
305 bool
bgf1() const306 TimeCode::bgf1 () const
307 {
308 return!!bitField (_time, 30, 30);
309 }
310
311
312 void
setBgf1(bool value)313 TimeCode::setBgf1 (bool value)
314 {
315 setBitField (_time, 30, 30, (unsigned int) !!value);
316 }
317
318
319 bool
bgf2() const320 TimeCode::bgf2 () const
321 {
322 return !!bitField (_time, 31, 31);
323 }
324
325
326 void
setBgf2(bool value)327 TimeCode::setBgf2 (bool value)
328 {
329 setBitField (_time, 31, 31, (unsigned int) !!value);
330 }
331
332
333 int
binaryGroup(int group) const334 TimeCode::binaryGroup (int group) const
335 {
336 if (group < 1 || group > 8)
337 throw IEX_NAMESPACE::ArgExc ("Cannot extract binary group from time code "
338 "user data. Group number is out of range.");
339
340 int minBit = 4 * (group - 1);
341 int maxBit = minBit + 3;
342 return int (bitField (_user, minBit, maxBit));
343 }
344
345
346 void
setBinaryGroup(int group,int value)347 TimeCode::setBinaryGroup (int group, int value)
348 {
349 if (group < 1 || group > 8)
350 throw IEX_NAMESPACE::ArgExc ("Cannot extract binary group from time code "
351 "user data. Group number is out of range.");
352
353 int minBit = 4 * (group - 1);
354 int maxBit = minBit + 3;
355 setBitField (_user, minBit, maxBit, (unsigned int) value);
356 }
357
358
359 unsigned int
timeAndFlags(Packing packing) const360 TimeCode::timeAndFlags (Packing packing) const
361 {
362 if (packing == TV50_PACKING)
363 {
364 unsigned int t = _time;
365
366 t &= ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31));
367
368 t |= ((unsigned int) bgf0() << 15);
369 t |= ((unsigned int) bgf2() << 23);
370 t |= ((unsigned int) bgf1() << 30);
371 t |= ((unsigned int) fieldPhase() << 31);
372
373 return t;
374 }
375 if (packing == FILM24_PACKING)
376 {
377 return _time & ~((1 << 6) | (1 << 7));
378 }
379 else // packing == TV60_PACKING
380 {
381 return _time;
382 }
383 }
384
385
386 void
setTimeAndFlags(unsigned int value,Packing packing)387 TimeCode::setTimeAndFlags (unsigned int value, Packing packing)
388 {
389 if (packing == TV50_PACKING)
390 {
391 _time = value &
392 ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31));
393
394 if (value & (1 << 15))
395 setBgf0 (true);
396
397 if (value & (1 << 23))
398 setBgf2 (true);
399
400 if (value & (1 << 30))
401 setBgf1 (true);
402
403 if (value & (1 << 31))
404 setFieldPhase (true);
405 }
406 else if (packing == FILM24_PACKING)
407 {
408 _time = value & ~((1 << 6) | (1 << 7));
409 }
410 else // packing == TV60_PACKING
411 {
412 _time = value;
413 }
414 }
415
416
417 unsigned int
userData() const418 TimeCode::userData () const
419 {
420 return _user;
421 }
422
423
424 void
setUserData(unsigned int value)425 TimeCode::setUserData (unsigned int value)
426 {
427 _user = value;
428 }
429
430
431 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
432