📄 postscript_handler.cpp
字号:
// =================================================================================================// 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 "XMPScanner.hpp"#include "Scanner_Handler.hpp"#include "PostScript_Handler.hpp"using namespace std;// =================================================================================================/// \file PostScript_Handler.cpp/// \brief File format handler for PostScript and EPS files.////// This header ...///// =================================================================================================static const char * kPSFileTag = "%!PS-Adobe-";static const int kPSFileTagLen = strlen ( kPSFileTag );// =================================================================================================// PostScript_MetaHandlerCTor// ==========================XMPFileHandler * PostScript_MetaHandlerCTor ( XMPFiles * parent ){ XMPFileHandler * newHandler = new PostScript_MetaHandler ( parent ); return newHandler;} // PostScript_MetaHandlerCTor// =================================================================================================// PostScript_CheckFormat// ======================bool PostScript_CheckFormat ( XMP_FileFormat format, XMP_StringPtr filePath, LFA_FileRef fileRef, XMPFiles * parent ){ IgnoreParam(filePath); IgnoreParam(parent); XMP_Assert ( (format == kXMP_EPSFile) || (format == kXMP_PostScriptFile) ); IOBuffer ioBuf; XMP_Int64 psOffset; size_t psLength; long temp1, temp2; // Check for the binary EPSF preview header. LFA_Seek ( fileRef, 0, SEEK_SET ); if ( ! CheckFileSpace ( fileRef, &ioBuf, 4 ) ) return false; temp1 = GetUns32BE ( ioBuf.ptr ); if ( temp1 == (long)0xC5D0D3C6 ) { if ( ! CheckFileSpace ( fileRef, &ioBuf, 30 ) ) return false; psOffset = GetUns32LE ( ioBuf.ptr+4 ); // PostScript offset. psLength = GetUns32LE ( ioBuf.ptr+8 ); // PostScript length. bool ok; LFA_Seek ( fileRef, psOffset, SEEK_SET, &ok ); if ( ! ok ) return false; // Don't throw for a failure. ioBuf.ptr = ioBuf.limit; // Make sure RefillBuffer does a simple read. RefillBuffer ( fileRef, &ioBuf ); if ( (ioBuf.len < kIOBufferSize) && (ioBuf.len < psLength) ) return false; // Not enough PostScript. } // Check the start of the PostScript DSC header comment. if ( ! CheckFileSpace ( fileRef, &ioBuf, (kPSFileTagLen + 3 + 1) ) ) return false; if ( ! CheckBytes ( ioBuf.ptr, Uns8Ptr(kPSFileTag), kPSFileTagLen ) ) return false; ioBuf.ptr += kPSFileTagLen; // Check the PostScript DSC major version number. temp1 = LONG_MIN; // Will safely overflow if there are digits, remain negative if there aren't. while ( (ioBuf.ptr < ioBuf.limit) && ('0' <= *ioBuf.ptr) && (*ioBuf.ptr <= '9') ) { temp1 = (temp1 * 10) + (*ioBuf.ptr - '0'); if ( temp1 < 0 ) return false; // Overflow. ioBuf.ptr += 1; } // if ( temp1 < 0 ) break; *** Covered by 3.0 check. if ( temp1 < 3 ) return false; // The version must be at least 3.0. if ( ! CheckFileSpace ( fileRef, &ioBuf, 3 ) ) return false; if ( *ioBuf.ptr != '.' ) return false; // No minor number. ioBuf.ptr += 1; // Check the PostScript DSC minor version number. temp2 = LONG_MIN; // Will safely overflow if there are digits, remain negative if there aren't. while ( (ioBuf.ptr < ioBuf.limit) && ('0' <= *ioBuf.ptr) && (*ioBuf.ptr <= '9') ) { temp2 = (temp2 * 10) + (*ioBuf.ptr - '0'); if ( temp2 < 0 ) return false; // Overflow. ioBuf.ptr += 1; } if ( temp2 < 0 ) return false; // No digits or overflow. // Note that we don't care about the actual minor version number. if ( format == kXMP_PostScriptFile ) { // Almost done for plain PostScript, check for whitespace. if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return false; if ( (*ioBuf.ptr != ' ') && (*ioBuf.ptr != kLF) && (*ioBuf.ptr != kCR) ) return false; ioBuf.ptr += 1; } else { // Check for the EPSF keyword on the header comment. if ( ! CheckFileSpace ( fileRef, &ioBuf, 6+3+1 ) ) return false; if ( ! CheckBytes ( ioBuf.ptr, Uns8Ptr(" EPSF-"), 6 ) ) return false; ioBuf.ptr += 6; // Check the EPS major version number. temp1 = LONG_MIN; // Will safely overflow if there are digits, remain negative if there aren't. while ( (ioBuf.ptr < ioBuf.limit) && ('0' <= *ioBuf.ptr) && (*ioBuf.ptr <= '9') ) { temp1 = (temp1 * 10) + (*ioBuf.ptr - '0'); if ( temp1 < 0 ) return false; // Overflow. ioBuf.ptr += 1; } // if ( temp1 < 0 ) break; *** Covered by 3.0 check. if ( temp1 < 3 ) return false; // The version must be at least 3.0. if ( ! CheckFileSpace ( fileRef, &ioBuf, 3 ) ) return false; if ( *ioBuf.ptr != '.' ) return false; // No minor number. ioBuf.ptr += 1; // Check the EPS minor version number. temp2 = LONG_MIN; // Will safely overflow if there are digits, remain negative if there aren't. while ( (ioBuf.ptr < ioBuf.limit) && ('0' <= *ioBuf.ptr) && (*ioBuf.ptr <= '9') ) { temp2 = (temp2 * 10) + (*ioBuf.ptr - '0'); if ( temp2 < 0 ) return false; // Overflow. ioBuf.ptr += 1; } if ( temp2 < 0 ) return false; // No digits or overflow. // Note that we don't care about the actual minor version number. if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return false; if ( (*ioBuf.ptr != kLF) && (*ioBuf.ptr != kCR) ) return false; ioBuf.ptr += 1; } return true;} // PostScript_CheckFormat// =================================================================================================// PostScript_MetaHandler::PostScript_MetaHandler// ==============================================PostScript_MetaHandler::PostScript_MetaHandler ( XMPFiles * _parent ){ this->parent = _parent; this->handlerFlags = kPostScript_HandlerFlags; this->stdCharForm = kXMP_Char8Bit; this->psHint = kPSHint_NoMarker;} // PostScript_MetaHandler::PostScript_MetaHandler// =================================================================================================// PostScript_MetaHandler::~PostScript_MetaHandler// ===============================================PostScript_MetaHandler::~PostScript_MetaHandler(){ // ! Inherit the base cleanup. } // PostScript_MetaHandler::~PostScript_MetaHandler// =================================================================================================// PostScript_MetaHandler::FindPostScriptHint// ==========================================//// Search for "%ADO_ContainsXMP:" at the beginning of a line, it must be before "%%EndComments". If// the XMP marker is found, look for the MainFirst/MainLast/NoMain options. static const char * kPSContainsXMPString = "%ADO_ContainsXMP:";static const int kPSContainsXMPLength = strlen ( kPSContainsXMPString ); static const char * kPSEndCommentString = "%%EndComments"; // ! Assumed shorter than kPSContainsXMPString.static const int kPSEndCommentLength = strlen ( kPSEndCommentString );int PostScript_MetaHandler::FindPostScriptHint(){ bool found = false; IOBuffer ioBuf; XMP_Uns8 ch; LFA_FileRef fileRef = this->parent->fileRef; XMP_AbortProc abortProc = this->parent->abortProc; void * abortArg = this->parent->abortArg; const bool checkAbort = (abortProc != 0); // Check for the binary EPSF preview header. LFA_Seek ( fileRef, 0, SEEK_SET ); if ( ! CheckFileSpace ( fileRef, &ioBuf, 4 ) ) return false; long temp1 = GetUns32BE ( ioBuf.ptr ); if ( temp1 == (long)0xC5D0D3C6 ) { if ( ! CheckFileSpace ( fileRef, &ioBuf, 30 ) ) return false; size_t psOffset = GetUns32LE ( ioBuf.ptr+4 ); // PostScript offset. size_t psLength = GetUns32LE ( ioBuf.ptr+8 ); // PostScript length. bool ok; LFA_Seek ( fileRef, psOffset, SEEK_SET, &ok ); if ( ! ok ) return false; // Don't throw for a failure. ioBuf.ptr = ioBuf.limit; // Force the next check to refill the buffer. } // Look for the ContainsXMP comment. while ( true ) { if ( checkAbort && abortProc(abortArg) ) { XMP_Throw ( "PostScript_MetaHandler::FindPostScriptHint - User abort", kXMPErr_UserAbort ); } if ( ! CheckFileSpace ( fileRef, &ioBuf, kPSContainsXMPLength ) ) return kPSHint_NoMarker; if ( CheckBytes ( ioBuf.ptr, Uns8Ptr(kPSEndCommentString), kPSEndCommentLength ) ) { // Found "%%EndComments", don't look any further. return kPSHint_NoMarker; } else if ( ! CheckBytes ( ioBuf.ptr, Uns8Ptr(kPSContainsXMPString), kPSContainsXMPLength ) ) { // Not "%%EndComments" or "%ADO_ContainsXMP:", skip past the end of this line. do { if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return kPSHint_NoMarker; ch = *ioBuf.ptr; ++ioBuf.ptr; } while ( ! IsNewline ( ch ) ); } else { // Found "%ADO_ContainsXMP:", look for the main packet location option. ioBuf.ptr += kPSContainsXMPLength; int xmpHint = kPSHint_NoMain; // ! From here on, a failure means "no main", not "no marker". if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return kPSHint_NoMain; if ( ! IsSpaceOrTab ( *ioBuf.ptr ) ) return kPSHint_NoMain; while ( true ) { while ( true ) { // Skip leading spaces and tabs. if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return kPSHint_NoMain; if ( ! IsSpaceOrTab ( *ioBuf.ptr ) ) break; ++ioBuf.ptr; } if ( IsNewline ( *ioBuf.ptr ) ) return kPSHint_NoMain; // Reached the end of the ContainsXMP comment. if ( ! CheckFileSpace ( fileRef, &ioBuf, 6 ) ) return kPSHint_NoMain; if ( CheckBytes ( ioBuf.ptr, Uns8Ptr("NoMain"), 6 ) ) { ioBuf.ptr += 6; xmpHint = kPSHint_NoMain; break; } else if ( CheckBytes ( ioBuf.ptr, Uns8Ptr("MainFi"), 6 ) ) { ioBuf.ptr += 6; if ( ! CheckFileSpace ( fileRef, &ioBuf, 3 ) ) return kPSHint_NoMain; if ( CheckBytes ( ioBuf.ptr, Uns8Ptr("rst"), 3 ) ) { ioBuf.ptr += 3; xmpHint = kPSHint_MainFirst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -