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

📄 jpeg_handler.cpp

📁 flash xmp sdk,flash官方SDK
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				this->exifContents.assign ( (XMP_StringPtr)ioBuf.ptr, segLen );				ioBuf.ptr += segLen;								continue;	// Move on to the next marker.							}						// Check for the main XMP APP1 marker segment.						ok = CheckFileSpace ( fileRef, &ioBuf, kMainXMPSignatureLength );			if ( ok && (segLen >= kMainXMPSignatureLength) &&				 CheckBytes ( ioBuf.ptr, kMainXMPSignatureString, kMainXMPSignatureLength ) ) {							// This is the main XMP, cache the contents.				ioBuf.ptr += kMainXMPSignatureLength;	// Move ioBuf.ptr to the XMP Packet.				segLen -= kMainXMPSignatureLength;	// Adjust segLen to count just the XMP Packet.				ok = CheckFileSpace ( fileRef, &ioBuf, segLen );	// Buffer the full content portion.				if ( ! ok ) return;	// Must be a truncated file.								this->packetInfo.offset = ioBuf.filePos + (ioBuf.ptr - &ioBuf.data[0]);				this->packetInfo.length = segLen;				this->packetInfo.padSize   = 0;				// Assume for now, set these properly in ProcessXMP.				this->packetInfo.charForm  = kXMP_CharUnknown;				this->packetInfo.writeable = true;				this->xmpPacket.assign ( (XMP_StringPtr)ioBuf.ptr, segLen );				ioBuf.ptr += segLen;	// ! Set this->packetInfo.offset first!								this->containsXMP = true;	// Found the standard XMP packet.				continue;	// Move on to the next marker.							}						// Check for an extension XMP APP1 marker segment.						ok = CheckFileSpace ( fileRef, &ioBuf, kExtXMPPrefixLength );	// ! The signature, GUID, length, and offset.			if ( ok && (segLen >= kExtXMPPrefixLength) &&				 CheckBytes ( ioBuf.ptr, kExtXMPSignatureString, kExtXMPSignatureLength ) ) {							// This is a portion of the extended XMP, cache the contents. This is complicated by				// the need to tolerate files where the extension portions are not in order. The				// local ExtendedXMPInfo map uses the GUID as the key and maps that to a struct that				// has the full length and a map of the known portions. This known portion map uses				// the offset of the portion as the key and maps that to a string. Only fully seen				// extended XMP streams are kept, the right one gets picked in ProcessXMP.								segLen -= kExtXMPPrefixLength;	// Adjust segLen to count just the XMP stream portion.				ioBuf.ptr += kExtXMPSignatureLength;	// Move ioBuf.ptr to the GUID.				GUID_32 guid;				XMP_Assert ( sizeof(guid.data) == 32 );				memcpy ( &guid.data[0], ioBuf.ptr, sizeof(guid.data) );	// AUDIT: Use of sizeof(guid.data) is safe.								ioBuf.ptr += 32;	// Move ioBuf.ptr to the length and offset.				XMP_Uns32 fullLen = GetUns32BE ( ioBuf.ptr );				XMP_Uns32 offset  = GetUns32BE ( ioBuf.ptr+4 );								ioBuf.ptr += 8;	// Move ioBuf.ptr to the XMP stream portion.								#if Trace_UnlimitedJPEG					printf ( "New extended XMP portion: fullLen %d, offset %d, GUID %.32s\n", fullLen, offset, guid.data );				#endif								// Find the ExtXMPContent for this GUID, and the string for this portion's offset.								ExtendedXMPInfo::iterator guidPos = extXMP.find ( guid );				if ( guidPos == extXMP.end() ) {					ExtXMPContent newExtContent ( fullLen );					guidPos = extXMP.insert ( extXMP.begin(), ExtendedXMPInfo::value_type ( guid, newExtContent ) );				}								ExtXMPPortions::iterator offsetPos;				ExtXMPContent & extContent = guidPos->second;				if ( extContent.portions.empty() ) {					// When new create a full size offset 0 string, to which all in-order portions will get appended.					offsetPos = extContent.portions.insert ( extContent.portions.begin(),															 ExtXMPPortions::value_type ( 0, std::string() ) );					offsetPos->second.reserve ( extContent.length );				}				// Try to append this portion to a logically contiguous preceeding one.				if ( offset == 0 ) {					offsetPos = extContent.portions.begin();					XMP_Assert ( (offsetPos->first == 0) && (offsetPos->second.size() == 0) );				} else {					offsetPos = extContent.portions.lower_bound ( offset );					--offsetPos;	// Back up to the portion whose offset is less than the new offset.					if ( (offsetPos->first + offsetPos->second.size()) != offset ) {						// Can't append, create a new portion.						offsetPos = extContent.portions.insert ( extContent.portions.begin(),																 ExtXMPPortions::value_type ( offset, std::string() ) );					}				}								// Cache this portion of the extended XMP.								std::string & extPortion = offsetPos->second;				ok = CheckFileSpace ( fileRef, &ioBuf, segLen );	// Buffer the full content portion.				if ( ! ok ) return;	// Must be a truncated file.				extPortion.append ( (XMP_StringPtr)ioBuf.ptr, segLen );				ioBuf.ptr += segLen;								continue;	// Move on to the next marker.							}						// If we get here this is some other uninteresting APP1 marker segment, skip it.						if ( segLen <= size_t(ioBuf.limit - ioBuf.ptr) ) {				ioBuf.ptr += segLen;	// The next marker is in this buffer.			} else {				// The next marker is beyond this buffer, RefillBuffer assumes we're doing sequential reads.				size_t skipCount = segLen - (ioBuf.limit - ioBuf.ptr);	// The amount to move beyond this buffer.				ioBuf.filePos = LFA_Seek ( fileRef, skipCount, SEEK_CUR );				ioBuf.ptr = ioBuf.limit;		// No data left in the buffer.			}				} else if ( TableOrDataMarker ( marker ) ) {					// This is a non-terminating but uninteresting marker segment. Skip it.						++ioBuf.ptr;	// Move ioBuf.ptr to the marker segment length field.			if ( ! CheckFileSpace ( fileRef, &ioBuf, 2 ) ) return;						segLen = GetUns16BE ( ioBuf.ptr );	// Remember that the length includes itself.			if ( segLen < 2 ) return;		// Invalid JPEG.			if ( segLen <= size_t(ioBuf.limit - ioBuf.ptr) ) {				ioBuf.ptr += segLen;	// The next marker is in this buffer.			} else {				// The next marker is beyond this buffer, RefillBuffer assumes we're doing sequential reads.				size_t skipCount = segLen - (ioBuf.limit - ioBuf.ptr);	// The amount to move beyond this buffer.				ioBuf.filePos = LFA_Seek ( fileRef, skipCount, SEEK_CUR );				ioBuf.ptr = ioBuf.limit;		// No data left in the buffer.			}						continue;	// Move on to the next marker.		} else {			break;	// This is a terminating marker of some sort.				}		}	if ( ! extXMP.empty() ) {			// We have extended XMP. Find out which ones are complete, collapse them into a single		// string, and save them for ProcessXMP.				ExtendedXMPInfo::iterator guidPos = extXMP.begin();		ExtendedXMPInfo::iterator guidEnd = extXMP.end();				for ( ; guidPos != guidEnd; ++guidPos ) {					ExtXMPContent & thisContent = guidPos->second;			ExtXMPPortions::iterator partZero = thisContent.portions.begin();			ExtXMPPortions::iterator partEnd  = thisContent.portions.end();			ExtXMPPortions::iterator partPos  = partZero;					#if Trace_UnlimitedJPEG				printf ( "Extended XMP portions for GUID %.32s, full length %d\n",					     guidPos->first.data, guidPos->second.length );				printf ( "  Offset %d, length %d, next offset %d\n",						 partZero->first, partZero->second.size(), (partZero->first + partZero->second.size()) );			#endif						for ( ++partPos; partPos != partEnd; ++partPos ) {				#if Trace_UnlimitedJPEG					printf ( "  Offset %d, length %d, next offset %d\n",							 partPos->first, partPos->second.size(), (partPos->first + partPos->second.size()) );				#endif				if ( partPos->first != partZero->second.size() ) break;	// Quit if not contiguous.				partZero->second.append ( partPos->second );			}						if ( (partPos == partEnd) && (partZero->first == 0) && (partZero->second.size() == thisContent.length) ) {				// This is a complete extended XMP stream.				this->extendedXMP.insert ( ExtendedXMPMap::value_type ( guidPos->first, partZero->second ) );				#if Trace_UnlimitedJPEG					printf ( "Full extended XMP for GUID %.32s, full length %d\n",							 guidPos->first.data, partZero->second.size() );				#endif			}							}		}	}	// JPEG_MetaHandler::CacheFileData// =================================================================================================// JPEG_MetaHandler::ProcessTNail// ==============================void JPEG_MetaHandler::ProcessTNail(){	XMP_Assert ( ! this->processedTNail );	this->processedTNail = true;	// Make sure we only come through here once.	this->containsTNail = false;	// Set it to true after all of the info is gathered.		if ( this->exifMgr == 0 ) {	// Thumbnails only need the Exif, not the PSIR or IPTC.		bool readOnly = ((this->parent->openFlags & kXMPFiles_OpenForUpdate) == 0);		if ( readOnly ) {	// *** Could reduce heap usage by not copying in TIFF_MemoryReader.			this->exifMgr = new TIFF_MemoryReader();		} else {			this->exifMgr = new TIFF_FileWriter();		}		this->exifMgr->ParseMemoryStream ( this->exifContents.c_str(), this->exifContents.size() );	}	this->containsTNail = this->exifMgr->GetTNailInfo ( &this->tnailInfo );	if ( this->containsTNail ) this->tnailInfo.fileFormat = this->parent->format;}	// JPEG_MetaHandler::ProcessTNail// =================================================================================================// JPEG_MetaHandler::ProcessXMP// ============================//// Process the raw XMP and legacy metadata that was previously cached.void JPEG_MetaHandler::ProcessXMP(){		XMP_Assert ( ! this->processedXMP );	this->processedXMP = true;	// Make sure we only come through here once.		// Create the PSIR and IPTC handlers, even if there is no legacy. They might be needed for updates.		XMP_Assert ( (this->psirMgr == 0) && (this->iptcMgr == 0) );	// ProcessTNail might create the exifMgr.	bool readOnly = ((this->parent->openFlags & kXMPFiles_OpenForUpdate) == 0);		if ( readOnly ) {		if ( this->exifMgr == 0 ) this->exifMgr = new TIFF_MemoryReader();		this->psirMgr = new PSIR_MemoryReader();		this->iptcMgr = new IPTC_Reader();	// ! Parse it later.	} else {		if ( this->exifMgr == 0 ) this->exifMgr = new TIFF_FileWriter();		this->psirMgr = new PSIR_FileWriter();		this->iptcMgr = new IPTC_Writer();	// ! Parse it later.	}	// Set up everything for the legacy import, but don't do it yet. This lets us do a forced legacy	// import if the XMP packet gets parsing errors.	bool found;	bool haveExif = (! this->exifContents.empty());	bool haveIPTC = false;		RecJTP_LegacyPriority lastLegacy = kLegacyJTP_None;	TIFF_Manager & exif = *this->exifMgr;	// Give the compiler help in recognizing non-aliases.	PSIR_Manager & psir = *this->psirMgr;	IPTC_Manager & iptc = *this->iptcMgr;	if ( haveExif ) {		exif.ParseMemoryStream ( this->exifContents.c_str(), this->exifContents.size() );	}		if ( ! this->psirContents.empty() ) {		psir.ParseMemoryResources ( this->psirContents.c_str(), this->psirContents.size() );	}		// Determine the last-legacy priority and do the reconciliation. For JPEG files, the relevant	// legacy priorities (ignoring Mac pnot and ANPA resources) are:	//	kLegacyJTP_PSIR_OldCaption - highest	//	kLegacyJTP_PSIR_IPTC	//	kLegacyJTP_JPEG_TIFF_Tags	//	kLegacyJTP_None - lowest	found = psir.GetImgRsrc ( kPSIR_OldCaption, 0 );	if ( ! found ) found = psir.GetImgRsrc ( kPSIR_OldCaptionPStr, 0 );	if ( found ) {		haveIPTC = true;		lastLegacy = kLegacyJTP_PSIR_OldCaption;	}	PSIR_Manager::ImgRsrcInfo iptcInfo;	found = psir.GetImgRsrc ( kPSIR_IPTC, &iptcInfo );	if ( found ) {		haveIPTC = true;		iptc.ParseMemoryDataSets ( iptcInfo.dataPtr, iptcInfo.dataLen );		if ( lastLegacy < kLegacyJTP_PSIR_IPTC ) lastLegacy = kLegacyJTP_PSIR_IPTC;	}		if ( lastLegacy < kLegacyJTP_JPEG_TIFF_Tags ) {		found = exif.GetTag ( kTIFF_PrimaryIFD, kTIFF_ImageDescription, 0 );		if ( ! found ) found = exif.GetTag ( kTIFF_PrimaryIFD, kTIFF_Artist, 0 );		if ( ! found ) found = exif.GetTag ( kTIFF_PrimaryIFD, kTIFF_Copyright, 0 );		if ( found ) lastLegacy = kLegacyJTP_JPEG_TIFF_Tags;	}		XMP_OptionBits options = 0;	if ( this->containsXMP ) options |= k2XMP_FileHadXMP;	if ( haveExif ) options |= k2XMP_FileHadExif;	if ( haveIPTC ) options |= k2XMP_FileHadIPTC;		// Process the main XMP packet. If it fails to parse, do a forced legacy import but still throw	// an exception. This tells the caller that an error happened, but gives them recovered legacy	// should they want to proceed with that.	if ( ! this->xmpPacket.empty() ) {		XMP_Assert ( this->containsXMP );		// Common code takes care of packetInfo.charForm, .padSize, and .writeable.		XMP_StringPtr packetStr = this->xmpPacket.c_str();		XMP_StringLen packetLen = this->xmpPacket.size();		try {			this->xmpObj.ParseFromBuffer ( packetStr, packetLen );		} catch ( ... ) {			XMP_ClearOption ( options, k2XMP_FileHadXMP );			ImportJTPtoXMP ( kXMP_JPEGFile, lastLegacy, &exif, psir, &iptc, &this->xmpObj, options );			throw;	// ! Rethrow the exception, don't absorb it.		}	}	// Process the extended XMP if it has a matching GUID.	if ( ! this->extendedXMP.empty() ) {			bool found;		GUID_32 g32;		std::string extGUID, extPacket;		ExtendedXMPMap::iterator guidPos = this->extendedXMP.end();		found = this->xmpObj.GetProperty ( kXMP_NS_XMP_Note, "HasExtendedXMP", &extGUID, 0 );		if ( found && (extGUID.size() == sizeof(g32.data)) ) {

⌨️ 快捷键说明

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