📄 postscript_handler.cpp
字号:
} break; } else if ( CheckBytes ( ioBuf.ptr, Uns8Ptr("MainLa"), 6 ) ) { ioBuf.ptr += 6; if ( ! CheckFileSpace ( fileRef, &ioBuf, 2 ) ) return kPSHint_NoMain; if ( CheckBytes ( ioBuf.ptr, Uns8Ptr("st"), 2 ) ) { ioBuf.ptr += 2; xmpHint = kPSHint_MainLast; } break; } else { while ( true ) { // Skip until whitespace. if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return kPSHint_NoMain; if ( IsWhitespace ( *ioBuf.ptr ) ) break; ++ioBuf.ptr; } } } // Look for the main packet location option. // Make sure we found exactly a known option. if ( ! CheckFileSpace ( fileRef, &ioBuf, 1 ) ) return kPSHint_NoMain; if ( ! IsWhitespace ( *ioBuf.ptr ) ) return kPSHint_NoMain; return xmpHint; } // Found "%ADO_ContainsXMP:". } // Outer marker loop. return kPSHint_NoMarker; // Should never reach here. } // PostScript_MetaHandler::FindPostScriptHint// =================================================================================================// PostScript_MetaHandler::FindFirstPacket// =======================================//// Run the packet scanner until we find a valid packet. The first one is the main. For simplicity,// the state of all snips is checked after each buffer is read. In theory only the last of the// previous snips might change from partial to valid, but then we would have to special case the// first pass when there is no previous set of snips. Since we have to get a full report to look at// the last snip anyway, it costs virtually nothing extra to recheck all of the snips.bool PostScript_MetaHandler::FindFirstPacket(){ int snipCount; bool found = false; size_t bufPos, bufLen; LFA_FileRef fileRef = this->parent->fileRef; XMP_Int64 fileLen = LFA_Measure ( fileRef ); XMP_PacketInfo & packetInfo = this->packetInfo; XMPScanner scanner ( fileLen ); XMPScanner::SnipInfoVector snips; enum { kBufferSize = 64*1024 }; XMP_Uns8 buffer [kBufferSize]; XMP_AbortProc abortProc = this->parent->abortProc; void * abortArg = this->parent->abortArg; const bool checkAbort = (abortProc != 0); bufPos = 0; bufLen = 0; LFA_Seek ( fileRef, 0, SEEK_SET ); // Seek back to the beginning of the file. while ( true ) { if ( checkAbort && abortProc(abortArg) ) { XMP_Throw ( "PostScript_MetaHandler::FindFirstPacket - User abort", kXMPErr_UserAbort ); } bufPos += bufLen; bufLen = LFA_Read ( fileRef, buffer, kBufferSize ); if ( bufLen == 0 ) return false; // Must be at EoF, no packets found. scanner.Scan ( buffer, bufPos, bufLen ); snipCount = scanner.GetSnipCount(); scanner.Report ( snips ); for ( int i = 0; i < snipCount; ++i ) { if ( snips[i].fState == XMPScanner::eValidPacketSnip ) { if ( snips[i].fLength > 0x7FFFFFFF ) XMP_Throw ( "PostScript_MetaHandler::FindFirstPacket: Oversize packet", kXMPErr_BadXMP ); packetInfo.offset = snips[i].fOffset; packetInfo.length = (XMP_Int32)snips[i].fLength; packetInfo.charForm = snips[i].fCharForm; packetInfo.writeable = (snips[i].fAccess == 'w'); return true; } } } return false;} // FindFirstPacket// =================================================================================================// PostScript_MetaHandler::FindLastPacket// ======================================//// Run the packet scanner backwards until we find the start of a packet, or a valid packet. If we// found a packet start, resume forward scanning to see if it is a valid packet. For simplicity, all// of the snips are checked on each pass, for much the same reasons as in FindFirstPacket.#if 1// *** Doing this right (as described above) requires out of order scanning support which isn't// *** implemented yet. For now we scan the whole file and pick the last valid packet.bool PostScript_MetaHandler::FindLastPacket(){ int pkt; size_t bufPos, bufLen; LFA_FileRef fileRef = this->parent->fileRef; XMP_Int64 fileLen = LFA_Measure ( fileRef ); XMP_PacketInfo & packetInfo = this->packetInfo; // ------------------------------------------------------ // Scan the entire file to find all of the valid packets. XMPScanner scanner ( fileLen ); enum { kBufferSize = 64*1024 }; XMP_Uns8 buffer [kBufferSize]; XMP_AbortProc abortProc = this->parent->abortProc; void * abortArg = this->parent->abortArg; const bool checkAbort = (abortProc != 0); LFA_Seek ( fileRef, 0, SEEK_SET ); // Seek back to the beginning of the file. for ( bufPos = 0; bufPos < fileLen; bufPos += bufLen ) { if ( checkAbort && abortProc(abortArg) ) { XMP_Throw ( "PostScript_MetaHandler::FindLastPacket - User abort", kXMPErr_UserAbort ); } bufLen = LFA_Read ( fileRef, buffer, kBufferSize ); if ( bufLen == 0 ) XMP_Throw ( "PostScript_MetaHandler::FindLastPacket: Read failure", kXMPErr_ExternalFailure ); scanner.Scan ( buffer, bufPos, bufLen ); } // ------------------------------- // Pick the last the valid packet. long snipCount = scanner.GetSnipCount(); XMPScanner::SnipInfoVector snips ( snipCount ); scanner.Report ( snips ); for ( pkt = snipCount-1; pkt >= 0; --pkt ) { if ( snips[pkt].fState == XMPScanner::eValidPacketSnip ) break; } if ( pkt >= 0 ) { if ( snips[pkt].fLength > 0x7FFFFFFF ) XMP_Throw ( "PostScript_MetaHandler::FindLastPacket: Oversize packet", kXMPErr_BadXMP ); packetInfo.offset = snips[pkt].fOffset; packetInfo.length = (XMP_Int32)snips[pkt].fLength; packetInfo.charForm = snips[pkt].fCharForm; packetInfo.writeable = (snips[pkt].fAccess == 'w'); return true; } return false;} // PostScript_MetaHandler::FindLastPacket#elsebool PostScript_MetaHandler::FindLastPacket(){ int err, snipCount; bool found = false; XMP_Int64 backPos, backLen; size_t ioCount; LFA_FileRef fileRef = this->parent->fileRef; XMP_Int64 fileLen = LFA_Measure ( fileRef ); XMP_PacketInfo & packetInfo = this->packetInfo; XMPScanner scanner ( fileLen ); XMPScanner::SnipInfoVector snips; enum { kBufferSize = 64*1024 }; XMP_Uns8 buffer [kBufferSize]; XMP_AbortProc abortProc = this->parent->abortProc; void * abortArg = this->parent->abortArg; const bool checkAbort = (abortProc != 0); backPos = fileLen; backLen = 0; while ( true ) { if ( checkAbort && abortProc(abortArg) ) { XMP_Throw ( "PostScript_MetaHandler::FindLastPacket - User abort", kXMPErr_UserAbort ); } backLen = kBufferSize; if ( backPos < kBufferSize ) backLen = backPos; if ( backLen == 0 ) return false; // Must be at BoF, no packets found. backPos -= backLen; LFA_Seek ( fileRef, backPos, SEEK_SET ); // Seek back to the start of the next buffer. #error "ioCount is 32 bits, backLen is 64" ioCount = LFA_Read ( fileRef, buffer, backLen ); if ( ioCount != backLen ) XMP_Throw ( "PostScript_MetaHandler::FindLastPacket: Read failure", kXMPErr_ExternalFailure ); scanner.Scan ( buffer, backPos, backLen ); snipCount = scanner.GetSnipCount(); scanner.Report ( snips ); for ( int i = snipCount-1; i >= 0; --i ) { if ( snips[i].fState == XMPScanner::eValidPacketSnip ) { return VerifyMainPacket ( fileRef, snips[i].fOffset, snips[i].fLength, format, beLenient, mainInfo ); } else if ( snips[i].fState == XMPScanner::ePartialPacketSnip ) { // This part is a tad tricky. We have a partial packet, so we need to scan // forward from its ending to see if it is a valid packet. Snips won't recombine, // the partial snip will change state. Be careful with the I/O to not clobber the // backward scan positions, so that it can be resumed if necessary. size_t fwdPos = snips[i].fOffset + snips[i].fLength; LFA_Seek ( fileRef, fwdPos, SEEK_SET ); // Seek to the end of the partial snip. while ( (fwdPos < fileLen) && (snips[i].fState == XMPScanner::ePartialPacketSnip) ) { ioCount = LFA_Read ( fileRef, buffer, kBufferSize ); if ( ioCount == 0 ) XMP_Throw ( "PostScript_MetaHandler::FindLastPacket: Read failure", kXMPErr_ExternalFailure ); scanner.Scan ( buffer, fwdPos, ioCount ); scanner.Report ( snips ); fwdPos += ioCount; } if ( snips[i].fState == XMPScanner::eValidPacketSnip ) { if ( snips[i].fLength > 0x7FFFFFFF ) XMP_Throw ( "PostScript_MetaHandler::FindLastPacket: Oversize packet", kXMPErr_BadXMP ); packetInfo.offset = snips[i].fOffset; packetInfo.length = (XMP_Int32)snips[i].fLength; packetInfo.charForm = snips[i].fCharForm; packetInfo.writeable = (snips[i].fAccess == 'w'); return true; } } } // Backwards snip loop. } // Backwards read loop. return false; // Should never get here. } // PostScript_MetaHandler::FindLastPacket#endif// =================================================================================================// PostScript_MetaHandler::CacheFileData// =====================================void PostScript_MetaHandler::CacheFileData(){ this->containsXMP = false; this->psHint = FindPostScriptHint(); if ( this->psHint == kPSHint_MainFirst ) { this->containsXMP = FindFirstPacket(); } else if ( this->psHint == kPSHint_MainLast ) { this->containsXMP = FindLastPacket(); } if ( this->containsXMP ) ReadXMPPacket ( this );} // PostScript_MetaHandler::CacheFileData// =================================================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -