/src/openexr/src/lib/OpenEXR/ImfTimeCode.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // SPDX-License-Identifier: BSD-3-Clause |
3 | | // Copyright (c) Contributors to the OpenEXR Project. |
4 | | // |
5 | | |
6 | | //----------------------------------------------------------------------------- |
7 | | // |
8 | | // class TimeCode |
9 | | // |
10 | | //----------------------------------------------------------------------------- |
11 | | |
12 | | #include "Iex.h" |
13 | | #include "ImfNamespace.h" |
14 | | #include <ImfTimeCode.h> |
15 | | |
16 | | OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER |
17 | | |
18 | | TimeCode::TimeCode () |
19 | 4 | { |
20 | 4 | _time = 0; |
21 | 4 | _user = 0; |
22 | 4 | } |
23 | | |
24 | | TimeCode::TimeCode ( |
25 | | int hours, |
26 | | int minutes, |
27 | | int seconds, |
28 | | int frame, |
29 | | bool dropFrame, |
30 | | bool colorFrame, |
31 | | bool fieldPhase, |
32 | | bool bgf0, |
33 | | bool bgf1, |
34 | | bool bgf2, |
35 | | int binaryGroup1, |
36 | | int binaryGroup2, |
37 | | int binaryGroup3, |
38 | | int binaryGroup4, |
39 | | int binaryGroup5, |
40 | | int binaryGroup6, |
41 | | int binaryGroup7, |
42 | | int binaryGroup8) |
43 | 0 | { |
44 | 0 | setHours (hours); |
45 | 0 | setMinutes (minutes); |
46 | 0 | setSeconds (seconds); |
47 | 0 | setFrame (frame); |
48 | 0 | setDropFrame (dropFrame); |
49 | 0 | setColorFrame (colorFrame); |
50 | 0 | setFieldPhase (fieldPhase); |
51 | 0 | setBgf0 (bgf0); |
52 | 0 | setBgf1 (bgf1); |
53 | 0 | setBgf2 (bgf2); |
54 | 0 | setBinaryGroup (1, binaryGroup1); |
55 | 0 | setBinaryGroup (2, binaryGroup2); |
56 | 0 | setBinaryGroup (3, binaryGroup3); |
57 | 0 | setBinaryGroup (4, binaryGroup4); |
58 | 0 | setBinaryGroup (5, binaryGroup5); |
59 | 0 | setBinaryGroup (6, binaryGroup6); |
60 | 0 | setBinaryGroup (7, binaryGroup7); |
61 | 0 | setBinaryGroup (8, binaryGroup8); |
62 | 0 | } |
63 | | |
64 | | TimeCode::TimeCode ( |
65 | | unsigned int timeAndFlags, unsigned int userData, Packing packing) |
66 | 4 | { |
67 | 4 | setTimeAndFlags (timeAndFlags, packing); |
68 | 4 | setUserData (userData); |
69 | 4 | } |
70 | | |
71 | | TimeCode::TimeCode (const TimeCode& other) |
72 | 4 | { |
73 | 4 | _time = other._time; |
74 | 4 | _user = other._user; |
75 | 4 | } |
76 | | |
77 | | TimeCode& |
78 | | TimeCode::operator= (const TimeCode& other) |
79 | 4 | { |
80 | 4 | if (&other != this) |
81 | 4 | { |
82 | 4 | _time = other._time; |
83 | 4 | _user = other._user; |
84 | 4 | } |
85 | 4 | return *this; |
86 | 4 | } |
87 | | |
88 | | bool |
89 | | TimeCode::operator== (const TimeCode& c) const |
90 | 0 | { |
91 | 0 | return (_time == c._time && _user == c._user); |
92 | 0 | } |
93 | | |
94 | | bool |
95 | | TimeCode::operator!= (const TimeCode& c) const |
96 | 0 | { |
97 | 0 | return (_time != c._time || _user != c._user); |
98 | 0 | } |
99 | | |
100 | | namespace |
101 | | { |
102 | | |
103 | | unsigned int |
104 | | bitField (unsigned int value, int minBit, int maxBit) |
105 | 0 | { |
106 | 0 | int shift = minBit; |
107 | 0 | unsigned int mask = (~(~0U << (maxBit - minBit + 1)) << minBit); |
108 | 0 | return (value & mask) >> shift; |
109 | 0 | } |
110 | | |
111 | | void |
112 | | setBitField (unsigned int& value, int minBit, int maxBit, unsigned int field) |
113 | 0 | { |
114 | 0 | int shift = minBit; |
115 | 0 | unsigned int mask = (~(~0U << (maxBit - minBit + 1)) << minBit); |
116 | 0 | value = ((value & ~mask) | ((field << shift) & mask)); |
117 | 0 | } |
118 | | |
119 | | int |
120 | | bcdToBinary (unsigned int bcd) |
121 | 0 | { |
122 | 0 | return int ((bcd & 0x0f) + 10 * ((bcd >> 4) & 0x0f)); |
123 | 0 | } |
124 | | |
125 | | unsigned int |
126 | | binaryToBcd (int binary) |
127 | 0 | { |
128 | 0 | int units = binary % 10; |
129 | 0 | int tens = (binary / 10) % 10; |
130 | 0 | return (unsigned int) (units | (tens << 4)); |
131 | 0 | } |
132 | | |
133 | | } // namespace |
134 | | |
135 | | int |
136 | | TimeCode::hours () const |
137 | 0 | { |
138 | 0 | return bcdToBinary (bitField (_time, 24, 29)); |
139 | 0 | } |
140 | | |
141 | | void |
142 | | TimeCode::setHours (int value) |
143 | 0 | { |
144 | 0 | if (value < 0 || value > 23) |
145 | 0 | throw IEX_NAMESPACE::ArgExc ("Cannot set hours field in time code. " |
146 | 0 | "New value is out of range."); |
147 | | |
148 | 0 | setBitField (_time, 24, 29, binaryToBcd (value)); |
149 | 0 | } |
150 | | |
151 | | int |
152 | | TimeCode::minutes () const |
153 | 0 | { |
154 | 0 | return bcdToBinary (bitField (_time, 16, 22)); |
155 | 0 | } |
156 | | |
157 | | void |
158 | | TimeCode::setMinutes (int value) |
159 | 0 | { |
160 | 0 | if (value < 0 || value > 59) |
161 | 0 | throw IEX_NAMESPACE::ArgExc ("Cannot set minutes field in time code. " |
162 | 0 | "New value is out of range."); |
163 | | |
164 | 0 | setBitField (_time, 16, 22, binaryToBcd (value)); |
165 | 0 | } |
166 | | |
167 | | int |
168 | | TimeCode::seconds () const |
169 | 0 | { |
170 | 0 | return bcdToBinary (bitField (_time, 8, 14)); |
171 | 0 | } |
172 | | |
173 | | void |
174 | | TimeCode::setSeconds (int value) |
175 | 0 | { |
176 | 0 | if (value < 0 || value > 59) |
177 | 0 | throw IEX_NAMESPACE::ArgExc ("Cannot set seconds field in time code. " |
178 | 0 | "New value is out of range."); |
179 | | |
180 | 0 | setBitField (_time, 8, 14, binaryToBcd (value)); |
181 | 0 | } |
182 | | |
183 | | int |
184 | | TimeCode::frame () const |
185 | 0 | { |
186 | 0 | return bcdToBinary (bitField (_time, 0, 5)); |
187 | 0 | } |
188 | | |
189 | | void |
190 | | TimeCode::setFrame (int value) |
191 | 0 | { |
192 | 0 | if (value < 0 || value > 29) |
193 | 0 | throw IEX_NAMESPACE::ArgExc ("Cannot set frame field in time code. " |
194 | 0 | "New value is out of range."); |
195 | | |
196 | 0 | setBitField (_time, 0, 5, binaryToBcd (value)); |
197 | 0 | } |
198 | | |
199 | | bool |
200 | | TimeCode::dropFrame () const |
201 | 0 | { |
202 | 0 | return !!bitField (_time, 6, 6); |
203 | 0 | } |
204 | | |
205 | | void |
206 | | TimeCode::setDropFrame (bool value) |
207 | 0 | { |
208 | 0 | setBitField (_time, 6, 6, (unsigned int) !!value); |
209 | 0 | } |
210 | | |
211 | | bool |
212 | | TimeCode::colorFrame () const |
213 | 0 | { |
214 | 0 | return !!bitField (_time, 7, 7); |
215 | 0 | } |
216 | | |
217 | | void |
218 | | TimeCode::setColorFrame (bool value) |
219 | 0 | { |
220 | 0 | setBitField (_time, 7, 7, (unsigned int) !!value); |
221 | 0 | } |
222 | | |
223 | | bool |
224 | | TimeCode::fieldPhase () const |
225 | 0 | { |
226 | 0 | return !!bitField (_time, 15, 15); |
227 | 0 | } |
228 | | |
229 | | void |
230 | | TimeCode::setFieldPhase (bool value) |
231 | 0 | { |
232 | 0 | setBitField (_time, 15, 15, (unsigned int) !!value); |
233 | 0 | } |
234 | | |
235 | | bool |
236 | | TimeCode::bgf0 () const |
237 | 0 | { |
238 | 0 | return !!bitField (_time, 23, 23); |
239 | 0 | } |
240 | | |
241 | | void |
242 | | TimeCode::setBgf0 (bool value) |
243 | 0 | { |
244 | 0 | setBitField (_time, 23, 23, (unsigned int) !!value); |
245 | 0 | } |
246 | | |
247 | | bool |
248 | | TimeCode::bgf1 () const |
249 | 0 | { |
250 | 0 | return !!bitField (_time, 30, 30); |
251 | 0 | } |
252 | | |
253 | | void |
254 | | TimeCode::setBgf1 (bool value) |
255 | 0 | { |
256 | 0 | setBitField (_time, 30, 30, (unsigned int) !!value); |
257 | 0 | } |
258 | | |
259 | | bool |
260 | | TimeCode::bgf2 () const |
261 | 0 | { |
262 | 0 | return !!bitField (_time, 31, 31); |
263 | 0 | } |
264 | | |
265 | | void |
266 | | TimeCode::setBgf2 (bool value) |
267 | 0 | { |
268 | 0 | setBitField (_time, 31, 31, (unsigned int) !!value); |
269 | 0 | } |
270 | | |
271 | | int |
272 | | TimeCode::binaryGroup (int group) const |
273 | 0 | { |
274 | 0 | if (group < 1 || group > 8) |
275 | 0 | throw IEX_NAMESPACE::ArgExc ( |
276 | 0 | "Cannot extract binary group from time code " |
277 | 0 | "user data. Group number is out of range."); |
278 | | |
279 | 0 | int minBit = 4 * (group - 1); |
280 | 0 | int maxBit = minBit + 3; |
281 | 0 | return int (bitField (_user, minBit, maxBit)); |
282 | 0 | } |
283 | | |
284 | | void |
285 | | TimeCode::setBinaryGroup (int group, int value) |
286 | 0 | { |
287 | 0 | if (group < 1 || group > 8) |
288 | 0 | throw IEX_NAMESPACE::ArgExc ( |
289 | 0 | "Cannot extract binary group from time code " |
290 | 0 | "user data. Group number is out of range."); |
291 | | |
292 | 0 | int minBit = 4 * (group - 1); |
293 | 0 | int maxBit = minBit + 3; |
294 | 0 | setBitField (_user, minBit, maxBit, (unsigned int) value); |
295 | 0 | } |
296 | | |
297 | | unsigned int |
298 | | TimeCode::timeAndFlags (Packing packing) const |
299 | 0 | { |
300 | 0 | if (packing == TV50_PACKING) |
301 | 0 | { |
302 | 0 | unsigned int t = _time; |
303 | |
|
304 | 0 | t &= ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31)); |
305 | |
|
306 | 0 | t |= ((unsigned int) bgf0 () << 15); |
307 | 0 | t |= ((unsigned int) bgf2 () << 23); |
308 | 0 | t |= ((unsigned int) bgf1 () << 30); |
309 | 0 | t |= ((unsigned int) fieldPhase () << 31); |
310 | |
|
311 | 0 | return t; |
312 | 0 | } |
313 | 0 | if (packing == FILM24_PACKING) { return _time & ~((1 << 6) | (1 << 7)); } |
314 | 0 | else // packing == TV60_PACKING |
315 | 0 | { |
316 | 0 | return _time; |
317 | 0 | } |
318 | 0 | } |
319 | | |
320 | | void |
321 | | TimeCode::setTimeAndFlags (unsigned int value, Packing packing) |
322 | 4 | { |
323 | 4 | if (packing == TV50_PACKING) |
324 | 0 | { |
325 | 0 | _time = |
326 | 0 | value & ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31)); |
327 | |
|
328 | 0 | if (value & (1 << 15)) setBgf0 (true); |
329 | |
|
330 | 0 | if (value & (1 << 23)) setBgf2 (true); |
331 | |
|
332 | 0 | if (value & (1 << 30)) setBgf1 (true); |
333 | |
|
334 | 0 | if (value & (1 << 31)) setFieldPhase (true); |
335 | 0 | } |
336 | 4 | else if (packing == FILM24_PACKING) |
337 | 0 | { |
338 | 0 | _time = value & ~((1 << 6) | (1 << 7)); |
339 | 0 | } |
340 | 4 | else // packing == TV60_PACKING |
341 | 4 | { |
342 | 4 | _time = value; |
343 | 4 | } |
344 | 4 | } |
345 | | |
346 | | unsigned int |
347 | | TimeCode::userData () const |
348 | 0 | { |
349 | 0 | return _user; |
350 | 0 | } |
351 | | |
352 | | void |
353 | | TimeCode::setUserData (unsigned int value) |
354 | 4 | { |
355 | 4 | _user = value; |
356 | 4 | } |
357 | | |
358 | | OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT |