⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiff_memoryreader.cpp

📁 flash xmp sdk,flash官方SDK
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// =================================================================================================// ADOBE SYSTEMS INCORPORATED// Copyright 2006-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 "TIFF_Support.hpp"// =================================================================================================/// \file TIFF_MemoryReader.cpp/// \brief Implementation of the memory-based read-only TIFF_Manager.////// The read-only forms of TIFF_Manager are derived from TIFF_Reader. The GetTag methods are common/// implementations in TIFF_Reader. The parsing code is different in the TIFF_MemoryReader and /// TIFF_FileReader constructors. There are also separate destructors to release captured info.////// The read-only implementations use runtime data that is simple tweaks on the stored form. The/// memory-based reader has one block of data for the whole TIFF stream. The file-based reader has/// one for each IFD, plus one for the collected non-local data for each IFD. Otherwise the logic/// is the same in both cases.////// The count for each IFD is extracted and a pointer set to the first entry in each IFD (serving as/// a normal C array pointer). The IFD entries are tweaked as follows:////// \li The id and type fields are converted to native values./// \li The count field is converted to a native byte count./// \li If the data is not inline the offset is converted to a pointer.////// The tag values, whether inline or not, are not converted to native values. The values returned/// from the GetTag methods are converted on the fly. The id, type, and count fields are easier to/// convert because their types are fixed. They are used more, and more valuable to convert.// =================================================================================================// =================================================================================================// TIFF_MemoryReader::SortIFD// ==========================//// Does a fairly simple minded insertion-like sort. This sort is not going to be optimal for edge// cases like and IFD with lots of duplicates.// *** Might be better done using read and write pointers and two loops. The first loop moves out// *** of order tags by a modified bubble sort, shifting the middle down one at a time in the loop.// *** The first loop stops when a duplicate is hit. The second loop continues by moving the tail// *** entries up to the appropriate slot.void TIFF_MemoryReader::SortIFD ( TweakedIFDInfo* thisIFD ){	XMP_Uns16 tagCount = thisIFD->count;	TweakedIFDEntry* ifdEntries = thisIFD->entries;	XMP_Uns16 prevTag = ifdEntries[0].id;		for ( size_t i = 1; i < tagCount; ++i ) {				XMP_Uns16 thisTag = ifdEntries[i].id;		if ( thisTag > prevTag ) {			// In proper order.			prevTag = thisTag;		} else if ( thisTag == prevTag ) {			// Duplicate tag, keep the 2nd copy, move the tail of the array up, prevTag is unchanged.			memcpy ( &ifdEntries[i-1], &ifdEntries[i], 12*(tagCount-i) );	// AUDIT: Safe, moving tail forward, i >= 1.			--tagCount;			--i; // ! Don't move forward in the array, we've moved the unseen part up.		} else if ( thisTag < prevTag ) {			// Out of order, move this tag up, prevTag is unchanged. Might still be a duplicate!			XMP_Int32 j;	// ! Need a signed value.			for ( j = i-1; j >= 0; --j ) {				if ( ifdEntries[j].id <= thisTag ) break;			}						if ( (j >= 0) && (ifdEntries[j].id == thisTag) ) {				// Out of order duplicate, move it to position j, move the tail of the array up.				ifdEntries[j] = ifdEntries[i];				memcpy ( &ifdEntries[i], &ifdEntries[i+1], 12*(tagCount-(i+1)) );	// AUDIT: Safe, moving tail forward, i >= 1.				--tagCount;				--i; // ! Don't move forward in the array, we've moved the unseen part up.			} else {				// Move the out of order entry to position j+1, move the middle of the array down.				TweakedIFDEntry temp = ifdEntries[i];				++j;	// ! So the insertion index becomes j.				memcpy ( &ifdEntries[j+1], &ifdEntries[j], 12*(i-j) );	// AUDIT: Safe, moving less than i entries to a location before i.				ifdEntries[j] = temp;			}		}			}		thisIFD->count = tagCount;	// Save the final count.	}	// TIFF_MemoryReader::SortIFD// =================================================================================================// TIFF_MemoryReader::GetIFD// =========================bool TIFF_MemoryReader::GetIFD ( XMP_Uns8 ifd, TagInfoMap* ifdMap ) const{	if ( ifd > kTIFF_LastRealIFD ) XMP_Throw ( "Invalid IFD requested", kXMPErr_InternalFailure );	const TweakedIFDInfo* thisIFD = &containedIFDs[ifd];		if ( ifdMap != 0 ) ifdMap->clear();	if ( thisIFD->count == 0 ) return false;		if ( ifdMap != 0 ) {				for ( size_t i = 0; i < thisIFD->count; ++i ) {			TweakedIFDEntry* thisTag = &(thisIFD->entries[i]);			TagInfo info ( thisTag->id, thisTag->type, 0, 0, thisTag->bytes );			info.count = info.dataLen / kTIFF_TypeSizes[info.type];			if ( info.dataLen <= 4 ) {				info.dataPtr = &(thisTag->dataOrPtr);			} else {				info.dataPtr = (const void*)(thisTag->dataOrPtr);			}			(*ifdMap)[info.id] = info;		}		}		return true;}	// TIFF_MemoryReader::GetIFD// =================================================================================================// TIFF_MemoryReader::FindTagInIFD// ===============================const TIFF_MemoryReader::TweakedIFDEntry* TIFF_MemoryReader::FindTagInIFD ( XMP_Uns8 ifd, XMP_Uns16 id ) const{	if ( ifd == kTIFF_KnownIFD ) {		// ... lookup the tag in the known tag map	}		if ( ifd > kTIFF_LastRealIFD ) XMP_Throw ( "Invalid IFD requested", kXMPErr_InternalFailure );	const TweakedIFDInfo* thisIFD = &containedIFDs[ifd];		if ( thisIFD->count == 0 ) return 0;		XMP_Uns32 spanLength = thisIFD->count;	const TweakedIFDEntry* spanBegin = &(thisIFD->entries[0]);		while ( spanLength > 1 ) {		XMP_Uns32 halfLength = spanLength >> 1;	// Since spanLength > 1, halfLength > 0.		const TweakedIFDEntry* spanMiddle = spanBegin + halfLength;				// There are halfLength entries below spanMiddle, then the spanMiddle entry, then		// spanLength-halfLength-1 entries above spanMiddle (which can be none).				if ( spanMiddle->id == id ) {			spanBegin = spanMiddle;			break;		} else if ( spanMiddle->id > id ) {			spanLength = halfLength;	// Discard the middle.		} else {			spanBegin = spanMiddle;	// Keep a valid spanBegin for the return check, don't use spanMiddle+1.			spanLength -= halfLength;		}			}		if ( spanBegin->id != id ) spanBegin = 0;	return spanBegin;}	// TIFF_MemoryReader::FindTagInIFD// =================================================================================================// TIFF_MemoryReader::GetValueOffset// =================================XMP_Uns32 TIFF_MemoryReader::GetValueOffset ( XMP_Uns8 ifd, XMP_Uns16 id ) const{	const TweakedIFDEntry* thisTag = this->FindTagInIFD ( ifd, id );	if ( thisTag == 0 ) return 0;		XMP_Uns8 * valuePtr = (XMP_Uns8*) thisTag->dataOrPtr;	if ( thisTag->bytes <= 4 ) valuePtr = (XMP_Uns8*) &(thisTag->dataOrPtr);		return (valuePtr - this->tiffStream);	}	// TIFF_MemoryReader::GetValueOffset// =================================================================================================// TIFF_MemoryReader::GetTag// =========================bool TIFF_MemoryReader::GetTag ( XMP_Uns8 ifd, XMP_Uns16 id, TagInfo* info ) const{	const TweakedIFDEntry* thisTag = this->FindTagInIFD ( ifd, id );	if ( thisTag == 0 ) return false;		if ( info != 0 ) {		info->id = thisTag->id;		info->type = thisTag->type;		info->count = thisTag->bytes / kTIFF_TypeSizes[thisTag->type];		info->dataLen = thisTag->bytes;				if ( thisTag->bytes <= 4 ) {			info->dataPtr = &(thisTag->dataOrPtr);		} else {			info->dataPtr = (const void*)(thisTag->dataOrPtr);		}	}		return true;	}	// TIFF_MemoryReader::GetTag// =================================================================================================// TIFF_MemoryReader::GetTag_Integer// =================================bool TIFF_MemoryReader::GetTag_Integer ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns32* data ) const{	const TweakedIFDEntry* thisTag = this->FindTagInIFD ( ifd, id );	if ( thisTag == 0 ) return false;		if ( data != 0 ) {		if ( thisTag->type == kTIFF_ShortType ) {			if ( thisTag->bytes != 2 ) return false;	// Wrong count.			*data = this->GetUns16 ( &(thisTag->dataOrPtr) );		} else if ( thisTag->type == kTIFF_LongType ) {			if ( thisTag->bytes != 4 ) return false;	// Wrong count.			*data = this->GetUns32 ( &(thisTag->dataOrPtr) );		} else {			return false;		}	}		return true;}	// TIFF_MemoryReader::GetTag_Integer// =================================================================================================// TIFF_MemoryReader::GetTag_Byte// ==============================bool TIFF_MemoryReader::GetTag_Byte ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns8* data ) const{	const TweakedIFDEntry* thisTag = this->FindTagInIFD ( ifd, id );	if ( thisTag == 0 ) return false;	if ( (thisTag->type != kTIFF_ByteType) || (thisTag->bytes != 1) ) return false;		if ( data != 0 ) {		*data = * ( (XMP_Uns8*) (&(thisTag->dataOrPtr)) );	}		return true;}	// TIFF_MemoryReader::GetTag_Byte// =================================================================================================// TIFF_MemoryReader::GetTag_SByte// ===============================bool TIFF_MemoryReader::GetTag_SByte ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Int8* data ) const{	const TweakedIFDEntry* thisTag = this->FindTagInIFD ( ifd, id );	if ( thisTag == 0 ) return false;	if ( (thisTag->type != kTIFF_SByteType) || (thisTag->bytes != 1) ) return false;		if ( data != 0 ) {		*data = * ( (XMP_Int8*) (&(thisTag->dataOrPtr)) );	}		return true;}	// TIFF_MemoryReader::GetTag_SByte// =================================================================================================// TIFF_MemoryReader::GetTag_Short// ===============================bool TIFF_MemoryReader::GetTag_Short ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns16* data ) const{	const TweakedIFDEntry* thisTag = this->FindTagInIFD ( ifd, id );	if ( thisTag == 0 ) return false;	if ( (thisTag->type != kTIFF_ShortType) || (thisTag->bytes != 2) ) return false;		if ( data != 0 ) {		*data = this->GetUns16 ( &(thisTag->dataOrPtr) );	}		return true;}	// TIFF_MemoryReader::GetTag_Short

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -