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