3rdparty/licenseReport: Add seperate LGPL checks
[haiku.git] / src / add-ons / media / plugins / mp4_reader / libMP4 / MP4Atom.cpp
blobaf3d235dcfa9f09f184edbe16e69665a9b9c0870
1 /*
2 * Copyright (c) 2005, David McPaul
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23 * OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "MP4Atom.h"
29 #include <stdio.h>
32 AtomBase::AtomBase(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType,
33 uint64 patomSize)
35 theStream = pStream;
36 streamOffset = pstreamOffset;
37 atomType = patomType;
38 atomSize = patomSize;
39 parentAtom = NULL;
43 AtomBase::~AtomBase()
45 theStream = NULL;
46 parentAtom = NULL;
50 char *
51 AtomBase::GetAtomTypeAsFourcc()
53 fourcc[0] = (char)((atomType >> 24) & 0xff);
54 fourcc[1] = (char)((atomType >> 16) & 0xff);
55 fourcc[2] = (char)((atomType >> 8) & 0xff);
56 fourcc[3] = (char)((atomType >> 0) & 0xff);
57 fourcc[4] = '\0';
59 return fourcc;
63 const char *
64 AtomBase::GetAtomName()
66 const char *_result;
67 _result = OnGetAtomName();
68 if (_result) {
69 return _result;
72 fourcc[0] = (char)((atomType >> 24) & 0xff);
73 fourcc[1] = (char)((atomType >> 16) & 0xff);
74 fourcc[2] = (char)((atomType >> 8) & 0xff);
75 fourcc[3] = (char)((atomType >> 0) & 0xff);
76 fourcc[4] = '\0';
78 return fourcc;
82 const char *
83 AtomBase::OnGetAtomName()
85 return NULL;
89 void
90 AtomBase::ProcessMetaData()
91 // ProcessMetaData() - Reads in the basic Atom Meta Data
92 // - Calls OnProcessMetaData()
93 // - Calls ProcessMetaData on each child atom
94 // (ensures stream is correct for child via offset)
96 SetAtomOffset(GetStream()->Position());
98 OnProcessMetaData();
100 MoveToEnd();
104 void
105 AtomBase::OnProcessMetaData()
107 MoveToEnd();
111 bool
112 AtomBase::MoveToEnd()
114 off_t NewPosition = streamOffset + atomSize;
116 if (GetStream()->Position() != NewPosition) {
117 return (GetStream()->Seek(NewPosition,0) > 0);
119 return true;
123 uint64
124 AtomBase::GetBytesRemaining()
126 off_t EndPosition = streamOffset + atomSize;
127 off_t CurrPosition = GetStream()->Position();
129 if (CurrPosition > EndPosition) {
130 printf("ERROR: Read past atom boundary by %Ld bytes\n",
131 CurrPosition - EndPosition);
132 return 0;
135 return (EndPosition - CurrPosition);
139 void
140 AtomBase::DisplayAtoms()
142 uint32 aindent = 0;
143 DisplayAtoms(aindent);
147 void
148 AtomBase::DisplayAtoms(uint32 pindent)
150 Indent(pindent);
151 printf("(%s)\n",GetAtomName());
155 void
156 AtomBase::Indent(uint32 pindent)
158 for (uint32 i=0;i<pindent;i++) {
159 printf("-");
164 bool
165 AtomBase::IsKnown()
167 return (OnGetAtomName() != NULL);
171 void
172 AtomBase::ReadArrayHeader(array_header *pHeader)
174 Read(&pHeader->NoEntries);
178 BPositionIO *
179 AtomBase::OnGetStream()
181 // default implementation
182 return theStream;
186 BPositionIO *
187 AtomBase::GetStream()
189 return OnGetStream();
193 void
194 AtomBase::Read(uint64 *value)
196 uint32 bytes_read;
198 bytes_read = GetStream()->Read(value,sizeof(uint64));
200 // Assert((bytes_read == sizeof(uint64),"Read Error");
202 *value = B_BENDIAN_TO_HOST_INT64(*value);
206 void
207 AtomBase::Read(uint32 *value)
209 uint32 bytes_read;
211 bytes_read = GetStream()->Read(value,sizeof(uint32));
213 // Assert((bytes_read == sizeof(uint32),"Read Error");
215 *value = B_BENDIAN_TO_HOST_INT32(*value);
219 void
220 AtomBase::Read(int32 *value)
222 uint32 bytes_read;
224 bytes_read = GetStream()->Read(value,sizeof(int32));
226 // Assert((bytes_read == sizeof(int32),"Read Error");
228 *value = B_BENDIAN_TO_HOST_INT32(*value);
232 void
233 AtomBase::Read(uint16 *value)
235 uint32 bytes_read;
237 bytes_read = GetStream()->Read(value,sizeof(uint16));
239 // Assert((bytes_read == sizeof(uint16),"Read Error");
241 *value = B_BENDIAN_TO_HOST_INT16(*value);
245 void
246 AtomBase::Read(uint8 *value)
248 uint32 bytes_read;
250 bytes_read = GetStream()->Read(value,sizeof(uint8));
252 // Assert((bytes_read == sizeof(uint8),"Read Error");
256 void
257 AtomBase::Read(char *value, uint32 maxread)
259 uint32 bytes_read;
261 bytes_read = GetStream()->Read(value,maxread);
263 // Assert((bytes_read == maxread,"Read Error");
267 void
268 AtomBase::Read(uint8 *value, uint32 maxread)
270 uint32 bytes_read;
272 bytes_read = GetStream()->Read(value,maxread);
274 // Assert((bytes_read == maxread,"Read Error");
278 uint64
279 AtomBase::GetBits(uint64 buffer, uint8 startBit, uint8 totalBits)
281 // startBit should range from 0-63, totalBits should range from 1-64
282 if ((startBit < 64) && (totalBits > 0) && (totalBits <= 64)
283 && (startBit + totalBits <= 64)) {
284 // Ok pull from the buffer the bits wanted.
285 buffer = buffer << startBit;
286 buffer = buffer >> (64 - (totalBits + startBit) + startBit);
288 return buffer;
291 return 0L;
295 uint32
296 AtomBase::GetBits(uint32 buffer, uint8 startBit, uint8 totalBits)
298 // startBit should range from 0-31, totalBits should range from 1-32
299 if ((startBit < 32) && (totalBits > 0) && (totalBits <= 32)
300 && (startBit + totalBits <= 32)) {
301 // Ok pull from the buffer the bits wanted.
302 buffer = buffer << startBit;
303 buffer = buffer >> (32 - (startBit + totalBits) + startBit);
305 return buffer;
308 return 0;
312 FullAtom::FullAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType,
313 uint64 patomSize)
315 AtomBase(pStream, pstreamOffset, patomType, patomSize)
320 FullAtom::~FullAtom()
325 void
326 FullAtom::OnProcessMetaData()
328 Read(&Version);
329 Read(&Flags1);
330 Read(&Flags2);
331 Read(&Flags3);
335 AtomContainer::AtomContainer(BPositionIO *pStream, off_t pstreamOffset,
336 uint32 patomType, uint64 patomSize)
338 AtomBase(pStream, pstreamOffset, patomType, patomSize)
340 TotalChildren = 0;
344 AtomContainer::~AtomContainer()
349 void
350 AtomContainer::DisplayAtoms(uint32 pindent)
352 Indent(pindent);
353 printf("%ld:(%s)\n",TotalChildren,GetAtomName());
354 pindent++;
355 // for each child
356 for (uint32 i = 0;i < TotalChildren;i++) {
357 atomChildren[i]->DisplayAtoms(pindent);
363 void
364 AtomContainer::ProcessMetaData()
366 SetAtomOffset(GetStream()->Position());
368 OnProcessMetaData();
370 AtomBase *aChild;
371 while (IsEndOfAtom() == false) {
372 aChild = GetAtom(GetStream());
373 if (AddChild(aChild)) {
374 aChild->ProcessMetaData();
378 OnChildProcessingComplete();
380 MoveToEnd();
384 bool
385 AtomContainer::AddChild(AtomBase *pChildAtom)
387 if (pChildAtom) {
388 pChildAtom->SetParent(this);
389 atomChildren.push_back(pChildAtom);
390 TotalChildren++;
391 return true;
393 return false;
397 AtomBase *AtomContainer::GetChildAtom(uint32 patomType, uint32 offset)
399 for (uint32 i=0;i<TotalChildren;i++) {
400 if (atomChildren[i]->IsType(patomType)) {
401 // found match, skip if offset non zero.
402 if (offset == 0) {
403 return atomChildren[i];
404 } else {
405 offset--;
407 } else {
408 if (atomChildren[i]->IsContainer()) {
409 // search container
410 AtomBase *aAtomBase = dynamic_cast<AtomContainer *>
411 (atomChildren[i])->GetChildAtom(patomType, offset);
412 if (aAtomBase) {
413 // found in container
414 return aAtomBase;
416 // not found
420 return NULL;
424 void
425 AtomContainer::OnProcessMetaData()