Exemplo n.º 1
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.º 2
0
XMP_Uns32 MOOV_Manager::NewSubtreeSize ( const BoxNode & node, const std::string & parentPath )
{
	XMP_Uns32 subtreeSize = 8 + node.contentSize;	// All boxes will have 8 byte headers.

	if( node.boxType == ISOMedia::k_uuid )
		subtreeSize += 16;				// id of uuid is 16 bytes long
	if ( (node.boxType == ISOMedia::k_free) || (node.boxType == ISOMedia::k_wide) ) {
	}

	for ( size_t i = 0, limit = node.children.size(); i < limit; ++i ) {

		char suffix[6];
		suffix[0] = '/';
		PutUns32BE ( node.boxType, &suffix[1] );
		suffix[5] = 0;
		std::string nodePath = parentPath + suffix;
		
		subtreeSize += this->NewSubtreeSize ( node.children[i], nodePath );
		XMP_Enforce ( subtreeSize < moovBoxSizeLimit );

	}

	return subtreeSize;
	
}	// MOOV_Manager::NewSubtreeSize
Exemplo n.º 3
0
void ID3Header::write ( XMP_IO* file, XMP_Int64 tagSize )
{

	XMP_Assert ( ((XMP_Int64)kID3_TagHeaderSize <= tagSize) && (tagSize < 256*1024*1024) );	// 256 MB limit due to synching.

	XMP_Uns32 synchSize = int32ToSynch ( (XMP_Uns32)tagSize - kID3_TagHeaderSize );
	PutUns32BE ( synchSize, &this->fields[ID3Header::o_size] );
	file->Write ( this->fields, kID3_TagHeaderSize );

}
Exemplo n.º 4
0
void ID3v2Frame::write ( XMP_IO* file, XMP_Uns8 majorVersion )
{
	XMP_Assert ( (2 <= majorVersion) && (majorVersion <= 4) );

	if ( majorVersion < 4 ) {
		PutUns32BE ( this->contentSize, &this->fields[o_size] );
	} else {
		PutUns32BE ( int32ToSynch ( this->contentSize ), &this->fields[o_size] );
	}

	if ( majorVersion > 2 ) {
		file->Write ( this->fields, kV23_FrameHeaderSize );
	} else {
		file->Write ( &this->fields[o_id], 3 );
		file->Write ( &this->fields[o_size+1], 3 );
	}

	file->Write ( this->content, this->contentSize );

}	// ID3v2Frame::write
Exemplo n.º 5
0
ID3v2Frame::ID3v2Frame ( XMP_Uns32 id ) : frameDefaults
{
	memset ( this->fields, 0, kV23_FrameHeaderSize );
	this->id = id;
	PutUns32BE ( id, &this->fields[o_id] );
}
Exemplo n.º 6
0
XMP_Uns32 PSIR_FileWriter::UpdateMemoryResources ( void** dataPtr )
{
	if ( this->fileParsed ) XMP_Throw ( "Not memory based", kXMPErr_EnforceFailure );

	// Compute the size and allocate the new image resource block.

	XMP_Uns32 newLength = 0;

	InternalRsrcMap::iterator irPos = this->imgRsrcs.begin();
	InternalRsrcMap::iterator irEnd = this->imgRsrcs.end();

	for ( ; irPos != irEnd; ++irPos ) {	// Add in the lengths for the 8BIM resources.
		const InternalRsrcInfo & rsrcInfo = irPos->second;
		newLength += 10;
		newLength += ((rsrcInfo.dataLen + 1) & 0xFFFFFFFEUL);
		if ( rsrcInfo.rsrcName == 0 ) {
			newLength += 2;
		} else {
			XMP_Uns32 nameLen = rsrcInfo.rsrcName[0];
			newLength += ((nameLen + 2) & 0xFFFFFFFEUL);	// ! Yes, +2.
		}
	}

	for ( size_t i = 0; i < this->otherRsrcs.size(); ++i ) {	// Add in the non-8BIM resources.
		newLength += this->otherRsrcs[i].rsrcLength;
	}

	XMP_Uns8* newContent = (XMP_Uns8*) malloc ( newLength );
	if ( newContent == 0 ) XMP_Throw ( "Out of memory", kXMPErr_NoMemory );

	// Fill in the new image resource block.

	XMP_Uns8* rsrcPtr = newContent;

	for ( irPos = this->imgRsrcs.begin(); irPos != irEnd; ++irPos ) {	// Do the 8BIM resources.

		const InternalRsrcInfo & rsrcInfo = irPos->second;

		PutUns32BE ( k8BIM, rsrcPtr );
		rsrcPtr += 4;
		PutUns16BE ( rsrcInfo.id, rsrcPtr );
		rsrcPtr += 2;

		if ( rsrcInfo.rsrcName == 0 ) {
			PutUns16BE ( 0, rsrcPtr );
			rsrcPtr += 2;
		} else {
			XMP_Uns32 nameLen = rsrcInfo.rsrcName[0];
			if ( (nameLen+1) > (newLength - (rsrcPtr - newContent)) ) {
				XMP_Throw ( "Buffer overrun", kXMPErr_InternalFailure );
			}
			memcpy ( rsrcPtr, rsrcInfo.rsrcName, nameLen+1 );	// AUDIT: Protected by the above check.
			rsrcPtr += nameLen+1;
			if ( (nameLen & 1) == 0 ) {
				*rsrcPtr = 0;
				++rsrcPtr;
			}
		}

		PutUns32BE ( rsrcInfo.dataLen, rsrcPtr );
		rsrcPtr += 4;
		if ( rsrcInfo.dataLen > (newLength - (rsrcPtr - newContent)) ) {
			XMP_Throw ( "Buffer overrun", kXMPErr_InternalFailure );
		}
		memcpy ( rsrcPtr, rsrcInfo.dataPtr, rsrcInfo.dataLen );	// AUDIT: Protected by the above check.
		rsrcPtr += rsrcInfo.dataLen;
		if ( (rsrcInfo.dataLen & 1) != 0 ) {	// Pad to an even length if necessary.
			*rsrcPtr = 0;
			++rsrcPtr;
		}

	}

	for ( size_t i = 0; i < this->otherRsrcs.size(); ++i ) {	// Do the non-8BIM resources.
		XMP_Uns8* srcPtr = this->memContent + this->otherRsrcs[i].rsrcOffset;
		XMP_Uns32 srcLen = this->otherRsrcs[i].rsrcLength;
		if ( srcLen > (newLength - (rsrcPtr - newContent)) ) {
			XMP_Throw ( "Buffer overrun", kXMPErr_InternalFailure );
		}
		memcpy ( rsrcPtr, srcPtr, srcLen );	// AUDIT: Protected by the above check.
		rsrcPtr += srcLen;	// No need to pad, included in the original resource length.
	}

	XMP_Assert ( rsrcPtr == (newContent + newLength) );

	// Parse the rebuilt image resource block. This is the easiest way to reconstruct the map.

	this->ParseMemoryResources ( newContent, newLength, false );
	this->ownedContent = (newLength > 0);	// ! We really do own the new content, if not empty.

	if ( dataPtr != 0 ) *dataPtr = newContent;
	return newLength;

}	// PSIR_FileWriter::UpdateMemoryResources