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 - 2004.  All Rights Reserved.
17  *
18  * 3GPP features implementation is based on 3GPP's TS26.234-v5.60,
19  * and was contributed by Ximpo Group Ltd.
20  *
21  * Portions created by Ximpo Group Ltd. are
22  * Copyright (C) Ximpo Group Ltd. 2003, 2004.  All Rights Reserved.
23  *
24  * Contributor(s):
25  *		Dave Mackie		dmackie@cisco.com
26  *              Ximpo Group Ltd.        mp4v2@ximpo.com
27  */
28 
29 #ifndef __MP4_ATOM_INCLUDED__
30 #define __MP4_ATOM_INCLUDED__
31 
32 class MP4Atom;
33 MP4ARRAY_DECL(MP4Atom, MP4Atom*);
34 
35 #define Required	true
36 #define Optional	false
37 #define OnlyOne		true
38 #define Many		false
39 #define Counted		true
40 
41 /* helper class */
42 class MP4AtomInfo {
43 public:
MP4AtomInfo()44 	MP4AtomInfo() {
45 		m_name = NULL;
46 	}
47 	MP4AtomInfo(const char* name, bool mandatory, bool onlyOne);
48 
49 	const char* m_name;
50 	bool m_mandatory;
51 	bool m_onlyOne;
52 	u_int32_t m_count;
53 };
54 
55 MP4ARRAY_DECL(MP4AtomInfo, MP4AtomInfo*);
56 
57 class MP4Atom {
58 public:
59 	MP4Atom(const char* type = NULL);
60 	virtual ~MP4Atom();
61 
62 	static MP4Atom* ReadAtom(MP4File* pFile, MP4Atom* pParentAtom);
63 	static MP4Atom* CreateAtom(const char* type);
64 	static bool IsReasonableType(const char* type);
65 
GetFile()66 	MP4File* GetFile() {
67 		return m_pFile;
68 	};
SetFile(MP4File * pFile)69 	void SetFile(MP4File* pFile) {
70 		m_pFile = pFile;
71 	};
72 
GetStart()73 	u_int64_t GetStart() {
74 		return m_start;
75 	};
SetStart(u_int64_t pos)76 	void SetStart(u_int64_t pos) {
77 		m_start = pos;
78 	};
79 
GetEnd()80 	u_int64_t GetEnd() {
81 		return m_end;
82 	};
SetEnd(u_int64_t pos)83 	void SetEnd(u_int64_t pos) {
84 		m_end = pos;
85 	};
86 
GetSize()87 	u_int64_t GetSize() {
88 		return m_size;
89 	}
SetSize(u_int64_t size)90 	void SetSize(u_int64_t size) {
91 		m_size = size;
92 	}
93 
GetType()94 	const char* GetType() {
95 		return m_type;
96 	};
SetType(const char * type)97 	void SetType(const char* type) {
98 		if (type && *type != '\0') {
99 		  // not needed ASSERT(strlen(type) == 4);
100 			memcpy(m_type, type, 4);
101 			m_type[4] = '\0';
102 		} else {
103 			memset(m_type, 0, 5);
104 		}
105 	}
106 
GetExtendedType(u_int8_t * pExtendedType)107 	void GetExtendedType(u_int8_t* pExtendedType) {
108 		memcpy(pExtendedType, m_extendedType, sizeof(m_extendedType));
109 	};
SetExtendedType(u_int8_t * pExtendedType)110 	void SetExtendedType(u_int8_t* pExtendedType) {
111 		memcpy(m_extendedType, pExtendedType, sizeof(m_extendedType));
112 	};
113 
IsUnknownType()114 	bool IsUnknownType() {
115 		return m_unknownType;
116 	}
117 	void SetUnknownType(bool unknownType = true) {
118 		m_unknownType = unknownType;
119 	}
120 
IsRootAtom()121 	bool IsRootAtom() {
122 		return m_type[0] == '\0';
123 	}
124 
GetParentAtom()125 	MP4Atom* GetParentAtom() {
126 		return m_pParentAtom;
127 	}
SetParentAtom(MP4Atom * pParentAtom)128 	void SetParentAtom(MP4Atom* pParentAtom) {
129 		m_pParentAtom = pParentAtom;
130 	}
131 
AddChildAtom(MP4Atom * pChildAtom)132 	void AddChildAtom(MP4Atom* pChildAtom) {
133 		pChildAtom->SetFile(m_pFile);
134 		pChildAtom->SetParentAtom(this);
135 		m_pChildAtoms.Add(pChildAtom);
136 	}
137 
InsertChildAtom(MP4Atom * pChildAtom,u_int32_t index)138 	void InsertChildAtom(MP4Atom* pChildAtom, u_int32_t index) {
139 		pChildAtom->SetFile(m_pFile);
140 		pChildAtom->SetParentAtom(this);
141 		m_pChildAtoms.Insert(pChildAtom, index);
142 	}
143 
DeleteChildAtom(MP4Atom * pChildAtom)144 	void DeleteChildAtom(MP4Atom* pChildAtom) {
145 		for (MP4ArrayIndex i = 0; i < m_pChildAtoms.Size(); i++) {
146 			if (m_pChildAtoms[i] == pChildAtom) {
147 				m_pChildAtoms.Delete(i);
148 				return;
149 			}
150 		}
151 	}
152 
GetNumberOfChildAtoms()153 	u_int32_t GetNumberOfChildAtoms() {
154 		return m_pChildAtoms.Size();
155 	}
156 
GetChildAtom(u_int32_t index)157 	MP4Atom* GetChildAtom(u_int32_t index) {
158 		return m_pChildAtoms[index];
159 	}
160 
GetProperty(u_int32_t index)161 	MP4Property* GetProperty(u_int32_t index) {
162 		return m_pProperties[index];
163 	}
164 
GetCount()165 	u_int32_t GetCount() {
166 		return m_pProperties.Size();
167 	}
168 
169 #if 0
170 	void SetProperty(u_int32_t index, MP4Property *property) {
171 		u_int64_t t;
172 		if (index > m_pProperties.Size())
173 			return;
174 
175 		t = property->Get(index);
176 		m_pProperties[index]->Set(t, index);
177 	}
178 #endif
179 
180 	MP4Atom* FindAtom(const char* name);
181 
182 	MP4Atom* FindChildAtom(const char* name);
183 
184 	bool FindProperty(const char* name,
185 		MP4Property** ppProperty, u_int32_t* pIndex = NULL);
186 
187 	u_int32_t GetFlags();
188 	void SetFlags(u_int32_t flags);
189 
190 	u_int8_t GetDepth();
191 
192 	void Skip();
193 
194 	virtual void Generate();
195 	virtual void Read();
196 	virtual void BeginWrite(bool use64 = false);
197 	virtual void Write();
198 	virtual void Rewrite();
199 	virtual void FinishWrite(bool use64 = false);
200 	virtual void Dump(FILE* pFile, u_int8_t indent, bool dumpImplicits);
201 
202 protected:
203 	void AddProperty(MP4Property* pProperty);
204 
205 	void AddVersionAndFlags();
206 
207 	void AddReserved(char* name, u_int32_t size);
208 
209 	void ExpectChildAtom(const char* name,
210 		bool mandatory, bool onlyOne = true);
211 
212 	MP4AtomInfo* FindAtomInfo(const char* name);
213 
214 	bool IsMe(const char* name);
215 
216 	bool FindContainedProperty(const char* name,
217 		MP4Property** ppProperty, u_int32_t* pIndex);
218 
219 	void ReadProperties(
220 		u_int32_t startIndex = 0, u_int32_t count = 0xFFFFFFFF);
221 	void ReadChildAtoms();
222 
223 	void WriteProperties(
224 		u_int32_t startIndex = 0, u_int32_t count = 0xFFFFFFFF);
225 	void WriteChildAtoms();
226 
227 	u_int8_t GetVersion();
228 	void SetVersion(u_int8_t version);
229 
230 	/* debugging aid */
231 	u_int32_t GetVerbosity();
232 
233 protected:
234 	MP4File*	m_pFile;
235 	u_int64_t	m_start;
236 	u_int64_t	m_end;
237 	u_int64_t	m_size;
238 	char		m_type[5];
239 	bool		m_unknownType;
240 	u_int8_t	m_extendedType[16];
241 
242 	MP4Atom*	m_pParentAtom;
243 	u_int8_t	m_depth;
244 
245 	MP4PropertyArray	m_pProperties;
246 	MP4AtomInfoArray 	m_pChildAtomInfos;
247 	MP4AtomArray		m_pChildAtoms;
248 };
249 
ATOMID(const char * type)250 inline u_int32_t ATOMID(const char* type) {
251 	return STRTOINT32(type);
252 }
253 
254 // inverse ATOMID - 32 bit id to string
IDATOM(u_int32_t type,char * s)255 inline void IDATOM(u_int32_t type, char *s) {
256 	INT32TOSTR(type, s);
257 }
258 
259 #endif /* __MP4_ATOM_INCLUDED__ */
260