Home | History | Annotate | Download | only in IlmImf
      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 
     48 TimeCode::TimeCode ()
     49 {
     50     _time = 0;
     51     _user = 0;
     52 }
     53 
     54 
     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 
     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 
    106 TimeCode::TimeCode (const TimeCode &other)
    107 {
    108     _time = other._time;
    109     _user = other._user;
    110 }
    111 
    112 
    113 TimeCode &
    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
    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
    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
    143 bcdToBinary (unsigned int bcd)
    144 {
    145     return int ((bcd & 0x0f) + 10 * ((bcd >> 4) & 0x0f));
    146 }
    147 
    148 
    149 unsigned int
    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
    162 TimeCode::hours () const
    163 {
    164     return bcdToBinary (bitField (_time, 24, 29));
    165 }
    166 
    167 
    168 void
    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
    180 TimeCode::minutes () const
    181 {
    182     return bcdToBinary (bitField (_time, 16, 22));
    183 }
    184 
    185 
    186 void
    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
    198 TimeCode::seconds () const
    199 {
    200     return bcdToBinary (bitField (_time, 8, 14));
    201 }
    202 
    203 
    204 void
    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
    216 TimeCode::frame () const
    217 {
    218     return bcdToBinary (bitField (_time, 0, 5));
    219 }
    220 
    221 
    222 void
    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
    234 TimeCode::dropFrame () const
    235 {
    236     return bool (bitField (_time, 6, 6));
    237 }
    238 
    239 
    240 void
    241 TimeCode::setDropFrame (bool value)
    242 {
    243     setBitField (_time, 6, 6, (unsigned int) !!value);
    244 }
    245 
    246 
    247 bool
    248 TimeCode::colorFrame () const
    249 {
    250     return bool (bitField (_time, 7, 7));
    251 }
    252 
    253 
    254 void
    255 TimeCode::setColorFrame (bool value)
    256 {
    257     setBitField (_time, 7, 7, (unsigned int) !!value);
    258 }
    259 
    260 
    261 bool
    262 TimeCode::fieldPhase () const
    263 {
    264     return bool (bitField (_time, 15, 15));
    265 }
    266 
    267 
    268 void
    269 TimeCode::setFieldPhase (bool value)
    270 {
    271     setBitField (_time, 15, 15, (unsigned int) !!value);
    272 }
    273 
    274 
    275 bool
    276 TimeCode::bgf0 () const
    277 {
    278     return bool (bitField (_time, 23, 23));
    279 }
    280 
    281 
    282 void
    283 TimeCode::setBgf0 (bool value)
    284 {
    285     setBitField (_time, 23, 23, (unsigned int) !!value);
    286 }
    287 
    288 
    289 bool
    290 TimeCode::bgf1 () const
    291 {
    292     return bool (bitField (_time, 30, 30));
    293 }
    294 
    295 
    296 void
    297 TimeCode::setBgf1 (bool value)
    298 {
    299     setBitField (_time, 30, 30, (unsigned int) !!value);
    300 }
    301 
    302 
    303 bool
    304 TimeCode::bgf2 () const
    305 {
    306     return bool (bitField (_time, 31, 31));
    307 }
    308 
    309 
    310 void
    311 TimeCode::setBgf2 (bool value)
    312 {
    313     setBitField (_time, 31, 31, (unsigned int) !!value);
    314 }
    315 
    316 
    317 int
    318 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
    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
    344 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
    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
    402 TimeCode::userData () const
    403 {
    404     return _user;
    405 }
    406 
    407 
    408 void
    409 TimeCode::setUserData (unsigned int value)
    410 {
    411     _user = value;
    412 }
    413 
    414 
    415 } // namespace Imf
    416