Beispiel #1
0
XMP_Uns32 TagTree::digest32u(LFA_FileRef file,const std::string key /* ="" */, bool BigEndian /*=false*/,bool hexDisplay /*=false*/ )
{
	XMP_Uns32 r;
	if (4 != LFA_Read ( file, &r, 4, false)) // require all == false => leave the throwing to this routine
		Log::error("could not read 4-byte value from file (end of file?)");
	if ( ((kBigEndianHost==1) &&  !BigEndian ) ||  ((kBigEndianHost==0) && BigEndian ))  // "XOR"
		Flip4(&r);
	if (!key.empty()) {
		char out[19]; //longest unsigned int is "2147483648", 10 chars resp. 0xFFFFFFFF 10 chars
		if (!hexDisplay)
			snprintf(out,18,"%u",r); //unsigned, mind the trailing \0 on Mac btw
		else
			snprintf(out,18,"0x%.8X",r); //unsigned, mind the trailing \0 on Mac btw
		setKeyValue(key,out);
	}
	return r;
}
XMP_Uns32 TIFF_MemoryReader::ProcessOneIFD ( XMP_Uns32 ifdOffset, XMP_Uns8 ifd )
{
	TweakedIFDInfo& ifdInfo = this->containedIFDs[ifd];

	if ( (ifdOffset < 8) || (ifdOffset > (this->tiffLength - kEmptyIFDLength)) ) {
		XMP_Error error(kXMPErr_BadTIFF, "Bad IFD offset" );
		this->NotifyClient ( kXMPErrSev_FileFatal, error );
	}

	XMP_Uns8* ifdPtr = this->tiffStream + ifdOffset;
	XMP_Uns16 ifdCount = this->GetUns16 ( ifdPtr );
	TweakedIFDEntry* ifdEntries = (TweakedIFDEntry*)(ifdPtr+2);

	if ( ifdCount >= 0x8000 ) {
		XMP_Error error(kXMPErr_BadTIFF, "Outrageous IFD count" );
		this->NotifyClient ( kXMPErrSev_FileFatal, error );
	}

	if ( (XMP_Uns32)(2 + ifdCount*12 + 4) > (this->tiffLength - ifdOffset) ) {
		XMP_Error error(kXMPErr_BadTIFF, "Out of bounds IFD" );
		this->NotifyClient ( kXMPErrSev_FileFatal, error );
	}

	ifdInfo.count = ifdCount;
	ifdInfo.entries = ifdEntries;

	XMP_Int32 prevTag = -1;	// ! The GPS IFD has a tag 0, so we need a signed initial value.
	bool needsSorting = false;
	for ( size_t i = 0; i < ifdCount; ++i ) {

		TweakedIFDEntry* thisEntry = &ifdEntries[i];	// Tweak the IFD entry to be more useful.

		if ( ! this->nativeEndian ) {
			Flip2 ( &thisEntry->id );
			Flip2 ( &thisEntry->type );
			Flip4 ( &thisEntry->bytes );
		}

		if ( GetUns16AsIs(&thisEntry->id) <= prevTag ) needsSorting = true;
		prevTag = GetUns16AsIs ( &thisEntry->id );

		if ( (GetUns16AsIs(&thisEntry->type) < kTIFF_ByteType) || (GetUns16AsIs(&thisEntry->type) > kTIFF_LastType) ) continue;	// Bad type, skip this tag.

		#if ! SUNOS_SPARC
	
			thisEntry->bytes *= (XMP_Uns32)kTIFF_TypeSizes[thisEntry->type];
			if ( thisEntry->bytes > 4 ) {
				if ( ! this->nativeEndian ) Flip4 ( &thisEntry->dataOrPos );
				if ( (thisEntry->dataOrPos < 8) || (thisEntry->dataOrPos >= this->tiffLength) ) {
					thisEntry->bytes = thisEntry->dataOrPos = 0;	// Make this bad tag look empty.
				}
				if ( thisEntry->bytes > (this->tiffLength - thisEntry->dataOrPos) ) {
					thisEntry->bytes = thisEntry->dataOrPos = 0;	// Make this bad tag look empty.
				}
			}
	
		#else
	
			void *tempEntryByte = &thisEntry->bytes;
			XMP_Uns32 temp = GetUns32AsIs(&thisEntry->bytes);
			temp = temp * (XMP_Uns32)kTIFF_TypeSizes[GetUns16AsIs(&thisEntry->type)];
			memcpy ( tempEntryByte, &temp, sizeof(thisEntry->bytes) );
	
			// thisEntry->bytes *= (XMP_Uns32)kTIFF_TypeSizes[thisEntry->type];
			if ( GetUns32AsIs(&thisEntry->bytes) > 4 ) {
				void *tempEntryDataOrPos = &thisEntry->dataOrPos;
				if ( ! this->nativeEndian ) Flip4 ( &thisEntry->dataOrPos );
				if ( (GetUns32AsIs(&thisEntry->dataOrPos) < 8) || (GetUns32AsIs(&thisEntry->dataOrPos) >= this->tiffLength) ) {
					// thisEntry->bytes = thisEntry->dataOrPos = 0;	// Make this bad tag look empty.
					memset ( tempEntryByte, 0, sizeof(XMP_Uns32) );
					memset ( tempEntryDataOrPos, 0, sizeof(XMP_Uns32) );
				}
				if ( GetUns32AsIs(&thisEntry->bytes) > (this->tiffLength - GetUns32AsIs(&thisEntry->dataOrPos)) ) {
					// thisEntry->bytes = thisEntry->dataOrPos = 0;	// Make this bad tag look empty.
					memset ( tempEntryByte, 0, sizeof(XMP_Uns32) );
					memset ( tempEntryDataOrPos, 0, sizeof(XMP_Uns32) );
				}
			}
	
		#endif

	}

	ifdPtr += (2 + ifdCount*12);
	XMP_Uns32 nextIFDOffset = this->GetUns32 ( ifdPtr );

	if ( needsSorting ) SortIFD ( &ifdInfo );	// ! Don't perturb the ifdCount used to find the next IFD offset.

	return nextIFDOffset;

}	// TIFF_MemoryReader::ProcessOneIFD