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

📄 jpeg_handler.cpp

📁 flash xmp sdk,flash官方SDK
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// =================================================================================================// ADOBE SYSTEMS INCORPORATED// Copyright 2002-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 "JPEG_Handler.hpp"#include "TIFF_Support.hpp"#include "PSIR_Support.hpp"#include "IPTC_Support.hpp"#include "ReconcileLegacy.hpp"#include "MD5.h"using namespace std;// =================================================================================================/// \file JPEG_Handler.cpp/// \brief File format handler for JPEG.////// This handler ...///// =================================================================================================static const char * kExifSignatureString = "Exif\0\x00";static const char * kExifSignatureAltStr = "Exif\0\xFF";static const size_t kExifSignatureLength = 6;static const size_t kExifMaxDataLength   = 0xFFFF - 2 - kExifSignatureLength;static const char * kPSIRSignatureString = "Photoshop 3.0\0";static const size_t kPSIRSignatureLength = 14;static const size_t kPSIRMaxDataLength   = 0xFFFF - 2 - kPSIRSignatureLength;static const char * kMainXMPSignatureString = "http://ns.adobe.com/xap/1.0/\0";static const size_t kMainXMPSignatureLength = 29;static const char * kExtXMPSignatureString = "http://ns.adobe.com/xmp/extension/\0";static const size_t kExtXMPSignatureLength = 35;static const size_t kExtXMPPrefixLength    = kExtXMPSignatureLength + 32 + 4 + 4;typedef std::map < XMP_Uns32 /* offset */, std::string /* portion */ > ExtXMPPortions;struct ExtXMPContent {	XMP_Uns32 length;	ExtXMPPortions portions;	ExtXMPContent() : length(0) {};	ExtXMPContent ( XMP_Uns32 _length ) : length(_length) {};};typedef std::map < JPEG_MetaHandler::GUID_32 /* guid */, ExtXMPContent /* content */ > ExtendedXMPInfo;#ifndef Trace_UnlimitedJPEG	#define Trace_UnlimitedJPEG 0#endif// =================================================================================================// JPEG_MetaHandlerCTor// ====================XMPFileHandler * JPEG_MetaHandlerCTor ( XMPFiles * parent ){	return new JPEG_MetaHandler ( parent );}	// JPEG_MetaHandlerCTor// =================================================================================================// JPEG_CheckFormat// ================// For JPEG we just check for the initial SOI standalone marker followed by any of the other markers// that might, well, follow it. A more aggressive check might be to read 4KB then check for legit// marker segments within that portion. Probably won't buy much, and thrashes the dCache more. We// tolerate only a small amount of 0xFF padding between the SOI and following marker. This formally// violates the rules of JPEG, but in practice there won't be any padding anyway.//// ! The CheckXyzFormat routines don't track the filePos, that is left to ScanXyzFile.bool JPEG_CheckFormat ( XMP_FileFormat format,	                    XMP_StringPtr  filePath,                        LFA_FileRef    fileRef,                        XMPFiles *     parent ){	IgnoreParam(format); IgnoreParam(filePath); IgnoreParam(parent);	XMP_Assert ( format == kXMP_JPEGFile );	IOBuffer ioBuf;		LFA_Seek ( fileRef, 0, SEEK_SET );	if ( ! CheckFileSpace ( fileRef, &ioBuf, 4 ) ) return false;	// We need at least 4, the buffer is filled anyway.		// First look for the SOI standalone marker. Then skip all 0xFF bytes, padding plus the high	// order byte of the next marker. Finally see if the next marker is legit.		if ( ! CheckBytes ( ioBuf.ptr, "\xFF\xD8", 2 ) ) return false;	ioBuf.ptr += 2;	// Move past the SOI.	while ( (ioBuf.ptr < ioBuf.limit) && (*ioBuf.ptr == 0xFF) ) ++ioBuf.ptr;	if ( ioBuf.ptr == ioBuf.limit ) return false;		XMP_Uns8 id = *ioBuf.ptr;	if ( id >= 0xDD ) return true;	// The most probable cases.	if ( (id < 0xC0) || ((id & 0xF8) == 0xD0) || (id == 0xD8) || (id == 0xDA) || (id == 0xDC) ) return false;	return true;	}	// JPEG_CheckFormat// =================================================================================================// JPEG_MetaHandler::JPEG_MetaHandler// ==================================JPEG_MetaHandler::JPEG_MetaHandler ( XMPFiles * _parent )	: exifMgr(0), psirMgr(0), iptcMgr(0), skipReconcile(false){	this->parent = _parent;	this->handlerFlags = kJPEG_HandlerFlags;	this->stdCharForm  = kXMP_Char8Bit;}	// JPEG_MetaHandler::JPEG_MetaHandler// =================================================================================================// JPEG_MetaHandler::~JPEG_MetaHandler// ===================================JPEG_MetaHandler::~JPEG_MetaHandler(){	if ( exifMgr != 0 ) delete ( exifMgr );	if ( psirMgr != 0 ) delete ( psirMgr );	if ( iptcMgr != 0 ) delete ( iptcMgr );	}	// JPEG_MetaHandler::~JPEG_MetaHandler// =================================================================================================// TableOrDataMarker// =================//// Returns true if the marker is for a table or data marker segment://   FFC4 - DHT//   FFCC - DAC//   FFDB - DQT//   FFDC - DNL//   FFDD - DRI//   FFDE - DHP//   FFDF - EXP//   FFEn - APPn//   FFFE - COMstatic inline bool TableOrDataMarker ( XMP_Uns16 marker ){	if ( (marker & 0xFFF0) == 0xFFE0 ) return true;	// APPn is probably the most common case.		if ( marker < 0xFFC4 ) return false;	if ( marker == 0xFFC4 ) return true;	if ( marker < 0xFFCC ) return false;	if ( marker == 0xFFCC ) return true;	if ( marker < 0xFFDB ) return false;	if ( marker <= 0xFFDF ) return true;	if ( marker < 0xFFFE ) return false;	if ( marker == 0xFFFE ) return true;		return false;}	// TableOrDataMarker// =================================================================================================// JPEG_MetaHandler::CacheFileData// ===============================//// Look for the Exif metadata, Photoshop image resources, and XMP in a JPEG (JFIF) file. The native// thumbnail is inside the Exif. The general layout of a JPEG file is://    SOI marker, 2 bytes, 0xFFD8//    Marker segments for tables and metadata//    SOFn marker segment//    Image data//    EOI marker, 2 bytes, 0xFFD9//// Each marker segment begins with a 2 byte big endian marker and a 2 byte big endian length. The// length includes the 2 bytes of the length field but not the marker. The high order byte of a // marker is 0xFF, the low order byte tells what kind of marker. A marker can be preceeded by any// number of 0xFF fill bytes, however there are no alignment constraints.//// There are virtually no constraints on the order of the marker segments before the SOFn. A reader// must be prepared to handle any order.//// The Exif metadata is in an APP1 marker segment with a 6 byte signature string of "Exif\0\0" at// the start of the data. The rest of the data is a TIFF stream.//// The Photoshop image resources are in an APP13 marker segment with a 14 byte signature string of// "Photoshop 3.0\0". The rest of the data is a sequence of image resources.//// The main XMP is in an APP1 marker segment with a 29 byte signature string of// "http://ns.adobe.com/xap/1.0/\0". The rest of the data is the serialized XMP packet. This is the// only XMP if everything fits within the 64KB limit for marker segment data. If not, there will be// a series of XMP extension segments.//// Each XMP extension segment is an APP1 marker segment whose data contains://    - A 35 byte signature string of "http://ns.adobe.com/xmp/extension/\0".//    - A 128 bit GUID stored as 32 ASCII hex digits, capital A-F, no nul termination.//    - A 32 bit unsigned integer length for the full extended XMP serialization.//    - A 32 bit unsigned integer offset for this portion of the extended XMP serialization.//    - A portion of the extended XMP serialization, up to about 65400 bytes (at most 65458).//// A reader must be prepared to encounter the extended XMP portions out of order. Also to encounter// defective files that have differing extended XMP according to the GUID. The main XMP contains the// GUID for the associated extended XMP.// *** This implementation simply returns when invalid JPEG is encountered. Should we throw instead?void JPEG_MetaHandler::CacheFileData(){	LFA_FileRef      fileRef    = this->parent->fileRef;	XMP_PacketInfo & packetInfo = this->packetInfo;	size_t	  segLen;	bool      ok;	IOBuffer ioBuf;		XMP_AbortProc abortProc  = this->parent->abortProc;	void *        abortArg   = this->parent->abortArg;	const bool    checkAbort = (abortProc != 0);		ExtendedXMPInfo extXMP;		XMP_Assert ( (! this->containsXMP) && (! this->containsTNail) );	// Set containsXMP to true here only if the standard XMP packet is found.		XMP_Assert ( kPSIRSignatureLength == (strlen(kPSIRSignatureString) + 1) );	XMP_Assert ( kMainXMPSignatureLength == (strlen(kMainXMPSignatureString) + 1) );	XMP_Assert ( kExtXMPSignatureLength == (strlen(kExtXMPSignatureString) + 1) );		// -------------------------------------------------------------------------------------------	// Look for any of the Exif, PSIR, main XMP, or extended XMP marker segments. Quit when we hit	// an SOFn, EOI, or invalid/unexpected marker.	LFA_Seek ( fileRef, 2, SEEK_SET );	// Skip the SOI. The JPEG header has already been verified.	ioBuf.filePos = 2;	RefillBuffer ( fileRef, &ioBuf );		while ( true ) {		if ( checkAbort && abortProc(abortArg) ) {			XMP_Throw ( "JPEG_MetaHandler::CacheFileData - User abort", kXMPErr_UserAbort );		}			if ( ! CheckFileSpace ( fileRef, &ioBuf, 2 ) ) return;		if ( *ioBuf.ptr != 0xFF ) return;	// All valid markers have a high byte of 0xFF.		while ( *ioBuf.ptr == 0xFF ) {	// Skip padding 0xFF bytes and the marker's high byte.			++ioBuf.ptr;			if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return;		}				XMP_Uns16 marker = 0xFF00 + *ioBuf.ptr;				if ( marker == 0xFFED ) {					// This is an APP13 marker, is it the Photoshop image resources?						++ioBuf.ptr;	// Move ioBuf.ptr to the marker segment length field.			if ( ! CheckFileSpace ( fileRef, &ioBuf, 2 ) ) return;						segLen = GetUns16BE ( ioBuf.ptr );			if ( segLen < 2 ) return;	// Invalid JPEG.			ioBuf.ptr += 2;	// Move ioBuf.ptr to the marker segment content.			segLen -= 2;	// Adjust segLen to count just the content portion.						ok = CheckFileSpace ( fileRef, &ioBuf, kPSIRSignatureLength );			if ( ok && (segLen >= kPSIRSignatureLength) &&				 CheckBytes ( ioBuf.ptr, kPSIRSignatureString, kPSIRSignatureLength ) ) {							// This is the Photoshop image resources, cache the contents.				ioBuf.ptr += kPSIRSignatureLength;	// Move ioBuf.ptr to the image resources.				segLen -= kPSIRSignatureLength;	// Adjust segLen to count just the image resources.				ok = CheckFileSpace ( fileRef, &ioBuf, segLen );	// Buffer the full content portion.				if ( ! ok ) return;	// Must be a truncated file.				this->psirContents.assign ( (XMP_StringPtr)ioBuf.ptr, segLen );				ioBuf.ptr += segLen;						} else {							// This is the not Photoshop image resources, skip the marker segment's content.				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 if ( marker == 0xFFE1 ) {					// This is an APP1 marker, is it the Exif, main XMP, or extended XMP?			// ! Check in that order, which happens to be increasing signature string length.						++ioBuf.ptr;	// Move ioBuf.ptr to the marker segment length field.			if ( ! CheckFileSpace ( fileRef, &ioBuf, 2 ) ) return;						segLen = GetUns16BE ( ioBuf.ptr );			if ( segLen < 2 ) return;	// Invalid JPEG.			ioBuf.ptr += 2;	// Move ioBuf.ptr to the marker segment content.			segLen -= 2;	// Adjust segLen to count just the content portion.						// Check for the Exif APP1 marker segment.						ok = CheckFileSpace ( fileRef, &ioBuf, kExifSignatureLength );			if ( ok && (segLen >= kExifSignatureLength) &&				 (CheckBytes ( ioBuf.ptr, kExifSignatureString, kExifSignatureLength ) ||				  CheckBytes ( ioBuf.ptr, kExifSignatureAltStr, kExifSignatureLength )) ) {							// This is the Exif metadata, cache the contents.				ioBuf.ptr += kExifSignatureLength;	// Move ioBuf.ptr to the TIFF stream.				segLen -= kExifSignatureLength;	// Adjust segLen to count just the TIFF stream.				ok = CheckFileSpace ( fileRef, &ioBuf, segLen );	// Buffer the full content portion.				if ( ! ok ) return;	// Must be a truncated file.

⌨️ 快捷键说明

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