text: // =================================================================================================
  // ADOBE SYSTEMS INCORPORATED
  // Copyright 2007 Adobe Systems Incorporated
  // All Rights Reserved
  //
  // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
  // of the Adobe license agreement accompanying it.
  // =================================================================================================
  
  #include "public/include/XMP_Environment.h"	// ! XMP_Environment.h must be the first included header.
  #include "public/include/XMP_Const.h"
  
  #include "XMPFiles/source/FormatSupport/ISOBaseMedia_Support.hpp"
  #include "XMPFiles/source/XMPFiles_Impl.hpp"
  #include "source/XIO.hpp"
  
  // =================================================================================================
  /// \file ISOBaseMedia_Support.cpp
  /// \brief Manager for parsing and serializing ISO Base Media files ( MPEG-4 and JPEG-2000).
  ///
  // =================================================================================================
  
  namespace ISOMedia {
  
  typedef  std::set<XMP_Uns32> KnownBoxList;
  static KnownBoxList boxList;
  #define ISOboxType(x,y) boxList.insert(y)
  #define SEPARATOR ;
  	bool IsKnownBoxType(XMP_Uns32 boxType) {
  		if (boxList.empty()){
  			ISOBoxList ISOBoxPrivateList ;
  		}
  		if (boxList.find(boxType)!=boxList.end()){
  			return true;
  		}
  		return false;
  	}
  	void TerminateGlobals()
  	{
  		boxList.clear();
  	}
  #undef ISOboxType
  #undef SEPARATOR
  static BoxInfo voidInfo;
  
  // =================================================================================================
  // GetBoxInfo - from memory
  // ========================
  
  const XMP_Uns8 * GetBoxInfo ( const XMP_Uns8 * boxPtr, const XMP_Uns8 * boxLimit,
  							  BoxInfo * info, bool throwErrors /* = false */ )
  {
  	XMP_Uns32 u32Size;
  	
  	if ( info == 0 ) info = &voidInfo;
  	info->boxType = info->headerSize = 0;
  	info->contentSize = 0;
  	
  	if ( boxPtr >= boxLimit ) XMP_Throw ( "Bad offset to GetBoxInfo", kXMPErr_InternalFailure );
  	
  	if ( (boxLimit - boxPtr) < 8 ) {	// Is there enough space for a standard box header?
  		if ( throwErrors ) XMP_Throw ( "No space for ISO box header", kXMPErr_BadFileFormat );
  		info->headerSize = (XMP_Uns32) (boxLimit - boxPtr);
  		return boxLimit;
  	}
  	
  	u32Size = GetUns32BE ( boxPtr );
  	info->boxType = GetUns32BE ( boxPtr+4 );
  
  	if ( u32Size >= 8 ) {
  		info->headerSize  = 8;	// Normal explicit size case.
  		info->contentSize = u32Size - 8;
  	} else if ( u32Size == 0 ) {
  		info->headerSize  = 8;	// The box goes to EoF - treat it as "to limit".
  		info->contentSize = (boxLimit - boxPtr) - 8;
  	} else if ( u32Size != 1 ) {
  		if ( throwErrors ) XMP_Throw ( "Bad ISO box size, 2..7", kXMPErr_BadFileFormat );
  		info->headerSize  = 8;	// Bad total size in the range of 2..7, treat as 8.
  		info->contentSize = 0;
  	} else {
  		if ( (boxLimit - boxPtr) < 16 ) {	// Is there enough space for an extended box header?
  			if ( throwErrors ) XMP_Throw ( "No space for ISO extended header", kXMPErr_BadFileFormat );
  			info->headerSize = (XMP_Uns32) (boxLimit - boxPtr);
  			return boxLimit;
  		}
  		XMP_Uns64 u64Size = GetUns64BE ( boxPtr+8 );
  		if ( u64Size < 16 ) {
  			if ( throwErrors ) XMP_Throw ( "Bad ISO extended box size, < 16", kXMPErr_BadFileFormat );
  			u64Size = 16;	// Treat bad total size as 16.
  		}
  		info->headerSize  = 16;
  		info->contentSize = u64Size - 16;
  	}
  	
  	XMP_Assert ( (XMP_Uns64)(boxLimit - boxPtr) >= (XMP_Uns64)info->headerSize );
  	if ( info->contentSize > (XMP_Uns64)((boxLimit - boxPtr) - info->headerSize) ) {
  		if ( throwErrors ) XMP_Throw ( "Bad ISO box content size", kXMPErr_BadFileFormat );
  		info->contentSize = ((boxLimit - boxPtr) - info->headerSize);	// Trim a bad content size to the limit.
  	}
  	
  	return (boxPtr + info->headerSize + info->contentSize);
  
  }	// GetBoxInfo
  
  // =================================================================================================
  // GetBoxInfo - from a file
  // ========================
  
  XMP_Uns64 GetBoxInfo ( XMP_IO* fileRef, const XMP_Uns64 boxOffset, const XMP_Uns64 boxLimit,
  					   BoxInfo * info, bool doSeek /* = true */, bool throwErrors /* = false */ )
  {
  	XMP_Uns8  buffer [8];
  	XMP_Uns32 u32Size;
  	
  	if ( info == 0 ) info = &voidInfo;
  	info->boxType = info->headerSize = 0;
  	info->contentSize = 0;
  	
  	if ( boxOffset >= boxLimit ) XMP_Throw ( "Bad offset to GetBoxInfo", kXMPErr_InternalFailure );
  	
  	if ( (boxLimit - boxOffset) < 8 ) {	// Is there enough space for a standard box header?
  		if ( throwErrors ) XMP_Throw ( "No space for ISO box header", kXMPErr_BadFileFormat );
  		info->headerSize = (XMP_Uns32) (boxLimit - boxOffset);
  		return boxLimit;
  	}
  	
  	if ( doSeek ) fileRef->Seek ( boxOffset, kXMP_SeekFromStart );
  	(void) fileRef->ReadAll ( buffer, 8 );
  
  	u32Size = GetUns32BE ( &buffer[0] );
  	info->boxType = GetUns32BE ( &buffer[4] );
  
  	if ( u32Size >= 8 ) {
  		info->headerSize  = 8;	// Normal explicit size case.
  		info->contentSize = u32Size - 8;
  	} else if ( u32Size == 0 ) {
  		info->headerSize  = 8;	// The box goes to EoF.
  		info->contentSize = fileRef->Length() - (boxOffset + 8);
  	} else if ( u32Size != 1 ) {
  		if ( throwErrors ) XMP_Throw ( "Bad ISO box size, 2..7", kXMPErr_BadFileFormat );
  		info->headerSize  = 8;	// Bad total size in the range of 2..7, treat as 8.
  		info->contentSize = 0;
  	} else {
  		if ( (boxLimit - boxOffset) < 16 ) {	// Is there enough space for an extended box header?
  			if ( throwErrors ) XMP_Throw ( "No space for ISO extended header", kXMPErr_BadFileFormat );
  			info->headerSize = (XMP_Uns32) (boxLimit - boxOffset);
  			return boxLimit;
  		}
  		(void) fileRef->ReadAll ( buffer, 8 );
  		XMP_Uns64 u64Size = GetUns64BE ( &buffer[0] );
  		if ( u64Size < 16 ) {
  			if ( throwErrors ) XMP_Throw ( "Bad ISO extended box size, < 16", kXMPErr_BadFileFormat );
  			u64Size = 16;	// Treat bad total size as 16.
  		}
  		info->headerSize  = 16;
  		info->contentSize = u64Size - 16;
  	}
  	
  	XMP_Assert ( (boxLimit - boxOffset) >= info->headerSize );
  	if ( info->contentSize > (boxLimit - boxOffset - info->headerSize) ) {
  		if ( throwErrors ) XMP_Throw ( "Bad ISO box content size", kXMPErr_BadFileFormat );
  		info->contentSize = (boxLimit - boxOffset - info->headerSize);	// Trim a bad content size to the limit.
  	}
  	
  	return (boxOffset + info->headerSize + info->contentSize);
  
  }	// GetBoxInfo
  
  }	// namespace ISO_Media
  
  
  // =================================================================================================
  