1 /*
2  * The contents of this file are subject to the Mozilla Public
3  * License Version 1.1 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of
5  * the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS
8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9  * implied. See the License for the specific language governing
10  * rights and limitations under the License.
11  *
12  * The Original Code is MPEG4IP.
13  *
14  * The Initial Developer of the Original Code is Cisco Systems Inc.
15  * Portions created by Cisco Systems Inc. are
16  * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
17  *
18  * Contributor(s):
19  *      Dave Mackie     dmackie@cisco.com
20  */
21 
22 #include "src/impl.h"
23 
24 namespace mp4v2 {
25 namespace impl {
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 
MP4ContentClassDescriptor(MP4Atom & parentAtom)29 MP4ContentClassDescriptor::MP4ContentClassDescriptor(MP4Atom& parentAtom)
30         : MP4Descriptor(parentAtom)
31 {
32     AddProperty( /* 0 */
33         new MP4Integer32Property(parentAtom, "classificationEntity"));
34     AddProperty( /* 1 */
35         new MP4Integer16Property(parentAtom, "classificationTable"));
36     AddProperty( /* 2 */
37         new MP4BytesProperty(parentAtom, "contentClassificationData"));
38 }
39 
Read(MP4File & file)40 void MP4ContentClassDescriptor::Read(MP4File& file)
41 {
42     ReadHeader(file);
43 
44     /* byte properties need to know how long they are before reading */
45     ((MP4BytesProperty*)m_pProperties[2])->SetValueSize(m_size - 6);
46 
47     ReadProperties(file);
48 }
49 
MP4KeywordDescriptor(MP4Atom & parentAtom)50 MP4KeywordDescriptor::MP4KeywordDescriptor(MP4Atom& parentAtom)
51         : MP4Descriptor(parentAtom)
52 {
53     AddProperty( /* 0 */
54         new MP4BytesProperty(parentAtom, "languageCode", 3));
55     AddProperty( /* 1 */
56         new MP4BitfieldProperty(parentAtom, "isUTF8String", 1));
57     AddProperty( /* 2 */
58         new MP4BitfieldProperty(parentAtom, "reserved", 7));
59     MP4Integer8Property* pCount =
60         new MP4Integer8Property(parentAtom, "keywordCount");
61     AddProperty(pCount); /* 3 */
62 
63     MP4TableProperty* pTable = new MP4TableProperty(parentAtom, "keywords", pCount);
64     AddProperty(pTable); /* 4 */
65 
66     pTable->AddProperty( /* 4, 0 */
67         new MP4StringProperty(pTable->GetParentAtom(), "string", Counted));
68 
69     SetReadMutate(2);
70 }
71 
Mutate()72 void MP4KeywordDescriptor::Mutate()
73 {
74     bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue();
75     MP4Property* pProperty =
76         ((MP4TableProperty*)m_pProperties[4])->GetProperty(0);
77     ASSERT(pProperty);
78     ((MP4StringProperty*)pProperty)->SetUnicode(!utf8Flag);
79 }
80 
MP4RatingDescriptor(MP4Atom & parentAtom)81 MP4RatingDescriptor::MP4RatingDescriptor(MP4Atom& parentAtom)
82         : MP4Descriptor(parentAtom)
83 {
84     AddProperty( /* 0 */
85         new MP4Integer32Property(parentAtom, "ratingEntity"));
86     AddProperty( /* 1 */
87         new MP4Integer16Property(parentAtom, "ratingCriteria"));
88     AddProperty( /* 2 */
89         new MP4BytesProperty(parentAtom, "ratingInfo"));
90 }
91 
Read(MP4File & file)92 void MP4RatingDescriptor::Read(MP4File& file)
93 {
94     ReadHeader(file);
95 
96     /* byte properties need to know how long they are before reading */
97     ((MP4BytesProperty*)m_pProperties[2])->SetValueSize(m_size - 6);
98 
99     ReadProperties(file);
100 }
101 
MP4LanguageDescriptor(MP4Atom & parentAtom)102 MP4LanguageDescriptor::MP4LanguageDescriptor(MP4Atom& parentAtom)
103         : MP4Descriptor(parentAtom)
104 {
105     AddProperty( /* 0 */
106         new MP4BytesProperty(parentAtom, "languageCode", 3));
107 }
108 
MP4ShortTextDescriptor(MP4Atom & parentAtom)109 MP4ShortTextDescriptor::MP4ShortTextDescriptor(MP4Atom& parentAtom)
110         : MP4Descriptor(parentAtom)
111 {
112     AddProperty( /* 0 */
113         new MP4BytesProperty(parentAtom, "languageCode", 3));
114     AddProperty( /* 1 */
115         new MP4BitfieldProperty(parentAtom, "isUTF8String", 1));
116     AddProperty( /* 2 */
117         new MP4BitfieldProperty(parentAtom, "reserved", 7));
118     AddProperty( /* 3 */
119         new MP4StringProperty(parentAtom, "eventName", Counted));
120     AddProperty( /* 4 */
121         new MP4StringProperty(parentAtom, "eventText", Counted));
122 
123     SetReadMutate(2);
124 }
125 
Mutate()126 void MP4ShortTextDescriptor::Mutate()
127 {
128     bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue();
129     ((MP4StringProperty*)m_pProperties[3])->SetUnicode(!utf8Flag);
130     ((MP4StringProperty*)m_pProperties[4])->SetUnicode(!utf8Flag);
131 }
132 
MP4ExpandedTextDescriptor(MP4Atom & parentAtom)133 MP4ExpandedTextDescriptor::MP4ExpandedTextDescriptor(MP4Atom& parentAtom)
134         : MP4Descriptor(parentAtom)
135 {
136     AddProperty( /* 0 */
137         new MP4BytesProperty(parentAtom, "languageCode", 3));
138     AddProperty( /* 1 */
139         new MP4BitfieldProperty(parentAtom, "isUTF8String", 1));
140     AddProperty( /* 2 */
141         new MP4BitfieldProperty(parentAtom, "reserved", 7));
142     MP4Integer8Property* pCount =
143         new MP4Integer8Property(parentAtom, "itemCount");
144     AddProperty(pCount); /* 3 */
145 
146     MP4TableProperty* pTable = new MP4TableProperty(parentAtom, "items", pCount);
147     AddProperty(pTable); /* 4 */
148 
149     pTable->AddProperty( /* Table 0 */
150         new MP4StringProperty(pTable->GetParentAtom(), "itemDescription", Counted));
151     pTable->AddProperty( /* Table 1 */
152         new MP4StringProperty(pTable->GetParentAtom(), "itemText", Counted));
153 
154     AddProperty( /* 5 */
155         new MP4StringProperty(parentAtom, "nonItemText"));
156     ((MP4StringProperty*)m_pProperties[5])->SetExpandedCountedFormat(true);
157 
158     SetReadMutate(2);
159 }
160 
Mutate()161 void MP4ExpandedTextDescriptor::Mutate()
162 {
163     bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue();
164 
165     MP4Property* pProperty =
166         ((MP4TableProperty*)m_pProperties[4])->GetProperty(0);
167     ASSERT(pProperty);
168     ((MP4StringProperty*)pProperty)->SetUnicode(!utf8Flag);
169 
170     pProperty = ((MP4TableProperty*)m_pProperties[4])->GetProperty(1);
171     ASSERT(pProperty);
172     ((MP4StringProperty*)pProperty)->SetUnicode(!utf8Flag);
173 
174     ((MP4StringProperty*)m_pProperties[5])->SetUnicode(!utf8Flag);
175 }
176 
177 class MP4CreatorTableProperty : public MP4TableProperty {
178 public:
MP4CreatorTableProperty(MP4Atom & parentAtom,const char * name,MP4Integer8Property * pCountProperty)179     MP4CreatorTableProperty(MP4Atom& parentAtom, const char* name, MP4Integer8Property* pCountProperty) :
180             MP4TableProperty(parentAtom, name, pCountProperty) {
181     };
182 protected:
183     void ReadEntry(MP4File& file, uint32_t index);
184     void WriteEntry(MP4File& file, uint32_t index);
185 private:
186     MP4CreatorTableProperty();
187     MP4CreatorTableProperty ( const MP4CreatorTableProperty &src );
188     MP4CreatorTableProperty &operator= ( const MP4CreatorTableProperty &src );
189 };
190 
MP4CreatorDescriptor(MP4Atom & parentAtom,uint8_t tag)191 MP4CreatorDescriptor::MP4CreatorDescriptor(MP4Atom& parentAtom, uint8_t tag)
192         : MP4Descriptor(parentAtom, tag)
193 {
194     MP4Integer8Property* pCount =
195         new MP4Integer8Property(parentAtom, "creatorCount");
196     AddProperty(pCount); /* 0 */
197 
198     MP4TableProperty* pTable = new MP4CreatorTableProperty(parentAtom, "creators", pCount);
199     AddProperty(pTable); /* 1 */
200 
201     pTable->AddProperty( /* Table 0 */
202         new MP4BytesProperty(pTable->GetParentAtom(), "languageCode", 3, 3));
203     pTable->AddProperty( /* Table 1 */
204         new MP4BitfieldProperty(pTable->GetParentAtom(), "isUTF8String", 1));
205     pTable->AddProperty( /* Table 2 */
206         new MP4BitfieldProperty(pTable->GetParentAtom(), "reserved", 7));
207     pTable->AddProperty( /* Table 3 */
208         new MP4StringProperty(pTable->GetParentAtom(), "name", Counted));
209 }
210 
ReadEntry(MP4File & file,uint32_t index)211 void MP4CreatorTableProperty::ReadEntry(MP4File& file, uint32_t index)
212 {
213     m_pProperties[0]->Read(file, index);
214     m_pProperties[1]->Read(file, index);
215 
216     bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue(index);
217     ((MP4StringProperty*)m_pProperties[3])->SetUnicode(!utf8Flag);
218 
219     m_pProperties[2]->Read(file, index);
220     m_pProperties[3]->Read(file, index);
221 }
222 
WriteEntry(MP4File & file,uint32_t index)223 void MP4CreatorTableProperty::WriteEntry(MP4File& file, uint32_t index)
224 {
225     bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue(index);
226     ((MP4StringProperty*)m_pProperties[3])->SetUnicode(!utf8Flag);
227 
228     MP4TableProperty::WriteEntry(file, index);
229 }
230 
MP4CreationDescriptor(MP4Atom & parentAtom,uint8_t tag)231 MP4CreationDescriptor::MP4CreationDescriptor(MP4Atom& parentAtom, uint8_t tag)
232         : MP4Descriptor(parentAtom, tag)
233 {
234     AddProperty( /* 0 */
235         new MP4BitfieldProperty(parentAtom, "contentCreationDate", 40));
236 }
237 
MP4SmpteCameraDescriptor(MP4Atom & parentAtom)238 MP4SmpteCameraDescriptor::MP4SmpteCameraDescriptor(MP4Atom& parentAtom)
239         : MP4Descriptor(parentAtom)
240 {
241     MP4Integer8Property* pCount =
242         new MP4Integer8Property(parentAtom, "parameterCount");
243     AddProperty(pCount);
244 
245     MP4TableProperty* pTable = new MP4TableProperty(parentAtom, "parameters", pCount);
246     AddProperty(pTable);
247 
248     pTable->AddProperty(
249         new MP4Integer8Property(parentAtom, "id"));
250     pTable->AddProperty(
251         new MP4Integer32Property(parentAtom, "value"));
252 }
253 
MP4UnknownOCIDescriptor(MP4Atom & parentAtom)254 MP4UnknownOCIDescriptor::MP4UnknownOCIDescriptor(MP4Atom& parentAtom)
255         : MP4Descriptor(parentAtom)
256 {
257     AddProperty( /* 0 */
258         new MP4BytesProperty(parentAtom, "data"));
259 }
260 
Read(MP4File & file)261 void MP4UnknownOCIDescriptor::Read(MP4File& file)
262 {
263     ReadHeader(file);
264 
265     /* byte properties need to know how long they are before reading */
266     ((MP4BytesProperty*)m_pProperties[0])->SetValueSize(m_size);
267 
268     ReadProperties(file);
269 }
270 
CreateOCIDescriptor(MP4Atom & parentAtom,uint8_t tag)271 MP4Descriptor* CreateOCIDescriptor(MP4Atom& parentAtom, uint8_t tag)
272 {
273     MP4Descriptor* pDescriptor = NULL;
274 
275     switch (tag) {
276     case MP4ContentClassDescrTag:
277         pDescriptor = new MP4ContentClassDescriptor(parentAtom);
278         break;
279     case MP4KeywordDescrTag:
280         pDescriptor = new MP4KeywordDescriptor(parentAtom);
281         break;
282     case MP4RatingDescrTag:
283         pDescriptor = new MP4RatingDescriptor(parentAtom);
284         break;
285     case MP4LanguageDescrTag:
286         pDescriptor = new MP4LanguageDescriptor(parentAtom);
287         break;
288     case MP4ShortTextDescrTag:
289         pDescriptor = new MP4ShortTextDescriptor(parentAtom);
290         break;
291     case MP4ExpandedTextDescrTag:
292         pDescriptor = new MP4ExpandedTextDescriptor(parentAtom);
293         break;
294     case MP4ContentCreatorDescrTag:
295     case MP4OCICreatorDescrTag:
296         pDescriptor = new MP4CreatorDescriptor(parentAtom, tag);
297         break;
298     case MP4ContentCreationDescrTag:
299     case MP4OCICreationDescrTag:
300         pDescriptor = new MP4CreationDescriptor(parentAtom, tag);
301         break;
302     case MP4SmpteCameraDescrTag:
303         pDescriptor = new MP4SmpteCameraDescriptor(parentAtom);
304         break;
305     }
306 
307     if (pDescriptor == NULL) {
308         if (tag >= MP4OCIDescrTagsStart && tag <= MP4OCIDescrTagsEnd) {
309             pDescriptor = new MP4UnknownOCIDescriptor(parentAtom);
310             pDescriptor->SetTag(tag);
311         }
312     }
313 
314     return pDescriptor;
315 }
316 
317 ///////////////////////////////////////////////////////////////////////////////
318 
319 }
320 } // namespace mp4v2::impl
321