1 /*****************************************************************
2 |
3 | AP4 - hdlr Atoms
4 |
5 | Copyright 2002-2008 Axiomatic Systems, LLC
6 |
7 |
8 | This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9 |
10 | Unless you have obtained Bento4 under a difference license,
11 | this version of Bento4 is Bento4|GPL.
12 | Bento4|GPL is free software; you can redistribute it and/or modify
13 | it under the terms of the GNU General Public License as published by
14 | the Free Software Foundation; either version 2, or (at your option)
15 | any later version.
16 |
17 | Bento4|GPL is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | GNU General Public License for more details.
21 |
22 | You should have received a copy of the GNU General Public License
23 | along with Bento4|GPL; see the file COPYING. If not, write to the
24 | Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 | 02111-1307, USA.
26 |
27 ****************************************************************/
28
29 /*----------------------------------------------------------------------
30 | includes
31 +---------------------------------------------------------------------*/
32 #include "Ap4HdlrAtom.h"
33 #include "Ap4AtomFactory.h"
34 #include "Ap4Utils.h"
35
36 /*----------------------------------------------------------------------
37 | dynamic cast support
38 +---------------------------------------------------------------------*/
AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_HdlrAtom)39 AP4_DEFINE_DYNAMIC_CAST_ANCHOR(AP4_HdlrAtom)
40
41 /*----------------------------------------------------------------------
42 | AP4_HdlrAtom::Create
43 +---------------------------------------------------------------------*/
44 AP4_HdlrAtom*
45 AP4_HdlrAtom::Create(AP4_Size size, AP4_ByteStream& stream)
46 {
47 AP4_UI08 version;
48 AP4_UI32 flags;
49 if (AP4_FAILED(AP4_Atom::ReadFullHeader(stream, version, flags))) return NULL;
50 if (version != 0) return NULL;
51 return new AP4_HdlrAtom(size, version, flags, stream);
52 }
53
54 /*----------------------------------------------------------------------
55 | AP4_HdlrAtom::AP4_HdlrAtom
56 +---------------------------------------------------------------------*/
AP4_HdlrAtom(AP4_Atom::Type hdlr_type,const char * hdlr_name)57 AP4_HdlrAtom::AP4_HdlrAtom(AP4_Atom::Type hdlr_type, const char* hdlr_name) :
58 AP4_Atom(AP4_ATOM_TYPE_HDLR, AP4_FULL_ATOM_HEADER_SIZE, 0, 0),
59 m_HandlerType(hdlr_type),
60 m_HandlerName(hdlr_name)
61 {
62 m_Size32 += 20+m_HandlerName.GetLength()+1;
63 m_Reserved[0] = m_Reserved[1] = m_Reserved[2] = 0;
64 }
65
66 /*----------------------------------------------------------------------
67 | AP4_HdlrAtom::AP4_HdlrAtom
68 +---------------------------------------------------------------------*/
AP4_HdlrAtom(AP4_UI32 size,AP4_UI08 version,AP4_UI32 flags,AP4_ByteStream & stream)69 AP4_HdlrAtom::AP4_HdlrAtom(AP4_UI32 size,
70 AP4_UI08 version,
71 AP4_UI32 flags,
72 AP4_ByteStream& stream) :
73 AP4_Atom(AP4_ATOM_TYPE_HDLR, size, version, flags)
74 {
75 AP4_UI32 predefined;
76 stream.ReadUI32(predefined);
77 stream.ReadUI32(m_HandlerType);
78 stream.ReadUI32(m_Reserved[0]);
79 stream.ReadUI32(m_Reserved[1]);
80 stream.ReadUI32(m_Reserved[2]);
81
82 // read the name unless it is empty
83 int name_size = size-(AP4_FULL_ATOM_HEADER_SIZE+20);
84 if (name_size == 0) return;
85 char* name = new char[name_size+1];
86 stream.Read(name, name_size);
87 name[name_size] = '\0'; // force a null termination
88 // handle a special case: the Quicktime files have a pascal
89 // string here, but ISO MP4 files have a C string.
90 // we try to detect a pascal encoding and correct it.
91 if (name[0] == name_size-1) {
92 m_HandlerName = name+1;
93 } else {
94 m_HandlerName = name;
95 }
96 delete[] name;
97 }
98
99 /*----------------------------------------------------------------------
100 | AP4_HdlrAtom::WriteFields
101 +---------------------------------------------------------------------*/
102 AP4_Result
WriteFields(AP4_ByteStream & stream)103 AP4_HdlrAtom::WriteFields(AP4_ByteStream& stream)
104 {
105 AP4_Result result;
106
107 // write the data
108 result = stream.WriteUI32(0); // predefined
109 if (AP4_FAILED(result)) return result;
110 result = stream.WriteUI32(m_HandlerType);
111 if (AP4_FAILED(result)) return result;
112 result = stream.WriteUI32(m_Reserved[0]);
113 if (AP4_FAILED(result)) return result;
114 result = stream.WriteUI32(m_Reserved[1]);
115 if (AP4_FAILED(result)) return result;
116 result = stream.WriteUI32(m_Reserved[2]);
117 if (AP4_FAILED(result)) return result;
118 AP4_UI08 name_size = (AP4_UI08)m_HandlerName.GetLength();
119 if (AP4_FULL_ATOM_HEADER_SIZE+20+name_size > m_Size32) {
120 name_size = (AP4_UI08)(m_Size32-AP4_FULL_ATOM_HEADER_SIZE+20);
121 }
122 if (name_size) {
123 result = stream.Write(m_HandlerName.GetChars(), name_size);
124 if (AP4_FAILED(result)) return result;
125 }
126
127 // pad with zeros if necessary
128 AP4_Size padding = m_Size32-(AP4_FULL_ATOM_HEADER_SIZE+20+name_size);
129 while (padding--) stream.WriteUI08(0);
130
131 return AP4_SUCCESS;
132 }
133
134 /*----------------------------------------------------------------------
135 | AP4_HdlrAtom::InspectFields
136 +---------------------------------------------------------------------*/
137 AP4_Result
InspectFields(AP4_AtomInspector & inspector)138 AP4_HdlrAtom::InspectFields(AP4_AtomInspector& inspector)
139 {
140 char type[5];
141 AP4_FormatFourChars(type, m_HandlerType);
142 inspector.AddField("handler_type", type);
143 inspector.AddField("handler_name", m_HandlerName.GetChars());
144
145 return AP4_SUCCESS;
146 }
147