📄 indesign_handler.cpp
字号:
// Look for the XMP contiguous object stream. Most of the time there will be just one stream and // it will be the XMP. So we might as well fill the whole buffer and not worry about reading too // much and seeking back to the start of the following stream. XMP_Int64 cobjPos = (XMP_Int64)dbPages * kINDD_PageSize; // ! Use a 64 bit multiply! XMP_Uns32 streamLength = (XMP_Uns32)(-(long)(2*sizeof(InDesignContigObjMarker))); // ! For the first pass in the loop. while ( true ) { if ( checkAbort && abortProc(abortArg) ) { XMP_Throw ( "InDesign_MetaHandler::LocateXMP - User abort", kXMPErr_UserAbort ); } // Fetch the start of the next stream and check the contiguous object header. // ! The writeable bit of fObjectClassID is ignored, we use the packet trailer flag. cobjPos += streamLength + (2 * sizeof(InDesignContigObjMarker)); ioBuf.filePos = cobjPos; ioBuf.ptr = ioBuf.limit; // Make sure RefillBuffer does a simple read. LFA_Seek ( fileRef, ioBuf.filePos, SEEK_SET ); RefillBuffer ( fileRef, &ioBuf ); if ( ioBuf.len < (2 * sizeof(InDesignContigObjMarker)) ) break; // Too small, must be end of file. const InDesignContigObjMarker * cobjHeader = (const InDesignContigObjMarker *) ioBuf.ptr; if ( ! CheckBytes ( Uns8Ptr(&cobjHeader->fGUID), kINDDContigObjHeaderGUID, kInDesignGUIDSize ) ) break; // Not a contiguous object header. this->xmpObjID = cobjHeader->fObjectUID; // Save these now while the buffer is good. this->xmpClassID = cobjHeader->fObjectClassID; streamLength = GetUns32LE ( (XMP_Uns8 *) &cobjHeader->fStreamLength ); ioBuf.ptr += sizeof ( InDesignContigObjMarker ); // See if this is the XMP stream. Only check for UTF-8, others get caught in fallback scanning. if ( ! CheckFileSpace ( fileRef, &ioBuf, 4 ) ) continue; // Too small, can't possibly be XMP. XMP_Uns32 innerLength = GetUns32LE ( ioBuf.ptr ); if ( this->streamBigEndian ) innerLength = GetUns32BE ( ioBuf.ptr ); if ( innerLength != (streamLength - 4) ) continue; // Not legit XMP. ioBuf.ptr += 4; if ( ! CheckFileSpace ( fileRef, &ioBuf, kUTF8_PacketHeaderLen ) ) continue; // Too small, can't possibly be XMP. if ( ! CheckBytes ( ioBuf.ptr, kUTF8_PacketStart, strlen((char*)kUTF8_PacketStart) ) ) continue; ioBuf.ptr += strlen((char*)kUTF8_PacketStart); XMP_Uns8 quote = *ioBuf.ptr; if ( (quote != '\'') && (quote != '"') ) continue; ioBuf.ptr += 1; if ( *ioBuf.ptr != quote ) { if ( ! CheckBytes ( ioBuf.ptr, Uns8Ptr("\xEF\xBB\xBF"), 3 ) ) continue; ioBuf.ptr += 3; } if ( *ioBuf.ptr != quote ) continue; ioBuf.ptr += 1; if ( ! CheckBytes ( ioBuf.ptr, Uns8Ptr(" id="), 4 ) ) continue; ioBuf.ptr += 4; quote = *ioBuf.ptr; if ( (quote != '\'') && (quote != '"') ) continue; ioBuf.ptr += 1; if ( ! CheckBytes ( ioBuf.ptr, kUTF8_PacketID, strlen((char*)kUTF8_PacketID) ) ) continue; ioBuf.ptr += strlen((char*)kUTF8_PacketID); if ( *ioBuf.ptr != quote ) continue; ioBuf.ptr += 1; // We've seen enough, it is the XMP. To fit the Basic_Handler model we need to compute the // total size of remaining contiguous objects, the trailingContentSize. this->xmpPrefixSize = sizeof(InDesignContigObjMarker) + 4; this->xmpSuffixSize = sizeof(InDesignContigObjMarker); packetInfo.offset = cobjPos + this->xmpPrefixSize; packetInfo.length = innerLength; XMP_Int64 tcStart = cobjPos + streamLength + (2 * sizeof(InDesignContigObjMarker)); while ( true ) { if ( checkAbort && abortProc(abortArg) ) { XMP_Throw ( "InDesign_MetaHandler::LocateXMP - User abort", kXMPErr_UserAbort ); } cobjPos += streamLength + (2 * sizeof(InDesignContigObjMarker)); ioBuf.filePos = cobjPos; ioBuf.ptr = ioBuf.limit; // Make sure RefillBuffer does a simple read. LFA_Seek ( fileRef, ioBuf.filePos, SEEK_SET ); RefillBuffer ( fileRef, &ioBuf ); if ( ioBuf.len < sizeof(InDesignContigObjMarker) ) break; // Too small, must be end of file. cobjHeader = (const InDesignContigObjMarker *) ioBuf.ptr; if ( ! CheckBytes ( Uns8Ptr(&cobjHeader->fGUID), kINDDContigObjHeaderGUID, kInDesignGUIDSize ) ) break; // Not a contiguous object header. streamLength = GetUns32LE ( (XMP_Uns8 *) &cobjHeader->fStreamLength ); } this->trailingContentSize = cobjPos - tcStart; #if TraceInDesignHandler XMP_Uns32 pktOffset = (XMP_Uns32)this->packetInfo.offset; printf ( "Found XMP in InDesign file, offsets:\n" ); printf ( " CObj head %X, XMP %X, CObj tail %X, file tail %X, padding %X\n", (pktOffset - this->xmpPrefixSize), pktOffset, (pktOffset + this->packetInfo.length), (pktOffset + this->packetInfo.length + this->xmpSuffixSize), (pktOffset + this->packetInfo.length + this->xmpSuffixSize + (XMP_Uns32)this->trailingContentSize) ); #endif this->containsXMP = true; break; } if ( this->containsXMP ) { this->xmpFileOffset = packetInfo.offset; this->xmpFileSize = packetInfo.length; ReadXMPPacket ( this ); }} // InDesign_MetaHandler::CacheFileData// =================================================================================================// InDesign_MetaHandler::WriteXMPPrefix// ====================================void InDesign_MetaHandler::WriteXMPPrefix(){ // Write the contiguous object header and the 4 byte length of the XMP packet. LFA_FileRef fileRef = this->parent->fileRef; XMP_PacketInfo & packetInfo = this->packetInfo; InDesignContigObjMarker header; memcpy ( header.fGUID, kINDDContigObjHeaderGUID, sizeof(header.fGUID) ); // AUDIT: Use of dest sizeof for length is safe. header.fObjectUID = this->xmpObjID; header.fObjectClassID = this->xmpClassID; header.fStreamLength = MakeUns32LE ( 4 + packetInfo.length ); header.fChecksum = (XMP_Uns32)(-1); LFA_Write ( fileRef, &header, sizeof(header) ); XMP_Uns32 pktLength = MakeUns32LE ( packetInfo.length ); if ( this->streamBigEndian ) pktLength = MakeUns32BE ( packetInfo.length ); LFA_Write ( fileRef, &pktLength, sizeof(pktLength) ); } // InDesign_MetaHandler::WriteXMPPrefix// =================================================================================================// InDesign_MetaHandler::WriteXMPSuffix// ====================================void InDesign_MetaHandler::WriteXMPSuffix(){ // Write the contiguous object trailer. LFA_FileRef fileRef = this->parent->fileRef; XMP_PacketInfo & packetInfo = this->packetInfo; InDesignContigObjMarker trailer; memcpy ( trailer.fGUID, kINDDContigObjTrailerGUID, sizeof(trailer.fGUID) ); // AUDIT: Use of dest sizeof for length is safe. trailer.fObjectUID = this->xmpObjID; trailer.fObjectClassID = this->xmpClassID; trailer.fStreamLength = MakeUns32LE ( 4 + packetInfo.length ); trailer.fChecksum = (XMP_Uns32)(-1); LFA_Write ( fileRef, &trailer, sizeof(trailer) ); } // InDesign_MetaHandler::WriteXMPSuffix// =================================================================================================// InDesign_MetaHandler::NoteXMPRemoval// ====================================void InDesign_MetaHandler::NoteXMPRemoval(){ // Nothing to do. } // InDesign_MetaHandler::NoteXMPRemoval// =================================================================================================// InDesign_MetaHandler::NoteXMPInsertion// ======================================void InDesign_MetaHandler::NoteXMPInsertion(){ // Nothing to do. } // InDesign_MetaHandler::NoteXMPInsertion// =================================================================================================// InDesign_MetaHandler::CaptureFileEnding// =======================================void InDesign_MetaHandler::CaptureFileEnding(){ // Nothing to do. The back of an InDesign file is the final zero padding.} // InDesign_MetaHandler::CaptureFileEnding// =================================================================================================// InDesign_MetaHandler::RestoreFileEnding// =======================================void InDesign_MetaHandler::RestoreFileEnding(){ // Pad the file with zeros to a page boundary. LFA_FileRef fileRef = this->parent->fileRef; XMP_PacketInfo & packetInfo = this->packetInfo; XMP_Int64 dataLength = LFA_Measure ( fileRef ); XMP_Int32 padLength = (kINDD_PageSize - ((XMP_Int32)dataLength & kINDD_PageMask)) & kINDD_PageMask; XMP_Uns8 buffer [kINDD_PageSize]; memset ( buffer, 0, kINDD_PageSize ); LFA_Write ( fileRef, buffer, padLength ); } // InDesign_MetaHandler::RestoreFileEnding// =================================================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -