📄 tiff_filewriter.cpp
字号:
bool TIFF_FileWriter::GetTag_SShort ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Int16* data ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( thisTag == 0 ) return false; if ( (thisTag->type != kTIFF_SShortType) || (thisTag->dataLen != 2) ) return false; if ( data != 0 ) { *data = (XMP_Int16) this->GetUns16 ( thisTag->dataPtr ); } return true;} // TIFF_FileWriter::GetTag_SShort// =================================================================================================// TIFF_FileWriter::GetTag_Long// ============================bool TIFF_FileWriter::GetTag_Long ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Uns32* data ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( thisTag == 0 ) return false; if ( (thisTag->type != kTIFF_LongType) || (thisTag->dataLen != 4) ) return false; if ( data != 0 ) { *data = this->GetUns32 ( thisTag->dataPtr ); } return true;} // TIFF_FileWriter::GetTag_Long// =================================================================================================// TIFF_FileWriter::GetTag_SLong// =============================bool TIFF_FileWriter::GetTag_SLong ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_Int32* data ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( thisTag == 0 ) return false; if ( (thisTag->type != kTIFF_SLongType) || (thisTag->dataLen != 4) ) return false; if ( data != 0 ) { *data = (XMP_Int32) this->GetUns32 ( thisTag->dataPtr ); } return true;} // TIFF_FileWriter::GetTag_SLong// =================================================================================================// TIFF_FileWriter::GetTag_Rational// ================================bool TIFF_FileWriter::GetTag_Rational ( XMP_Uns8 ifd, XMP_Uns16 id, Rational* data ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( (thisTag == 0) || (thisTag->dataPtr == 0) ) return false; if ( (thisTag->type != kTIFF_RationalType) || (thisTag->dataLen != 8) ) return false; if ( data != 0 ) { XMP_Uns32* dataPtr = (XMP_Uns32*)thisTag->dataPtr; data->num = this->GetUns32 ( dataPtr ); data->denom = this->GetUns32 ( dataPtr+1 ); } return true;} // TIFF_FileWriter::GetTag_Rational// =================================================================================================// TIFF_FileWriter::GetTag_SRational// =================================bool TIFF_FileWriter::GetTag_SRational ( XMP_Uns8 ifd, XMP_Uns16 id, SRational* data ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( (thisTag == 0) || (thisTag->dataPtr == 0) ) return false; if ( (thisTag->type != kTIFF_SRationalType) || (thisTag->dataLen != 8) ) return false; if ( data != 0 ) { XMP_Uns32* dataPtr = (XMP_Uns32*)thisTag->dataPtr; data->num = (XMP_Int32) this->GetUns32 ( dataPtr ); data->denom = (XMP_Int32) this->GetUns32 ( dataPtr+1 ); } return true;} // TIFF_FileWriter::GetTag_SRational// =================================================================================================// TIFF_FileWriter::GetTag_Float// =============================bool TIFF_FileWriter::GetTag_Float ( XMP_Uns8 ifd, XMP_Uns16 id, float* data ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( thisTag == 0 ) return false; if ( (thisTag->type != kTIFF_FloatType) || (thisTag->dataLen != 4) ) return false; if ( data != 0 ) { *data = this->GetFloat ( thisTag->dataPtr ); } return true;} // TIFF_FileWriter::GetTag_Float// =================================================================================================// TIFF_FileWriter::GetTag_Double// ==============================bool TIFF_FileWriter::GetTag_Double ( XMP_Uns8 ifd, XMP_Uns16 id, double* data ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( (thisTag == 0) || (thisTag->dataPtr == 0) ) return false; if ( (thisTag->type != kTIFF_DoubleType) || (thisTag->dataLen != 8) ) return false; if ( data != 0 ) { double* dataPtr = (double*)thisTag->dataPtr; *data = this->GetDouble ( dataPtr ); } return true;} // TIFF_FileWriter::GetTag_Double// =================================================================================================// TIFF_FileWriter::GetTag_ASCII// =============================bool TIFF_FileWriter::GetTag_ASCII ( XMP_Uns8 ifd, XMP_Uns16 id, XMP_StringPtr* dataPtr, XMP_StringLen* dataLen ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( thisTag == 0 ) return false; if ( (thisTag->dataLen > 4) && (thisTag->dataPtr == 0) ) return false; if ( thisTag->type != kTIFF_ASCIIType ) return false; if ( dataPtr != 0 ) *dataPtr = (XMP_StringPtr)thisTag->dataPtr; if ( dataLen != 0 ) *dataLen = thisTag->dataLen; return true;} // TIFF_FileWriter::GetTag_ASCII// =================================================================================================// TIFF_FileWriter::GetTag_EncodedString// =====================================bool TIFF_FileWriter::GetTag_EncodedString ( XMP_Uns8 ifd, XMP_Uns16 id, std::string* utf8Str ) const{ const InternalTagInfo* thisTag = this->FindTagInIFD ( ifd, id ); if ( thisTag == 0 ) return false; if ( thisTag->type != kTIFF_UndefinedType ) return false; if ( utf8Str == 0 ) return true; // Return true if the converted string is not wanted. bool ok = this->DecodeString ( thisTag->dataPtr, thisTag->dataLen, utf8Str ); return ok;} // TIFF_FileWriter::GetTag_EncodedString// =================================================================================================// TIFF_FileWriter::SetTag_EncodedString// =====================================void TIFF_FileWriter::SetTag_EncodedString ( XMP_Uns8 ifd, XMP_Uns16 id, const std::string& utf8Str, XMP_Uns8 encoding ){ XMP_Throw ( "Not yet implemented", kXMPErr_Unimplemented );} // TIFF_FileWriter::SetTag_EncodedString// =================================================================================================// TIFF_FileWriter::IsLegacyChanged// ================================bool TIFF_FileWriter::IsLegacyChanged(){ if ( ! this->changed ) return false; for ( int ifd = 0; ifd < kTIFF_KnownIFDCount; ++ifd ) { InternalIFDInfo & thisIFD = this->containedIFDs[ifd]; if ( ! thisIFD.changed ) continue; InternalTagMap::iterator tagPos; InternalTagMap::iterator tagEnd = thisIFD.tagMap.end(); for ( tagPos = thisIFD.tagMap.begin(); tagPos != tagEnd; ++tagPos ) { InternalTagInfo & thisTag = tagPos->second; if ( thisTag.changed && (thisTag.id != kTIFF_XMP) ) return true; } } return false; // Can get here if the XMP tag is the only one changed.} // TIFF_FileWriter::IsLegacyChanged// =================================================================================================// TIFF_FileWriter::ParseMemoryStream// ==================================void TIFF_FileWriter::ParseMemoryStream ( const void* data, XMP_Uns32 length, bool copyData /* = true */ ) { this->DeleteExistingInfo(); this->memParsed = true; if ( length == 0 ) return; // Allocate space for the full in-memory stream and copy it. if ( ! copyData ) { XMP_Assert ( ! this->ownedStream ); this->memStream = (XMP_Uns8*) data; } else { if ( length > 100*1024*1024 ) XMP_Throw ( "Outrageous length for memory-based TIFF", kXMPErr_BadTIFF ); this->memStream = (XMP_Uns8*) malloc(length); if ( this->memStream == 0 ) XMP_Throw ( "Out of memory", kXMPErr_NoMemory ); memcpy ( this->memStream, data, length ); // AUDIT: Safe, malloc'ed length bytes above. } this->tiffLength = length; // Find and process the primary, Exif, GPS, and Interoperability IFDs. XMP_Uns32 primaryIFDOffset = this->CheckTIFFHeader ( this->memStream, length ); XMP_Uns32 tnailIFDOffset = 0; if ( primaryIFDOffset != 0 ) tnailIFDOffset = this->ProcessMemoryIFD ( primaryIFDOffset, kTIFF_PrimaryIFD ); const InternalTagInfo* exifIFDTag = this->FindTagInIFD ( kTIFF_PrimaryIFD, kTIFF_ExifIFDPointer ); if ( (exifIFDTag != 0) && (exifIFDTag->type == kTIFF_LongType) && (exifIFDTag->dataLen == 4) ) { XMP_Uns32 exifOffset = this->GetUns32 ( &exifIFDTag->dataOrOffset ); (void) this->ProcessMemoryIFD ( exifOffset, kTIFF_ExifIFD ); } const InternalTagInfo* gpsIFDTag = this->FindTagInIFD ( kTIFF_PrimaryIFD, kTIFF_GPSInfoIFDPointer ); if ( (gpsIFDTag != 0) && (gpsIFDTag->type == kTIFF_LongType) && (gpsIFDTag->dataLen == 4) ) { XMP_Uns32 gpsOffset = this->GetUns32 ( &gpsIFDTag->dataOrOffset ); (void) this->ProcessMemoryIFD ( gpsOffset, kTIFF_GPSInfoIFD ); } const InternalTagInfo* interopIFDTag = this->FindTagInIFD ( kTIFF_ExifIFD, kTIFF_InteroperabilityIFDPointer ); if ( (interopIFDTag != 0) && (interopIFDTag->type == kTIFF_LongType) && (interopIFDTag->dataLen == 4) ) { XMP_Uns32 interopOffset = this->GetUns32 ( &interopIFDTag->dataOrOffset ); (void) this->ProcessMemoryIFD ( interopOffset, kTIFF_InteropIFD ); } // Process the thumbnail IFD. We only do this for Exif-compliant TIFF streams. Extract the // JPEG thumbnail image pointer (tag 513) for later use by GetTNailInfo. if ( (tnailIFDOffset != 0) && (! this->containedIFDs[kTIFF_ExifIFD].tagMap.empty()) ) { (void) this->ProcessMemoryIFD ( tnailIFDOffset, kTIFF_TNailIFD ); const InternalTagInfo* jpegInfo = FindTagInIFD ( kTIFF_TNailIFD, kTIFF_JPEGInterchangeFormat ); if ( jpegInfo != 0 ) { XMP_Uns32 tnailImageOffset = this->GetUns32 ( &jpegInfo->dataOrOffset ); this->jpegTNailPtr = (XMP_Uns8*)this->memStream + tnailImageOffset; } } #if 0 { printf ( "\nExiting TIFF_FileWriter::ParseMemoryStream\n" ); for ( int ifd = 0; ifd < kTIFF_KnownIFDCount; ++ifd ) { InternalIFDInfo & thisIFD = this->containedIFDs[ifd]; printf ( "\n IFD %d, count %d, mapped %d, offset %d (0x%X), next IFD %d (0x%X)\n", ifd, thisIFD.origCount, thisIFD.tagMap.size(), thisIFD.origOffset, thisIFD.origOffset, thisIFD.origNextIFD, thisIFD.origNextIFD ); InternalTagMap::iterator tagPos; InternalTagMap::iterator tagEnd = thisIFD.tagMap.end(); for ( tagPos = thisIFD.tagMap.begin(); tagPos != tagEnd; ++tagPos ) { InternalTagInfo & thisTag = tagPos->second; printf ( " Tag %d, dataOrOffset 0x%X, origLen %d, origOffset %d (0x%X)\n", thisTag.id, thisTag.dataOrOffset, thisTag.origLen, thisTag.origOffset, thisTag.origOffset ); } } printf ( "\n" ); } #endif} // TIFF_FileWriter::ParseMemoryStream// =================================================================================================// TIFF_FileWriter::ProcessMemoryIFD// =================================XMP_Uns32 TIFF_FileWriter::ProcessMemoryIFD ( XMP_Uns32 ifdOffset, XMP_Uns8 ifd ){ InternalIFDInfo& ifdInfo ( this->containedIFDs[ifd] ); if ( (ifdOffset < 8) || (ifdOffset > (this->tiffLength - kEmptyIFDLength)) ) { XMP_Throw ( "Bad IFD offset", kXMPErr_BadTIFF ); } XMP_Uns8* ifdPtr = this->memStream + ifdOffset; XMP_Uns16 tagCount = this->GetUns16 ( ifdPtr ); RawIFDEntry* ifdEntries = (RawIFDEntry*)(ifdPtr+2); if ( tagCount >= 0x8000 ) XMP_Throw ( "Outrageous IFD count", kXMPErr_BadTIFF ); if ( (ifdOffset + 2 + tagCount*12 + 4) > this->tiffLength ) XMP_Throw ( "Out of bounds IFD", kXMPErr_BadTIFF ); ifdInfo.origOffset = ifdOffset; ifdInfo.origCount = tagCount; for ( size_t i = 0; i < tagCount; ++i ) { RawIFDEntry* rawTag = &ifdEntries[i]; InternalTagInfo mapTag ( this->GetUns16(&rawTag->id), this->GetUns16(&rawTag->type), this->GetUns32(&rawTag->count) ); if ( (mapTag.type < kTIFF_ByteType) || (mapTag.type > kTIFF_LastType) ) continue; // Bad type, skip this tag. mapTag.dataLen = mapTag.origLen = mapTag.count * kTIFF_TypeSizes[mapTag.type]; mapTag.dataOrOffset = rawTag->dataOrOffset; // Keep the value or offset in stream byte ordering. if ( mapTag.dataLen <= 4 ) { mapTag.dataPtr = (XMP_Uns8*) &mapTag.dataOrOffset; mapTag.origOffset = ifdOffset + 2 + (12 * i); // Compute the data offset. } else { mapTag.origOffset = this->GetUns32 ( &rawTag->dataOrOffset ); // Extract the data offset. mapTag.dataPtr = this->memStream + mapTag.origOffset; // printf ( "FW_ProcessMemoryIFD tag %d large value @ %.8X\n", mapTag.id, mapTag.dataPtr ); } ifdInfo.tagMap[mapTag.id] = mapTag; } ifdPtr += (2 + tagCount*12); ifdInfo.origNextIFD = this->GetUns32 ( ifdPtr ); return ifdInfo.origNextIFD;} // TIFF_FileWriter::ProcessMemoryIFD// =================================================================================================// CaptureJPEGTNail// ================//// Capture the JPEG image stream for an Exif compressed thumbnail.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -