ISXDDataEssenceDescriptor_NamespaceURI UL fixed
[asdcplib.git] / src / ACES.cpp
1 /*
2 Copyright (c) 2018, Bjoern Stresing, Patrick Bichiou, Wolfgang Ruppel,
3 John Hurst
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. The name of the author may not be used to endorse or promote products
16 derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "ACES.h"
31 #include "KM_log.h"
32
33
34 namespace
35 {
36
37 const std::string AttrAcesImageContainerFlag("acesImageContainerFlag");
38 const std::string AttrChannels("channels");
39 const std::string AttrChromaticities("chromaticities");
40 const std::string AttrCompression("compression");
41 const std::string AttrDataWindow("dataWindow");
42 const std::string AttrDisplayWindow("displayWindow");
43 const std::string AttrLineOrder("lineOrder");
44 const std::string AttrPixelAspectRatio("pixelAspectRatio");
45 const std::string AttrScreenWindowCenter("screenWindowCenter");
46 const std::string AttrScreenWindowWidth("screenWindowWidth");
47
48 const std::string TypeUnsignedChar("unsigned char");
49 const std::string TypeUnsignedChar_("unsignedChar");
50 const std::string TypeShort("short");
51 const std::string TypeUnsignedShort("unsigned short");
52 const std::string TypeUnsignedShort_("unsignedShort");
53 const std::string TypeInt("int");
54 const std::string TypeUnsignedInt("unsigned int");
55 const std::string TypeUnsignedInt_("unsignedInt");
56 const std::string TypeUnsignedLong("unsigned long");
57 const std::string TypeUnsignedLong_("unsignedLong");
58 const std::string TypeHalf("half");
59 const std::string TypeFloat("float");
60 const std::string TypeDouble("double");
61 const std::string TypeBox2i("box2i");
62 const std::string TypeChlist("chlist");
63 const std::string TypeChromaticities("chromaticities");
64 const std::string TypeCompression("compression");
65 const std::string TypeLineOrder("lineOrder");
66 const std::string TypeKeycode("keycode");
67 const std::string TypeRational("rational");
68 const std::string TypeString("string");
69 const std::string TypeStringVector("stringVector");
70 const std::string TypeTimecode("timecode");
71 const std::string TypeV2f("v2f");
72 const std::string TypeV3f("v3f");
73
74 } // namespace
75
76 void AS_02::ACES::Attribute::Move(const byte_t *buf)
77 {
78   mAttrType = Invalid;
79   mType = Unknown_t;
80   mAttrName.clear();
81   mpValue = NULL;
82   mDataSize = 0;
83   mValueSize = 0;
84   if(buf)
85   {
86     mpData = buf;
87     while(*buf != 0x00 && buf - mpData < 256)
88     {
89       buf++;
90     }
91     if(buf - mpData < 1)
92     {
93        Kumu::DefaultLogSink().Error("Size of attribute name == 0 Bytes\n");
94        return;
95     }
96     else if(buf - mpData > 255)
97     {
98        Kumu::DefaultLogSink().Error("Size of attribute name > 255 Bytes\n");
99        return;
100     }
101     mAttrName.assign((const char*)mpData, buf - mpData); // We don't want the Null termination.
102     buf++; // Move to "attribute type name".
103     const byte_t *ptmp = buf;
104     while(*buf != 0x00 && buf - ptmp < 256)
105     {
106       buf++;
107     }
108     if(buf - ptmp < 1)
109     {
110        Kumu::DefaultLogSink().Error("Size of attribute type == 0 Bytes\n");
111        return;
112     }
113     else if(buf - ptmp > 255)
114     {
115        Kumu::DefaultLogSink().Error("Size of attribute type > 255 Bytes\n");
116        return;
117     }
118     std::string attribute_type_name;
119     attribute_type_name.assign((const char*)ptmp, buf - ptmp); // We don't want the Null termination.
120     buf++; // Move to "attribute size".
121     i32_t size = KM_i32_LE(*(i32_t*)(buf));
122     if(size < 0)
123     {
124        Kumu::DefaultLogSink().Error("Attribute size is negative\n");
125        return;
126     }
127     mValueSize = size;
128     mpValue = buf + 4;
129     mDataSize = mpValue - mpData + mValueSize;
130     MatchAttribute(mAttrName);
131     MatchType(attribute_type_name);
132   }
133 }
134
135 void AS_02::ACES::Attribute::MatchAttribute(const std::string &Type)
136 {
137
138   if(Type == AttrAcesImageContainerFlag) mAttrType = AcesImageContainerFlag;
139   else if(Type == AttrChannels) mAttrType = Channels;
140   else if(Type == AttrChromaticities) mAttrType = Chromaticities;
141   else if(Type == AttrCompression) mAttrType = Compression;
142   else if(Type == AttrDataWindow) mAttrType = DataWindow;
143   else if(Type == AttrDisplayWindow) mAttrType = DisplayWindow;
144   else if(Type == AttrLineOrder) mAttrType = LineOrder;
145   else if(Type == AttrPixelAspectRatio) mAttrType = PixelAspectRatio;
146   else if(Type == AttrScreenWindowCenter) mAttrType = ScreenWindowCenter;
147   else if(Type == AttrScreenWindowWidth) mAttrType = SreenWindowWidth;
148   else mAttrType = Other;
149 }
150
151 void AS_02::ACES::Attribute::MatchType(const std::string &Type)
152 {
153
154   if(Type == TypeUnsignedChar || Type == TypeUnsignedChar_) mType = UnsignedChar_t;
155   else if(Type == TypeShort) mType = Short_t;
156   else if(Type == TypeUnsignedShort || Type == TypeUnsignedShort_) mType = UnsignedShort_t;
157   else if(Type == TypeInt) mType = Int_t;
158   else if(Type == TypeUnsignedInt || Type == TypeUnsignedInt_) mType = UnsignedInt_t;
159   else if(Type == TypeUnsignedLong || Type == TypeUnsignedLong_) mType = UnsignedLong_t;
160   else if(Type == TypeHalf) mType = Half_t;
161   else if(Type == TypeFloat) mType = Float_t;
162   else if(Type == TypeDouble) mType = Double_t;
163   else if(Type == TypeBox2i) mType = Box2i_t;
164   else if(Type == TypeChlist) mType = Chlist_t;
165   else if(Type == TypeChromaticities) mType = Chromaticities_t;
166   else if(Type == TypeCompression) mType = Compression_t;
167   else if(Type == TypeLineOrder) mType = LineOrder_t;
168   else if(Type == TypeKeycode) mType = Keycode_t;
169   else if(Type == TypeRational) mType = Rational_t;
170   else if(Type == TypeString) mType = String_t;
171   else if(Type == TypeStringVector) mType = StringVector_t;
172   else if(Type == TypeTimecode) mType = Timecode_t;
173   else if(Type == TypeV2f) mType = V2f_t;
174   else if(Type == TypeV3f) mType = V3f_t;
175   else mType = Unknown_t;
176 }
177
178 AS_02::Result_t AS_02::ACES::Attribute::CopyToGenericContainer(other &value) const
179 {
180
181   generic gen;
182   if(mValueSize > sizeof(gen.data)) return RESULT_FAIL;
183   memcpy(gen.data, mpValue, mValueSize);
184   gen.type = mType;
185   gen.size = mValueSize;
186   gen.attributeName = mAttrName;
187   value.push_back(gen);
188   return RESULT_OK;
189 }
190
191 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(ui8_t &value) const
192 {
193
194   if(sizeof(value) != mValueSize) return RESULT_FAIL;
195   ACESDataAccessor::AsBasicType(mpValue, value);
196   return RESULT_OK;
197 }
198
199 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(i16_t &value) const
200 {
201
202   if(sizeof(value) != mValueSize) return RESULT_FAIL;
203   ACESDataAccessor::AsBasicType(mpValue, value);
204   return RESULT_OK;
205 }
206
207 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(ui16_t &value) const
208 {
209
210   if(sizeof(value) != mValueSize) return RESULT_FAIL;
211   ACESDataAccessor::AsBasicType(mpValue, value);
212   return RESULT_OK;
213 }
214
215 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(i32_t &value) const {
216
217   if(sizeof(value) != mValueSize) return RESULT_FAIL;
218   ACESDataAccessor::AsBasicType(mpValue, value);
219   return RESULT_OK;
220 }
221
222 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(ui32_t &value) const
223 {
224
225   if(sizeof(value) != mValueSize) return RESULT_FAIL;
226   ACESDataAccessor::AsBasicType(mpValue, value);
227   return RESULT_OK;
228 }
229
230 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(ui64_t &value) const
231 {
232
233   if(sizeof(value) != mValueSize) return RESULT_FAIL;
234   ACESDataAccessor::AsBasicType(mpValue, value);
235   return RESULT_OK;
236 }
237
238 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(real32_t &value) const
239 {
240
241   if(sizeof(value) != mValueSize) return RESULT_FAIL;
242   ACESDataAccessor::AsBasicType(mpValue, value);
243   return RESULT_OK;
244 }
245
246 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBasicType(real64_t &value) const
247 {
248
249   if(sizeof(value) != mValueSize) return RESULT_FAIL;
250   ACESDataAccessor::AsBasicType(mpValue, value);
251   return RESULT_OK;
252 }
253
254 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsBox2i(box2i &value) const
255 {
256
257   ACESDataAccessor::AsBox2i(mpValue, value);
258   return RESULT_OK;
259 }
260
261 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsChlist(chlist &value) const
262 {
263
264   ACESDataAccessor::AsChlist(mpValue, mValueSize, value);
265   return RESULT_OK;
266 }
267
268 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsChromaticities(chromaticities &value) const
269 {
270
271   ACESDataAccessor::AsChromaticities(mpValue, value);
272   return RESULT_OK;
273 }
274
275 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsKeycode(keycode &value) const
276 {
277
278   ACESDataAccessor::AsKeycode(mpValue, value);
279   return RESULT_OK;
280 }
281
282 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsRational(ASDCP::Rational &value) const
283 {
284
285   ACESDataAccessor::AsRational(mpValue, value);
286   return RESULT_OK;
287 }
288
289 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsString(std::string &value) const
290 {
291
292   ACESDataAccessor::AsString(mpValue, mValueSize, value);
293   return RESULT_OK;
294 }
295
296 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsStringVector(stringVector &value) const
297 {
298
299   ACESDataAccessor::AsStringVector(mpValue, mValueSize, value);
300   return RESULT_OK;
301 }
302
303 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsV2f(v2f &value) const
304 {
305
306   ACESDataAccessor::AsV2f(mpValue, value);
307   return RESULT_OK;
308 }
309
310 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsV3f(v3f &value) const
311 {
312
313   ACESDataAccessor::AsV3f(mpValue, value);
314   return RESULT_OK;
315 }
316
317 AS_02::Result_t AS_02::ACES::Attribute::GetValueAsTimecode(timecode &value) const
318 {
319
320   ACESDataAccessor::AsTimecode(mpValue, value);
321   return RESULT_OK;
322 }
323
324 AS_02::Result_t AS_02::ACES::GetNextAttribute(const byte_t **buf, Attribute &attr)
325 {
326
327   assert((buf != NULL) && (*buf != NULL));
328   while(**buf != 0x00) { (*buf)++; }
329   (*buf)++;
330   while(**buf != 0x00) { (*buf)++; }
331   (*buf)++;
332   i32_t size = KM_i32_LE(*(i32_t*)(*buf));
333   if(size < 0)
334   {
335     Kumu::DefaultLogSink().Error("Attribute size is negative\n");
336     return RESULT_FAIL;
337   }
338   *buf += 4 + size;
339   if(**buf == 0x00)
340   {
341     return RESULT_ENDOFFILE; // Indicates end of header.
342   }
343   attr.Move(*buf);
344   return RESULT_OK;
345 }
346
347 AS_02::Result_t AS_02::ACES::CheckMagicNumber(const byte_t **buf)
348 {
349
350   assert((buf != NULL) && (*buf != NULL));
351   if(memcmp(Magic, *buf, 4) != 0) return RESULT_FAIL;
352   *buf += 4;
353   return RESULT_OK;
354 }
355
356 AS_02::Result_t AS_02::ACES::CheckVersionField(const byte_t **buf)
357 {
358
359   assert((buf != NULL) && (*buf != NULL));
360   if(memcmp(Version_short, *buf, 4) != 0 && memcmp(Version_long, *buf, 4) != 0) return RESULT_FAIL;
361   *buf += 4;
362   return RESULT_OK;
363 }
364
365 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, ui8_t &value)
366 {
367
368   value = *(ui8_t*)(buf);
369 }
370
371 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, i16_t &value)
372 {
373
374   value = KM_i16_LE(*(i16_t*)(buf));
375 }
376
377 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, ui16_t &value)
378 {
379
380   value = KM_i16_LE(*(ui16_t*)(buf));
381 }
382
383 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, i32_t &value)
384 {
385
386   value = KM_i32_LE(*(i32_t*)(buf));
387 }
388
389 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, ui32_t &value)
390 {
391
392   value = KM_i32_LE(*(ui32_t*)(buf));
393 }
394
395 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, ui64_t &value)
396 {
397
398   value = KM_i64_LE(*(ui64_t*)(buf));
399 }
400
401 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, real32_t &value)
402 {
403
404   value = KM_i32_LE(*(real32_t*)(buf));
405 }
406
407 void AS_02::ACES::ACESDataAccessor::AsBasicType(const byte_t *buf, real64_t &value)
408 {
409
410   value = KM_i64_LE(*(real64_t*)(buf));
411 }
412
413 void AS_02::ACES::ACESDataAccessor::AsBox2i(const byte_t *buf, box2i &value)
414 {
415
416   value.xMin = KM_i32_LE(*(i32_t*)(buf));
417   value.yMin = KM_i32_LE(*(i32_t*)(buf + 4));
418   value.xMax = KM_i32_LE(*(i32_t*)(buf + 8));
419   value.yMax = KM_i32_LE(*(i32_t*)(buf + 12));
420 }
421
422 void AS_02::ACES::ACESDataAccessor::AsChlist(const byte_t *buf, ui32_t size, chlist &value)
423 {
424
425   const byte_t *end = buf + size - 1;
426   while(buf < end)
427   {
428     const byte_t *ptmp = buf;
429     while(*buf != 0x00 && buf - ptmp < 256) { buf++; }
430     if(buf - ptmp < 1)
431     {
432        Kumu::DefaultLogSink().Error("Size of name == 0 Bytes\n");
433        return;
434     }
435     else if(buf - ptmp > 255)
436     {
437        Kumu::DefaultLogSink().Error("Size of name > 255 Bytes\n");
438        return;
439     }
440     channel ch;
441     ch.name.assign((const char*)ptmp, buf - ptmp); // We don't want the Null termination.
442     buf++;
443     ch.pixelType = KM_i32_LE(*(i32_t*)(buf));
444     buf += 4;
445     ch.pLinear = KM_i32_LE(*(ui32_t*)(buf));
446     buf += 4;
447     ch.xSampling = KM_i32_LE(*(i32_t*)(buf));
448     buf += 4;
449     ch.ySampling = KM_i32_LE(*(i32_t*)(buf));
450     buf += 4;
451     value.push_back(ch);
452   }
453 }
454
455 void AS_02::ACES::ACESDataAccessor::AsChromaticities(const byte_t *buf, chromaticities &value)
456 {
457
458   value.red.x = KM_i32_LE(*(real32_t*)(buf));
459   value.red.y = KM_i32_LE(*(real32_t*)(buf + 4));
460   value.green.x = KM_i32_LE(*(real32_t*)(buf + 8));
461   value.green.y = KM_i32_LE(*(real32_t*)(buf + 12));
462   value.blue.x = KM_i32_LE(*(real32_t*)(buf + 16));
463   value.blue.y = KM_i32_LE(*(real32_t*)(buf + 20));
464   value.white.x = KM_i32_LE(*(real32_t*)(buf + 24));
465   value.white.y = KM_i32_LE(*(real32_t*)(buf + 28));
466 }
467
468 void AS_02::ACES::ACESDataAccessor::AsKeycode(const byte_t *buf, keycode &value)
469 {
470
471   value.filmMfcCode = KM_i32_LE(*(i32_t*)(buf));
472   value.filmType = KM_i32_LE(*(i32_t*)(buf + 4));
473   value.prefix = KM_i32_LE(*(i32_t*)(buf + 8));
474   value.count = KM_i32_LE(*(i32_t*)(buf + 12));
475   value.perfOffset = KM_i32_LE(*(i32_t*)(buf + 16));
476   value.perfsPerFrame = KM_i32_LE(*(i32_t*)(buf + 20));
477   value.perfsPerCount = KM_i32_LE(*(i32_t*)(buf + 24));
478 }
479
480 void AS_02::ACES::ACESDataAccessor::AsRational(const byte_t *buf, ASDCP::Rational &value)
481 {
482
483   value.Numerator = KM_i32_LE(*(i32_t*)(buf));
484   value.Denominator = KM_i32_LE(*(ui32_t*)(buf + 4));
485 }
486
487 void AS_02::ACES::ACESDataAccessor::AsString(const byte_t *buf, ui32_t size, std::string &value)
488 {
489
490   value.assign((const char*)buf, size);
491 }
492
493 void AS_02::ACES::ACESDataAccessor::AsStringVector(const byte_t *buf, ui32_t size, stringVector &value)
494 {
495
496   const byte_t *end = buf + size - 1;
497   while(buf < end)
498   {
499     i32_t str_length = KM_i32_LE(*(i32_t*)(buf));
500     std::string str;
501     str.assign((const char*)buf, str_length);
502     value.push_back(str);
503     if(buf + str_length >= end) break;
504     else buf += str_length;
505   }
506 }
507
508 void AS_02::ACES::ACESDataAccessor::AsV2f(const byte_t *buf, v2f &value)
509 {
510
511   value.x = KM_i32_LE(*(real32_t*)(buf));
512   value.y = KM_i32_LE(*(real32_t*)(buf + 4));
513 }
514
515 void AS_02::ACES::ACESDataAccessor::AsV3f(const byte_t *buf, v3f &value)
516 {
517
518   value.x = KM_i32_LE(*(real32_t*)(buf));
519   value.y = KM_i32_LE(*(real32_t*)(buf + 4));
520   value.z = KM_i32_LE(*(real32_t*)(buf + 8));
521 }
522
523 void AS_02::ACES::ACESDataAccessor::AsTimecode(const byte_t *buf, timecode &value)
524 {
525
526   value.timeAndFlags = KM_i32_LE(*(ui32_t*)(buf));
527   value.userData = KM_i32_LE(*(ui32_t*)(buf + 4));
528 }