📄 tiff_support.cpp
字号:
// =================================================================================================// ADOBE SYSTEMS INCORPORATED// Copyright 2006-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 "TIFF_Support.hpp"#include "EndianUtils.hpp"#include "UnicodeConversions.hpp"// =================================================================================================/// \file TIFF_Support.cpp/// \brief Manager for parsing and serializing TIFF streams.///// =================================================================================================// =================================================================================================// TIFF_Manager::TIFF_Manager// ==========================static bool sFirstCTor = true;TIFF_Manager::TIFF_Manager() : bigEndian(false), nativeEndian(false), jpegTNailPtr(0), GetUns16(0), GetUns32(0), GetFloat(0), GetDouble(0), PutUns16(0), PutUns32(0), PutFloat(0), PutDouble(0), xmpHadUserComment(false), xmpHadRelatedSoundFile(false){ if ( sFirstCTor ) { sFirstCTor = false; #if XMP_DebugBuild for ( int ifd = 0; ifd < kTIFF_KnownIFDCount; ++ifd ) { // Make sure the known tag arrays are sorted. for ( const XMP_Uns16* idPtr = sKnownTags[ifd]; *idPtr != 0xFFFF; ++idPtr ) { XMP_Assert ( *idPtr < *(idPtr+1) ); } } #endif } } // TIFF_Manager::TIFF_Manager// =================================================================================================// TIFF_Manager::CheckTIFFHeader// =============================//// Checks the 4 byte TIFF prefix for validity and endianness. Sets the endian flags and the Get// function pointers. Returns the 0th IFD offset.XMP_Uns32 TIFF_Manager::CheckTIFFHeader ( const XMP_Uns8* tiffPtr, XMP_Uns32 length ){ if ( length < kEmptyTIFFLength ) XMP_Throw ( "The TIFF is too small", kXMPErr_BadTIFF ); XMP_Uns32 tiffPrefix = (tiffPtr[0] << 24) | (tiffPtr[1] << 16) | (tiffPtr[2] << 8) | (tiffPtr[3]); if ( tiffPrefix == kBigEndianPrefix ) { this->bigEndian = true; } else if ( tiffPrefix == kLittleEndianPrefix ) { this->bigEndian = false; } else { XMP_Throw ( "Unrecognized TIFF prefix", kXMPErr_BadTIFF ); } this->nativeEndian = (this->bigEndian == kBigEndianHost); if ( this->bigEndian ) { this->GetUns16 = GetUns16BE; this->GetUns32 = GetUns32BE; this->GetFloat = GetFloatBE; this->GetDouble = GetDoubleBE; this->PutUns16 = PutUns16BE; this->PutUns32 = PutUns32BE; this->PutFloat = PutFloatBE; this->PutDouble = PutDoubleBE; } else { this->GetUns16 = GetUns16LE; this->GetUns32 = GetUns32LE; this->GetFloat = GetFloatLE; this->GetDouble = GetDoubleLE; this->PutUns16 = PutUns16LE; this->PutUns32 = PutUns32LE; this->PutFloat = PutFloatLE; this->PutDouble = PutDoubleLE; } XMP_Uns32 mainIFDOffset = this->GetUns32 ( tiffPtr+4 ); // ! Do this after setting the Get/Put procs! if ( mainIFDOffset != 0 ) { // Tolerate empty TIFF even though formally invalid. if ( (length < (kEmptyTIFFLength + kEmptyIFDLength)) || (mainIFDOffset < kEmptyTIFFLength) || (mainIFDOffset > (length - kEmptyIFDLength)) ) { XMP_Throw ( "Invalid primary IFD offset", kXMPErr_BadTIFF ); } } return mainIFDOffset;} // TIFF_Manager::CheckTIFFHeader// =================================================================================================// TIFF_Manager::SetTag_Integer// ============================void TIFF_Manager::SetTag_Integer ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns32 data32 ) { if ( data32 > 0xFFFF ) { this->SetTag ( ifd, id, kTIFF_LongType, 1, &data32 ); } else { XMP_Uns16 data16 = (XMP_Uns16)data32; this->SetTag ( ifd, id, kTIFF_ShortType, 1, &data16 ); }} // TIFF_Manager::SetTag_Integer// =================================================================================================// TIFF_Manager::SetTag_Byte// =========================void TIFF_Manager::SetTag_Byte ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns8 data ){ this->SetTag ( ifd, id, kTIFF_ByteType, 1, &data );} // TIFF_Manager::SetTag_Byte// =================================================================================================// TIFF_Manager::SetTag_SByte// ==========================void TIFF_Manager::SetTag_SByte ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Int8 data ){ this->SetTag ( ifd, id, kTIFF_SByteType, 1, &data );} // TIFF_Manager::SetTag_SByte// =================================================================================================// TIFF_Manager::SetTag_Short// ==========================void TIFF_Manager::SetTag_Short ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns16 clientData ){ XMP_Uns16 streamData; this->PutUns16 ( clientData, &streamData ); this->SetTag ( ifd, id, kTIFF_ShortType, 1, &streamData );} // TIFF_Manager::SetTag_Short// =================================================================================================// TIFF_Manager::SetTag_SShort// =========================== void TIFF_Manager::SetTag_SShort ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Int16 clientData ){ XMP_Int16 streamData; this->PutUns16 ( (XMP_Uns16)clientData, &streamData ); this->SetTag ( ifd, id, kTIFF_SShortType, 1, &streamData );} // TIFF_Manager::SetTag_SShort// =================================================================================================// TIFF_Manager::SetTag_Long// ========================= void TIFF_Manager::SetTag_Long ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns32 clientData ){ XMP_Uns32 streamData; this->PutUns32 ( clientData, &streamData ); this->SetTag ( ifd, id, kTIFF_LongType, 1, &streamData );} // TIFF_Manager::SetTag_Long// =================================================================================================// TIFF_Manager::SetTag_SLong// ========================== void TIFF_Manager::SetTag_SLong ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Int32 clientData ){ XMP_Int32 streamData; this->PutUns32 ( (XMP_Uns32)clientData, &streamData ); this->SetTag ( ifd, id, kTIFF_SLongType, 1, &streamData );} // TIFF_Manager::SetTag_SLong// =================================================================================================// TIFF_Manager::SetTag_Rational// =============================struct StreamRational { XMP_Uns32 num, denom; }; void TIFF_Manager::SetTag_Rational ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns32 clientNum, XMP_Uns32 clientDenom ){ StreamRational streamData; this->PutUns32 ( clientNum, &streamData.num ); this->PutUns32 ( clientDenom, &streamData.denom ); this->SetTag ( ifd, id, kTIFF_RationalType, 1, &streamData );} // TIFF_Manager::SetTag_Rational// =================================================================================================// TIFF_Manager::SetTag_SRational// ============================== void TIFF_Manager::SetTag_SRational ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Int32 clientNum, XMP_Int32 clientDenom ){ StreamRational streamData; this->PutUns32 ( (XMP_Uns32)clientNum, &streamData.num ); this->PutUns32 ( (XMP_Uns32)clientDenom, &streamData.denom ); this->SetTag ( ifd, id, kTIFF_SRationalType, 1, &streamData );} // TIFF_Manager::SetTag_SRational// =================================================================================================// TIFF_Manager::SetTag_Float// ========================== void TIFF_Manager::SetTag_Float ( XMP_Uns8 ifd, XMP_Uns16 id, float clientData ){ float streamData; this->PutFloat ( clientData, &streamData ); this->SetTag ( ifd, id, kTIFF_FloatType, 1, &streamData );} // TIFF_Manager::SetTag_Float// =================================================================================================// TIFF_Manager::SetTag_Double// =========================== void TIFF_Manager::SetTag_Double ( XMP_Uns8 ifd, XMP_Uns16 id, double clientData ){ double streamData; this->PutDouble ( clientData, &streamData ); this->SetTag ( ifd, id, kTIFF_DoubleType, 1, &streamData );} // TIFF_Manager::SetTag_Double// =================================================================================================// TIFF_Manager::SetTag_ASCII// ===========================void TIFF_Manager::SetTag_ASCII ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_StringPtr data ){ this->SetTag ( ifd, id, kTIFF_ASCIIType, (strlen(data) + 1), data ); // ! Include trailing nul.} // TIFF_Manager::SetTag_ASCII// =================================================================================================// UTF16_to_UTF8// =============static void UTF16_to_UTF8 ( const UTF16Unit * utf16Ptr, size_t utf16Len, bool bigEndian, std::string * outStr ){ UTF16_to_UTF8_Proc ToUTF8 = 0; if ( bigEndian ) { ToUTF8 = UTF16BE_to_UTF8; } else { ToUTF8 = UTF16LE_to_UTF8; } UTF8Unit buffer [1000]; size_t inCount, outCount; outStr->erase(); outStr->reserve ( utf16Len * 2 ); // As good a guess as any. while ( utf16Len > 0 ) { ToUTF8 ( utf16Ptr, utf16Len, buffer, sizeof(buffer), &inCount, &outCount ); outStr->append ( (XMP_StringPtr)buffer, outCount ); utf16Ptr += inCount; utf16Len -= inCount; } } // UTF16_to_UTF8// =================================================================================================// TIFF_Manager::DecodeString// ==========================//// Convert an explicitly encoded string to UTF-8. The input must be encoded according to table 6 of// the Exif 2.2 specification. The input pointer is to the start of the 8 byte header, the length is// the full length. In other words, the pointer and length from the IFD entry. Returns true if the// encoding is supported and the conversion succeeds.// *** JIS encoding is not supported yet. Need a static mapping table from JIS X 208-1990 to Unicode.bool TIFF_Manager::DecodeString ( const void * encodedPtr, size_t encodedLen, std::string* utf8Str ) const{ XMP_StringPtr typePtr = (XMP_StringPtr)encodedPtr; XMP_StringPtr valuePtr = typePtr + 8; size_t valueLen = encodedLen - 8; utf8Str->erase(); if ( *typePtr == 'A' ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -