📄 indesign_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 "InDesign_Handler.hpp"using namespace std;// =================================================================================================/// \file InDesign_Handler.cpp/// \brief File format handler for InDesign files.////// This header ...////// The layout of an InDesign file in terms of the Basic_MetaHandler model is:////// \li The front of the file. This is everything up to the XMP contiguous object section. The file/// starts with a pair of master pages, followed by the data pages, followed by contiguous object/// sections, finished with padding to a page boundary.////// \li A prefix for the XMP section. This is the contiguous object header. The offset is/// (this->packetInfo.offset - this->xmpPrefixSize).////// \li The XMP packet. The offset is this->packetInfo.offset.////// \li A suffix for the XMP section. This is the contiguous object header. The offset is/// (this->packetInfo.offset + this->packetInfo.length).////// \li Trailing file content. This is the contiguous objects that follow the XMP. The offset is/// (this->packetInfo.offset + this->packetInfo.length + this->xmpSuffixSize).////// \li The back of the file. This is the final padding to a page boundary. The offset is/// (this->packetInfo.offset + this->packetInfo.length + this->xmpSuffixSize + this->trailingContentSize).///// =================================================================================================// *** Add PutXMP overrides that throw if the file does not contain XMP.#ifndef TraceInDesignHandler #define TraceInDesignHandler 0#endifenum { kInDesignGUIDSize = 16 };struct InDesignMasterPage { XMP_Uns8 fGUID [kInDesignGUIDSize]; XMP_Uns8 fMagicBytes [8]; XMP_Uns8 fObjectStreamEndian; XMP_Uns8 fIrrelevant1 [239]; XMP_Uns64 fSequenceNumber; XMP_Uns8 fIrrelevant2 [8]; XMP_Uns32 fFilePages; XMP_Uns8 fIrrelevant3 [3812];};enum { kINDD_PageSize = 4096, kINDD_PageMask = (kINDD_PageSize - 1), kINDD_LittleEndian = 1, kINDD_BigEndian = 2 };struct InDesignContigObjMarker { XMP_Uns8 fGUID [kInDesignGUIDSize]; XMP_Uns32 fObjectUID; XMP_Uns32 fObjectClassID; XMP_Uns32 fStreamLength; XMP_Uns32 fChecksum;};static const XMP_Uns8 * kINDD_MasterPageGUID = (const XMP_Uns8 *) "\x06\x06\xED\xF5\xD8\x1D\x46\xE5\xBD\x31\xEF\xE7\xFE\x74\xB7\x1D";static const XMP_Uns8 * kINDDContigObjHeaderGUID = (const XMP_Uns8 *) "\xDE\x39\x39\x79\x51\x88\x4B\x6C\x8E\x63\xEE\xF8\xAE\xE0\xDD\x38";static const XMP_Uns8 * kINDDContigObjTrailerGUID = (const XMP_Uns8 *) "\xFD\xCE\xDB\x70\xF7\x86\x4B\x4F\xA4\xD3\xC7\x28\xB3\x41\x71\x06";// =================================================================================================// InDesign_MetaHandlerCTor// ========================XMPFileHandler * InDesign_MetaHandlerCTor ( XMPFiles * parent ){ return new InDesign_MetaHandler ( parent );} // InDesign_MetaHandlerCTor// =================================================================================================// InDesign_CheckFormat// ====================//// For InDesign we check that the pair of master pages begin with the 16 byte GUID.bool InDesign_CheckFormat ( XMP_FileFormat format, XMP_StringPtr filePath, LFA_FileRef fileRef, XMPFiles * parent ){ IgnoreParam(format); IgnoreParam(filePath); IgnoreParam(parent); XMP_Assert ( format == kXMP_InDesignFile ); XMP_Assert ( strlen ( (const char *) kINDD_MasterPageGUID ) == kInDesignGUIDSize ); enum { kBufferSize = 2*kINDD_PageSize }; XMP_Uns8 buffer [kBufferSize]; XMP_Int64 filePos = 0; XMP_Uns8 * bufPtr = buffer; XMP_Uns8 * bufLimit = bufPtr + kBufferSize; LFA_Seek ( fileRef, 0, SEEK_SET ); size_t bufLen = LFA_Read ( fileRef, buffer, kBufferSize ); if ( bufLen != kBufferSize ) return false; if ( ! CheckBytes ( bufPtr, kINDD_MasterPageGUID, kInDesignGUIDSize ) ) return false; if ( ! CheckBytes ( bufPtr+kINDD_PageSize, kINDD_MasterPageGUID, kInDesignGUIDSize ) ) return false; return true; } // InDesign_CheckFormat// =================================================================================================// InDesign_MetaHandler::InDesign_MetaHandler// ==========================================InDesign_MetaHandler::InDesign_MetaHandler ( XMPFiles * _parent ) : streamBigEndian(0), xmpObjID(0), xmpClassID(0){ this->parent = _parent; this->handlerFlags = kInDesign_HandlerFlags; this->stdCharForm = kXMP_Char8Bit;} // InDesign_MetaHandler::InDesign_MetaHandler// =================================================================================================// InDesign_MetaHandler::~InDesign_MetaHandler// ===========================================InDesign_MetaHandler::~InDesign_MetaHandler(){ // Nothing to do here. } // InDesign_MetaHandler::~InDesign_MetaHandler// =================================================================================================// InDesign_MetaHandler::CacheFileData// ===================================//// Look for the XMP in an InDesign database file. This is a paged database using 4K byte pages,// followed by redundant "contiguous object streams". Each contiguous object stream is a copy of a// database object stored as a contiguous byte stream. The XMP that we want is one of these.//// The first 2 pages of the database are alternating master pages. A generation number is used to// select the active master page. The master page contains an offset to the start of the contiguous// object streams. Each of the contiguous object streams contains a header and trailer, allowing// fast motion from one stream to the next.//// There is no unique "what am I" tagging to the contiguous object streams, so we simply pick the// first one that looks right. At present this is a 4 byte little endian packet size followed by the// packet.// ! Note that insertion of XMP is not allowed for InDesign, the XMP must be a contiguous copy of an// ! internal database object. So we don't set the packet offset to an insertion point if not found.void InDesign_MetaHandler::CacheFileData(){ LFA_FileRef fileRef = this->parent->fileRef; XMP_PacketInfo & packetInfo = this->packetInfo; IOBuffer ioBuf; size_t dbPages; XMP_Uns8 cobjEndian; XMP_AbortProc abortProc = this->parent->abortProc; void * abortArg = this->parent->abortArg; const bool checkAbort = (abortProc != 0); XMP_Assert ( kINDD_PageSize == sizeof(InDesignMasterPage) ); XMP_Assert ( kIOBufferSize >= (2 * kINDD_PageSize) ); this->containsXMP = false; // --------------------------------------------------------------------------------- // Figure out which master page is active and seek to the contiguous object portion. { ioBuf.filePos = 0; 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 * kINDD_PageSize) ) XMP_Throw ( "GetMainPacket/ScanInDesignFile: Read failure", kXMPErr_ExternalFailure ); InDesignMasterPage * masters = (InDesignMasterPage *) ioBuf.ptr; XMP_Uns64 seq0 = GetUns64LE ( (XMP_Uns8 *) &masters[0].fSequenceNumber ); XMP_Uns64 seq1 = GetUns64LE ( (XMP_Uns8 *) &masters[1].fSequenceNumber ); dbPages = GetUns32LE ( (XMP_Uns8 *) &masters[0].fFilePages ); cobjEndian = masters[0].fObjectStreamEndian; if ( seq1 > seq0 ) { dbPages = GetUns32LE ( (XMP_Uns8 *) &masters[1].fFilePages ); cobjEndian = masters[1].fObjectStreamEndian; } } XMP_Assert ( ! this->streamBigEndian ); if ( cobjEndian == kINDD_BigEndian ) this->streamBigEndian = true; // ---------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -