Modify to test email notice.
[asdcplib.git] / src / ACES_Codestream_Parser.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_fileio.h>
32 #include <assert.h>
33 #include <KM_log.h>
34
35
36 using Kumu::DefaultLogSink;
37
38 AS_02::Result_t AS_02::ACES::ParseMetadataIntoDesc(const FrameBuffer &FB, PictureDescriptor &PDesc, byte_t *start_of_data /*= NULL*/) {
39
40   const byte_t* p = FB.RoData();
41   const byte_t* end_p = p + FB.Size();
42   Result_t result = RESULT_OK;
43   Attribute NextAttribute;
44
45   result = CheckMagicNumber(&p);
46   if(ASDCP_FAILURE(result)) return result;
47   result = CheckVersionField(&p);
48   if(ASDCP_FAILURE(result)) return result;
49   NextAttribute.Move(p);
50
51   while(p < end_p && ASDCP_SUCCESS(result)) {
52
53     if(NextAttribute.IsValid()) {
54       switch(NextAttribute.GetAttribute()) {
55         case AcesImageContainerFlag:
56           result = NextAttribute.GetValueAsBasicType(PDesc.AcesImageContainerFlag);
57           break;
58         case Channels:
59           result = NextAttribute.GetValueAsChlist(PDesc.Channels);
60           break;
61         case Chromaticities:
62           result = NextAttribute.GetValueAsChromaticities(PDesc.Chromaticities);
63           break;
64         case Compression:
65           result = NextAttribute.GetValueAsBasicType(PDesc.Compression);
66           break;
67         case DataWindow:
68           result = NextAttribute.GetValueAsBox2i(PDesc.DataWindow);
69           break;
70         case DisplayWindow:
71           result = NextAttribute.GetValueAsBox2i(PDesc.DisplayWindow);
72           break;
73         case LineOrder:
74           result = NextAttribute.GetValueAsBasicType(PDesc.LineOrder);
75           break;
76         case PixelAspectRatio:
77           result = NextAttribute.GetValueAsBasicType(PDesc.PixelAspectRatio);
78           break;
79         case ScreenWindowCenter:
80           result = NextAttribute.GetValueAsV2f(PDesc.ScreenWindowCenter);
81           break;
82         case SreenWindowWidth:
83           result = NextAttribute.GetValueAsBasicType(PDesc.ScreenWindowWidth);
84           break;
85         case Other:
86           result = NextAttribute.CopyToGenericContainer(PDesc.Other);
87           break;
88         default:
89           DefaultLogSink().Error("Attribute mismatch.\n");
90           result = RESULT_FAIL;
91           break;
92       }
93       if(ASDCP_FAILURE(result))
94       {
95         result = RESULT_FAIL;
96         break;
97       }
98     }
99     result = GetNextAttribute(&p, NextAttribute);
100     if(result == RESULT_ENDOFFILE)
101     { // Indicates end of header.
102       p = end_p;
103       result = RESULT_OK;
104     }
105   }
106   return result;
107 }
108
109 class AS_02::ACES::CodestreamParser::h__CodestreamParser
110 {
111
112   ASDCP_NO_COPY_CONSTRUCT(h__CodestreamParser);
113
114 public:
115   PictureDescriptor  m_PDesc;
116   Kumu::FileReader   m_File;
117
118   h__CodestreamParser()
119   {
120     memset(&m_PDesc, 0, sizeof(m_PDesc));
121     m_PDesc.EditRate = ASDCP::Rational(24, 1);
122     m_PDesc.SampleRate = m_PDesc.EditRate;
123   }
124
125   ~h__CodestreamParser() {}
126
127   Result_t OpenReadFrame(const std::string& filename, FrameBuffer& FB)
128   {
129     m_File.Close();
130     Result_t result = m_File.OpenRead(filename);
131
132     if(ASDCP_SUCCESS(result))
133     {
134       Kumu::fsize_t file_size = m_File.Size();
135       if(FB.Capacity() < file_size)
136       {
137         DefaultLogSink().Error("FrameBuf.Capacity: %u frame length: %u\n", FB.Capacity(), (ui32_t)file_size);
138         return RESULT_SMALLBUF;
139       }
140     }
141
142     ui32_t read_count;
143
144     if(ASDCP_SUCCESS(result)) result = m_File.Read(FB.Data(), FB.Capacity(), &read_count);
145
146     if(ASDCP_SUCCESS(result)) FB.Size(read_count);
147
148     if(ASDCP_SUCCESS(result))
149     {
150       byte_t start_of_data = 0; // out param
151       result = ParseMetadataIntoDesc(FB, m_PDesc, &start_of_data);
152       if(ASDCP_SUCCESS(result)) FB.PlaintextOffset(start_of_data);
153     }
154     return result;
155   }
156 };
157
158 AS_02::ACES::CodestreamParser::CodestreamParser()
159 {
160
161 }
162
163 AS_02::ACES::CodestreamParser::~CodestreamParser()
164 {
165
166 }
167
168 AS_02::Result_t AS_02::ACES::CodestreamParser::OpenReadFrame(const std::string &filename, FrameBuffer &FB) const
169 {
170
171   const_cast<AS_02::ACES::CodestreamParser*>(this)->m_Parser = new h__CodestreamParser;
172   return m_Parser->OpenReadFrame(filename, FB);
173 }
174
175 AS_02::Result_t AS_02::ACES::CodestreamParser::FillPictureDescriptor(PictureDescriptor &PDesc) const
176 {
177
178   if(m_Parser.empty()) return RESULT_INIT;
179   PDesc = m_Parser->m_PDesc;
180   return RESULT_OK;
181 }