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 "mp4common.h"
23 
MP4ContentClassDescriptor()24 MP4ContentClassDescriptor::MP4ContentClassDescriptor()
25 	: MP4Descriptor()
26 {
27 	AddProperty( /* 0 */
28 		new MP4Integer32Property("classificationEntity"));
29 	AddProperty( /* 1 */
30 		new MP4Integer16Property("classificationTable"));
31 	AddProperty( /* 2 */
32 		new MP4BytesProperty("contentClassificationData"));
33 }
34 
Read(MP4File * pFile)35 void MP4ContentClassDescriptor::Read(MP4File* pFile)
36 {
37 	ReadHeader(pFile);
38 
39 	/* byte properties need to know how long they are before reading */
40 	((MP4BytesProperty*)m_pProperties[2])->SetValueSize(m_size - 6);
41 
42 	ReadProperties(pFile);
43 }
44 
MP4KeywordDescriptor()45 MP4KeywordDescriptor::MP4KeywordDescriptor()
46 	: MP4Descriptor()
47 {
48 	AddProperty( /* 0 */
49 		new MP4BytesProperty("languageCode", 3));
50 	AddProperty( /* 1 */
51 		new MP4BitfieldProperty("isUTF8String", 1));
52 	AddProperty( /* 2 */
53 		new MP4BitfieldProperty("reserved", 7));
54 	MP4Integer8Property* pCount =
55 		new MP4Integer8Property("keywordCount");
56 	AddProperty(pCount); /* 3 */
57 
58 	MP4TableProperty* pTable = new MP4TableProperty("keywords", pCount);
59 	AddProperty(pTable); /* 4 */
60 
61 	pTable->AddProperty( /* 4, 0 */
62 		new MP4StringProperty("string", Counted));
63 
64 	SetReadMutate(2);
65 }
66 
Mutate()67 void MP4KeywordDescriptor::Mutate()
68 {
69 	bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue();
70 	MP4Property* pProperty =
71 		((MP4TableProperty*)m_pProperties[4])->GetProperty(0);
72 	ASSERT(pProperty);
73 	((MP4StringProperty*)pProperty)->SetUnicode(!utf8Flag);
74 }
75 
MP4RatingDescriptor()76 MP4RatingDescriptor::MP4RatingDescriptor()
77 	: MP4Descriptor()
78 {
79 	AddProperty( /* 0 */
80 		new MP4Integer32Property("ratingEntity"));
81 	AddProperty( /* 1 */
82 		new MP4Integer16Property("ratingCriteria"));
83 	AddProperty( /* 2 */
84 		new MP4BytesProperty("ratingInfo"));
85 }
86 
Read(MP4File * pFile)87 void MP4RatingDescriptor::Read(MP4File* pFile)
88 {
89 	ReadHeader(pFile);
90 
91 	/* byte properties need to know how long they are before reading */
92 	((MP4BytesProperty*)m_pProperties[2])->SetValueSize(m_size - 6);
93 
94 	ReadProperties(pFile);
95 }
96 
MP4LanguageDescriptor()97 MP4LanguageDescriptor::MP4LanguageDescriptor()
98 	: MP4Descriptor()
99 {
100 	AddProperty( /* 0 */
101 		new MP4BytesProperty("languageCode", 3));
102 }
103 
MP4ShortTextDescriptor()104 MP4ShortTextDescriptor::MP4ShortTextDescriptor()
105 	: MP4Descriptor()
106 {
107 	AddProperty( /* 0 */
108 		new MP4BytesProperty("languageCode", 3));
109 	AddProperty( /* 1 */
110 		new MP4BitfieldProperty("isUTF8String", 1));
111 	AddProperty( /* 2 */
112 		new MP4BitfieldProperty("reserved", 7));
113 	AddProperty( /* 3 */
114 		new MP4StringProperty("eventName", Counted));
115 	AddProperty( /* 4 */
116 		new MP4StringProperty("eventText", Counted));
117 
118 	SetReadMutate(2);
119 }
120 
Mutate()121 void MP4ShortTextDescriptor::Mutate()
122 {
123 	bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue();
124 	((MP4StringProperty*)m_pProperties[3])->SetUnicode(!utf8Flag);
125 	((MP4StringProperty*)m_pProperties[4])->SetUnicode(!utf8Flag);
126 }
127 
MP4ExpandedTextDescriptor()128 MP4ExpandedTextDescriptor::MP4ExpandedTextDescriptor()
129 	: MP4Descriptor()
130 {
131 	AddProperty( /* 0 */
132 		new MP4BytesProperty("languageCode", 3));
133 	AddProperty( /* 1 */
134 		new MP4BitfieldProperty("isUTF8String", 1));
135 	AddProperty( /* 2 */
136 		new MP4BitfieldProperty("reserved", 7));
137 	MP4Integer8Property* pCount =
138 		new MP4Integer8Property("itemCount");
139 	AddProperty(pCount); /* 3 */
140 
141 	MP4TableProperty* pTable = new MP4TableProperty("items", pCount);
142 	AddProperty(pTable); /* 4 */
143 
144 	pTable->AddProperty( /* Table 0 */
145 		new MP4StringProperty("itemDescription", Counted));
146 	pTable->AddProperty( /* Table 1 */
147 		new MP4StringProperty("itemText", Counted));
148 
149 	AddProperty( /* 5 */
150 		new MP4StringProperty("nonItemText"));
151 	((MP4StringProperty*)m_pProperties[5])->SetExpandedCountedFormat(true);
152 
153 	SetReadMutate(2);
154 }
155 
Mutate()156 void MP4ExpandedTextDescriptor::Mutate()
157 {
158 	bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue();
159 
160 	MP4Property* pProperty =
161 		((MP4TableProperty*)m_pProperties[4])->GetProperty(0);
162 	ASSERT(pProperty);
163 	((MP4StringProperty*)pProperty)->SetUnicode(!utf8Flag);
164 
165 	pProperty = ((MP4TableProperty*)m_pProperties[4])->GetProperty(1);
166 	ASSERT(pProperty);
167 	((MP4StringProperty*)pProperty)->SetUnicode(!utf8Flag);
168 
169 	((MP4StringProperty*)m_pProperties[5])->SetUnicode(!utf8Flag);
170 }
171 
172 class MP4CreatorTableProperty : public MP4TableProperty {
173 public:
MP4CreatorTableProperty(char * name,MP4Integer8Property * pCountProperty)174 	MP4CreatorTableProperty(char* name, MP4Integer8Property* pCountProperty) :
175 		MP4TableProperty(name, pCountProperty) {
176 	};
177 protected:
178 	void ReadEntry(MP4File* pFile, u_int32_t index);
179 	void WriteEntry(MP4File* pFile, u_int32_t index);
180 };
181 
MP4CreatorDescriptor(u_int8_t tag)182 MP4CreatorDescriptor::MP4CreatorDescriptor(u_int8_t tag)
183 	: MP4Descriptor(tag)
184 {
185 	MP4Integer8Property* pCount =
186 		new MP4Integer8Property("creatorCount");
187 	AddProperty(pCount); /* 0 */
188 
189 	MP4TableProperty* pTable = new MP4CreatorTableProperty("creators", pCount);
190 	AddProperty(pTable); /* 1 */
191 
192 	pTable->AddProperty( /* Table 0 */
193 		new MP4BytesProperty("languageCode", 3, 3));
194 	pTable->AddProperty( /* Table 1 */
195 		new MP4BitfieldProperty("isUTF8String", 1));
196 	pTable->AddProperty( /* Table 2 */
197 		new MP4BitfieldProperty("reserved", 7));
198 	pTable->AddProperty( /* Table 3 */
199 		new MP4StringProperty("name", Counted));
200 }
201 
ReadEntry(MP4File * pFile,u_int32_t index)202 void MP4CreatorTableProperty::ReadEntry(MP4File* pFile, u_int32_t index)
203 {
204 	m_pProperties[0]->Read(pFile, index);
205 	m_pProperties[1]->Read(pFile, index);
206 
207 	bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue(index);
208 	((MP4StringProperty*)m_pProperties[3])->SetUnicode(!utf8Flag);
209 
210 	m_pProperties[2]->Read(pFile, index);
211 	m_pProperties[3]->Read(pFile, index);
212 }
213 
WriteEntry(MP4File * pFile,u_int32_t index)214 void MP4CreatorTableProperty::WriteEntry(MP4File* pFile, u_int32_t index)
215 {
216 	bool utf8Flag = ((MP4BitfieldProperty*)m_pProperties[1])->GetValue(index);
217 	((MP4StringProperty*)m_pProperties[3])->SetUnicode(!utf8Flag);
218 
219 	MP4TableProperty::WriteEntry(pFile, index);
220 }
221 
MP4CreationDescriptor(u_int8_t tag)222 MP4CreationDescriptor::MP4CreationDescriptor(u_int8_t tag)
223 	: MP4Descriptor(tag)
224 {
225 	AddProperty( /* 0 */
226 		new MP4BitfieldProperty("contentCreationDate", 40));
227 }
228 
MP4SmpteCameraDescriptor()229 MP4SmpteCameraDescriptor::MP4SmpteCameraDescriptor()
230 	: MP4Descriptor()
231 {
232 	MP4Integer8Property* pCount =
233 		new MP4Integer8Property("parameterCount");
234 	AddProperty(pCount);
235 
236 	MP4TableProperty* pTable = new MP4TableProperty("parameters", pCount);
237 	AddProperty(pTable);
238 
239 	pTable->AddProperty(
240 		new MP4Integer8Property("id"));
241 	pTable->AddProperty(
242 		new MP4Integer32Property("value"));
243 }
244 
MP4UnknownOCIDescriptor()245 MP4UnknownOCIDescriptor::MP4UnknownOCIDescriptor()
246 	: MP4Descriptor()
247 {
248 	AddProperty( /* 0 */
249 		new MP4BytesProperty("data"));
250 }
251 
Read(MP4File * pFile)252 void MP4UnknownOCIDescriptor::Read(MP4File* pFile)
253 {
254 	ReadHeader(pFile);
255 
256 	/* byte properties need to know how long they are before reading */
257 	((MP4BytesProperty*)m_pProperties[0])->SetValueSize(m_size);
258 
259 	ReadProperties(pFile);
260 }
261 
CreateOCIDescriptor(u_int8_t tag)262 MP4Descriptor* CreateOCIDescriptor(u_int8_t tag)
263 {
264 	MP4Descriptor* pDescriptor = NULL;
265 
266 	switch (tag) {
267 	case MP4ContentClassDescrTag:
268 		pDescriptor = new MP4ContentClassDescriptor();
269 		break;
270 	case MP4KeywordDescrTag:
271 		pDescriptor = new MP4KeywordDescriptor();
272 		break;
273 	case MP4RatingDescrTag:
274 		pDescriptor = new MP4RatingDescriptor();
275 		break;
276 	case MP4LanguageDescrTag:
277 		pDescriptor = new MP4LanguageDescriptor();
278 		break;
279 	case MP4ShortTextDescrTag:
280 		pDescriptor = new MP4ShortTextDescriptor();
281 		break;
282 	case MP4ExpandedTextDescrTag:
283 		pDescriptor = new MP4ExpandedTextDescriptor();
284 		break;
285 	case MP4ContentCreatorDescrTag:
286 	case MP4OCICreatorDescrTag:
287 		pDescriptor = new MP4CreatorDescriptor(tag);
288 		break;
289 	case MP4ContentCreationDescrTag:
290 	case MP4OCICreationDescrTag:
291 		pDescriptor = new MP4CreationDescriptor(tag);
292 		break;
293 	case MP4SmpteCameraDescrTag:
294 		pDescriptor = new MP4SmpteCameraDescriptor();
295 		break;
296 	}
297 
298 	if (pDescriptor == NULL) {
299 		if (tag >= MP4OCIDescrTagsStart && tag <= MP4OCIDescrTagsEnd) {
300 			pDescriptor = new MP4UnknownOCIDescriptor();
301 			pDescriptor->SetTag(tag);
302 		}
303 	}
304 
305 	return pDescriptor;
306 }
307 
308