Exemplo n.º 1
0
static void CreatorAtom_ToBE ( CR8R_CreatorAtom * creator_atomP )
{
	creator_atomP->atom_vers_majorS = MakeUns16BE ( creator_atomP->atom_vers_majorS );
	creator_atomP->atom_vers_minorS = MakeUns16BE ( creator_atomP->atom_vers_minorS );

	creator_atomP->magicLu			= MakeUns32BE ( creator_atomP->magicLu );
	creator_atomP->atom_sizeL		= MakeUns32BE ( creator_atomP->atom_sizeL );
	creator_atomP->creator_codeLu	= MakeUns32BE ( creator_atomP->creator_codeLu );
	creator_atomP->creator_eventLu	= MakeUns32BE ( creator_atomP->creator_eventLu );
}
Exemplo n.º 2
0
XMP_Uns8 * MOOV_Manager::AppendNewSubtree ( const BoxNode & node, const std::string & parentPath,
											XMP_Uns8 * newPtr, XMP_Uns8 * newEnd )
{
	if ( (node.boxType == ISOMedia::k_free) || (node.boxType == ISOMedia::k_wide) ) {
	}
	
	XMP_Assert ( (node.boxType != ISOMedia::k_meta) ? (node.children.empty() || (node.contentSize == 0)) :
													  (node.children.empty() || (node.contentSize == 4)) );
	
	XMP_Enforce ( (XMP_Uns32)(newEnd - newPtr) >= (8 + node.contentSize) );

	#if TraceUpdateMoovTree
		XMP_Uns32 be32 = MakeUns32BE ( node.boxType );
		XMP_Uns32 newOffset = (XMP_Uns32) (newPtr - newOrigin);
		XMP_Uns32 addr32 = (XMP_Uns32) this->PickContentPtr ( node );
		fprintf ( stderr, "  Appending %s/%.4s @ 0x%X, size %d, content @ 0x%X\n",
				  parentPath.c_str(), &be32, newOffset, node.contentSize, addr32 );
	#endif

	// Leave the size as 0 for now, append the type and content.
	
	XMP_Uns8 * boxOrigin = newPtr;	// Save origin to fill in the final size.
	PutUns32BE ( node.boxType, (newPtr + 4) );
	IncrNewPtr ( 8 );
	if( node.boxType == ISOMedia::k_uuid )		// For uuid, additional 16 bytes is stored for ID 
	{
		XMP_Enforce ( (XMP_Uns32)(newEnd - newPtr) >= ( 16 + node.contentSize ) );
		memcpy( newPtr, node.idUUID, 16 );
		IncrNewPtr ( 16 );
	}
	if ( node.contentSize != 0 ) {
		const XMP_Uns8 * content = PickContentPtr( node );
		memcpy ( newPtr, content, node.contentSize );
		IncrNewPtr ( node.contentSize );
	}
	
	// Append the nested boxes.
	
	if ( ! node.children.empty() ) {

		char suffix[6];
		suffix[0] = '/';
		PutUns32BE ( node.boxType, &suffix[1] );
		suffix[5] = 0;
		std::string nodePath = parentPath + suffix;
		
		for ( size_t i = 0, limit = node.children.size(); i < limit; ++i ) {
			newPtr = this->AppendNewSubtree ( node.children[i], nodePath, newPtr, newEnd );
		}

	}
	
	// Fill in the final size.
	
	PutUns32BE ( (XMP_Uns32)(newPtr - boxOrigin), boxOrigin );
	
	return newPtr;
	
}	// MOOV_Manager::AppendNewSubtree
Exemplo n.º 3
0
void MOOV_Manager::ParseNestedBoxes ( BoxNode * parentNode, const std::string & parentPath, bool ignoreMetaBoxes )
{
	ISOMedia::BoxInfo isoInfo;
	const XMP_Uns8 * moovOrigin = &this->fullSubtree[0];
	const XMP_Uns8 * childOrigin = moovOrigin + parentNode->offset + parentNode->headerSize;
	const XMP_Uns8 * childLimit  = childOrigin + parentNode->contentSize;
	const XMP_Uns8 * nextChild;
	
	parentNode->contentSize = 0;	// Exclude nested box size.
	if ( parentNode->boxType == ISOMedia::k_meta ) {	// ! The 'meta' box is a FullBox.
		parentNode->contentSize = 4;
		childOrigin += 4;
	}

	for ( const XMP_Uns8 * currChild = childOrigin; currChild < childLimit; currChild = nextChild ) {
	
		nextChild = ISOMedia::GetBoxInfo ( currChild, childLimit, &isoInfo );
		if ( (isoInfo.boxType == 0) &&
			 (isoInfo.headerSize < 8) &&
			 (isoInfo.contentSize == 0) ) continue;	// Skip trailing padding that QT sometimes writes.
		
		XMP_Uns32 childOffset = (XMP_Uns32) (currChild - moovOrigin);
		if( isoInfo.boxType == ISOMedia::k_uuid )
			parentNode->children.push_back ( BoxNode ( childOffset, isoInfo.boxType, isoInfo.headerSize, (XMP_Uns8 *)isoInfo.idUUID, (XMP_Uns32)isoInfo.contentSize ) );
		else
			parentNode->children.push_back ( BoxNode ( childOffset, isoInfo.boxType, isoInfo.headerSize, (XMP_Uns32)isoInfo.contentSize ) );
		BoxNode * newChild = &parentNode->children.back();
		
		#if TraceParseMoovTree
			size_t depth = (parentPath.size()+1) / 5;
			for ( size_t i = 0; i < depth; ++i ) fprintf ( stderr, "  " );
			XMP_Uns32 be32 = MakeUns32BE ( newChild->boxType );
			XMP_Uns32 addr32 = (XMP_Uns32) this->PickContentPtr ( *newChild );
			fprintf ( stderr, "  Parsed %s/%.4s, offset 0x%X, size %d, content @ 0x%X, BoxNode @ 0x%X\n",
					  parentPath.c_str(), &be32, newChild->offset, newChild->contentSize, addr32, newChild );
		#endif
		
		const char * pathSuffix = 0;	// Set to non-zero for boxes of interest.
		/*char buffer[6];	buffer[0] = 0;*/
		
			switch ( isoInfo.boxType ) {	// Want these boxes regardless of parent.
				case ISOMedia::k_udta : pathSuffix = "/udta"; break;
				case ISOMedia::k_meta : pathSuffix = "/meta"; break;
				case ISOMedia::k_ilst : pathSuffix = "/ilst"; break;
				case ISOMedia::k_trak : pathSuffix = "/trak"; break;
				case ISOMedia::k_edts : pathSuffix = "/edts"; break;
				case ISOMedia::k_mdia : pathSuffix = "/mdia"; break;
				case ISOMedia::k_minf : pathSuffix = "/minf"; break;
				case ISOMedia::k_dinf : pathSuffix = "/dinf"; break;
				case ISOMedia::k_stbl : pathSuffix = "/stbl"; break;
			}
		if ( pathSuffix != 0 ) {
			this->ParseNestedBoxes ( newChild, (parentPath + pathSuffix), ignoreMetaBoxes );
		}
	
	}

}	// MOOV_Manager::ParseNestedBoxes
Exemplo n.º 4
0
void MOOV_Manager::SetBox ( BoxRef theBox, const void* dataPtr, XMP_Uns32 size , const XMP_Uns8 * idUUID )
{
	XMP_Enforce ( size < moovBoxSizeLimit );
	BoxNode * node = (BoxNode*)theBox;
	
	if ( node->contentSize == size ) {
		if( node->boxType == ISOMedia::k_uuid && idUUID != 0 )
		{
			memcpy ( node->idUUID, idUUID, 16 );
			this->moovNode.changed = true;
		}
		XMP_Uns8 * oldContent = PickContentPtr ( *node );
		if ( memcmp ( oldContent, dataPtr, size ) == 0 ) return;	// No change.
		memcpy ( oldContent, dataPtr, size );	// Update the old content in-place
		this->moovNode.changed = true;
		
		#if TraceUpdateMoovTree
			XMP_Uns32 be32 = MakeUns32BE ( node->boxType );
			fprintf ( stderr, "Updated '%.4s', parse offset 0x%X, same size\n", &be32, node->offset );
		#endif
	
	} else {
	
		node->changedContent.assign ( size, 0 );	// Fill with 0's first to get the storage.
		memcpy ( &node->changedContent[0], dataPtr, size );
		node->contentSize = size;
		node->changed = true;
		if( node->boxType == ISOMedia::k_uuid && idUUID != 0)
			memcpy ( node->idUUID, idUUID, 16 );
		this->moovNode.changed = true;
		
		#if TraceUpdateMoovTree
			XMP_Uns32 be32 = MakeUns32BE ( node->boxType );
			XMP_Uns32 addr32 = (XMP_Uns32) this->PickContentPtr ( *node );
			fprintf ( stderr, "Updated '%.4s', parse offset 0x%X, new size %d, new content @ 0x%X\n",
					  &be32, node->offset, node->contentSize, addr32 );
		#endif
	
	}

}	// MOOV_Manager::SetBox
Exemplo n.º 5
0
XMP_Uns32 PSIR_FileWriter::UpdateFileResources ( LFA_FileRef sourceRef, LFA_FileRef destRef,
												 IOBuffer * ioBuf, XMP_AbortProc abortProc, void * abortArg )
{
	IgnoreParam(ioBuf);
	const XMP_Uns32 zero32 = 0;

	const bool checkAbort = (abortProc != 0);

	struct RsrcHeader {
		XMP_Uns32 type;
		XMP_Uns16 id;
	};
	XMP_Assert ( (offsetof(RsrcHeader,type) == 0) && (offsetof(RsrcHeader,id) == 4) );

	if ( this->memParsed ) XMP_Throw ( "Not file based", kXMPErr_EnforceFailure );

	XMP_Int64 destLenOffset = LFA_Seek ( destRef, 0, SEEK_CUR );
	XMP_Uns32 destLength = 0;

	LFA_Write ( destRef, &destLength, 4 );	// Write a placeholder for the new PSIR section length.

	#if 0
	{
		printf ( "\nPSIR_FileWriter::UpdateFileResources, count = %d\n", this->imgRsrcs.size() );
		InternalRsrcMap::iterator irPos = this->imgRsrcs.begin();
		InternalRsrcMap::iterator irEnd = this->imgRsrcs.end();
		for ( ; irPos != irEnd; ++irPos ) {
			InternalRsrcInfo& thisRsrc = irPos->second;
			printf ( "  #%d, dataLen %d, origOffset %d (0x%X)%s\n",
					 thisRsrc.id, thisRsrc.dataLen, thisRsrc.origOffset, thisRsrc.origOffset,
					 (thisRsrc.changed ? ", changed" : "") );
		}
	}
	#endif

	// First write all of the '8BIM' resources from the map. Use the internal data if present, else
	// copy the data from the file.

	RsrcHeader outHeader;
	outHeader.type  = MakeUns32BE ( k8BIM );

	InternalRsrcMap::iterator rsrcPos = this->imgRsrcs.begin();
	InternalRsrcMap::iterator rsrcEnd = this->imgRsrcs.end();

	// printf ( "\nPSIR_FileWriter::UpdateFileResources - 8BIM resources\n" );
	for ( ; rsrcPos != rsrcEnd; ++rsrcPos ) {

		InternalRsrcInfo& currRsrc = rsrcPos->second;

		outHeader.id = MakeUns16BE ( currRsrc.id );
		LFA_Write ( destRef, &outHeader, 6 );
		destLength += 6;

		if ( currRsrc.rsrcName == 0 ) {
			LFA_Write ( destRef, &zero32, 2 );
			destLength += 2;
		} else {
			XMP_Assert ( currRsrc.rsrcName[0] != 0 );
			XMP_Uns16 nameLen = currRsrc.rsrcName[0];	// ! Include room for +1.
			XMP_Uns16 paddedLen = (nameLen + 2) & 0xFFFE;	// ! Round up to an even total. Yes, +2!
			LFA_Write ( destRef, currRsrc.rsrcName, paddedLen );
			destLength += paddedLen;
		}

		XMP_Uns32 dataLen = MakeUns32BE ( currRsrc.dataLen );
		LFA_Write ( destRef, &dataLen, 4 );
		// printf ( "  #%d, offset %d (0x%X), dataLen %d\n", currRsrc.id, destLength, destLength, currRsrc.dataLen );

		if ( currRsrc.dataPtr != 0 ) {
			LFA_Write ( destRef, currRsrc.dataPtr, currRsrc.dataLen );
		} else {
			LFA_Seek ( sourceRef, currRsrc.origOffset, SEEK_SET );
			LFA_Copy ( sourceRef, destRef, currRsrc.dataLen );
		}

		destLength += 4 + currRsrc.dataLen;

		if ( (currRsrc.dataLen & 1) != 0 ) {
			LFA_Write ( destRef, &zero32, 1 );	// ! Pad the data to an even length.
			++destLength;
		}

	}

	// Now write all of the non-8BIM resources. Copy the entire resource chunk from the source file.

	// printf ( "\nPSIR_FileWriter::UpdateFileResources - other resources\n" );
	for ( size_t i = 0; i < this->otherRsrcs.size(); ++i ) {
		// printf ( "  offset %d (0x%X), length %d",
		//		 this->otherRsrcs[i].rsrcOffset, this->otherRsrcs[i].rsrcOffset, this->otherRsrcs[i].rsrcLength );
		LFA_Seek ( sourceRef, this->otherRsrcs[i].rsrcOffset, SEEK_SET );
		LFA_Copy ( sourceRef, destRef, this->otherRsrcs[i].rsrcLength );
		destLength += this->otherRsrcs[i].rsrcLength;	// Alignment padding is already included.
	}

	// Write the final PSIR section length, seek back to the end of the file, return the length.

	// printf ( "\nPSIR_FileWriter::UpdateFileResources - final length %d (0x%X)\n", destLength, destLength );
	LFA_Seek ( destRef, destLenOffset, SEEK_SET );
	XMP_Uns32 outLen = MakeUns32BE ( destLength );
	LFA_Write ( destRef, &outLen, 4 );
	LFA_Seek ( destRef, 0, SEEK_END );

	// *** Not rebuilding the internal map - turns out we never want it, why pay for the I/O.
	// *** Should probably add an option for all of these cases, memory and file based.

	return destLength;

}	// PSIR_FileWriter::UpdateFileResources
Exemplo n.º 6
0
namespace ISOMedia {

	enum {
		k_ftyp = 0x66747970UL, 	// File header Box, no version/flags.
	
		k_mp41 = 0x6D703431UL, 	// Compatible brand codes
		k_mp42 = 0x6D703432UL, 
		k_f4v  = 0x66347620UL, 
		k_qt   = 0x71742020UL, 
	
		k_moov = 0x6D6F6F76UL, 	// Container Box, no version/flags.
		k_mvhd = 0x6D766864UL, 	// Data FullBox, has version/flags.
		k_hdlr = 0x68646C72UL,
		k_udta = 0x75647461UL, 	// Container Box, no version/flags.
		k_cprt = 0x63707274UL, 	// Data FullBox, has version/flags.
		k_uuid = 0x75756964UL, 	// Data Box, no version/flags.
		k_free = 0x66726565UL, 	// Free space Box, no version/flags.
		k_mdat = 0x6D646174UL, 	// Media data Box, no version/flags.

		k_trak = 0x7472616BUL,	// Types for the QuickTime timecode track.
		k_tkhd = 0x746B6864UL,
		k_mdia = 0x6D646961UL,
		k_mdhd = 0x6D646864UL,
		k_tmcd = 0x746D6364UL,
		k_mhlr = 0x6D686C72UL,
		k_minf = 0x6D696E66UL,
		k_stbl = 0x7374626CUL,
		k_stsd = 0x73747364UL,
		k_stsc = 0x73747363UL,
		k_stco = 0x7374636FUL,
		k_co64 = 0x636F3634UL,
	
		k_meta = 0x6D657461UL, 	// Types for the iTunes metadata boxes.
		k_ilst = 0x696C7374UL, 
		k_mdir = 0x6D646972UL, 
		k_mean = 0x6D65616EUL,
		k_name = 0x6E616D65UL,
		k_data = 0x64617461UL,
		k_hyphens = 0x2D2D2D2DUL,
	
		k_skip = 0x736B6970UL, 	// Additional classic QuickTime top level boxes.
		k_wide = 0x77696465UL, 
		k_pnot = 0x706E6F74UL, 
	
		k_XMP_ = 0x584D505FUL 	// The QuickTime variant XMP box.
	};
	
	static XMP_Uns32 k_xmpUUID [4] = { MakeUns32BE ( 0xBE7ACFCBUL ),
									   MakeUns32BE ( 0x97A942E8UL ),
									   MakeUns32BE ( 0x9C719994UL ),
									   MakeUns32BE ( 0x91E3AFACUL ) };

	struct BoxInfo {
		XMP_Uns32 boxType;		// In memory as native endian!
		XMP_Uns32 headerSize;	// Normally 8 or 16, less than 8 if available space is too small.
		XMP_Uns64 contentSize;	// Always the real size, never 0 for "to EoF".
		BoxInfo() : boxType(0), headerSize(0), contentSize(0) {};
	};

	// Get basic info about a box in memory, returning a pointer to the following box.
	const XMP_Uns8 * GetBoxInfo ( const XMP_Uns8 * boxPtr, const XMP_Uns8 * boxLimit,
								  BoxInfo * info, bool throwErrors = false );
	
	// Get basic info about a box in a file, returning the offset of the following box. The I/O
	// pointer is left at the start of the box's content. Returns the offset of the following box.
	XMP_Uns64 GetBoxInfo ( LFA_FileRef fileRef, const XMP_Uns64 boxOffset, const XMP_Uns64 boxLimit,
						   BoxInfo * info, bool doSeek = true, bool throwErrors = false );

//	XMP_Uns32 CountChildBoxes ( LFA_FileRef fileRef, const XMP_Uns64 childOffset, const XMP_Uns64 childLimit );

}	// namespace ISO_Media
Exemplo n.º 7
0
	static inline XMP_Uns32 ReadUns32_BE ( XMP_IO* file )
	{
		XMP_Uns32 value;
		file->ReadAll ( &value, 4 );
		return MakeUns32BE ( value );
	}
Exemplo n.º 8
0
	static inline void WriteUns32_BE ( XMP_IO* file, XMP_Uns32 value )
	{
		XMP_Uns32 v = MakeUns32BE ( value );
		file->Write ( &v, 4 );
	}