TiffComponent* newNikonMn(uint16_t tag, IfdId group, IfdId /*mnGroup*/, const byte* pData, uint32_t size, ByteOrder /*byteOrder*/) { // If there is no "Nikon" string it must be Nikon1 format if (size < 6 || std::string(reinterpret_cast<const char*>(pData), 6) != std::string("Nikon\0", 6)) { // Require at least an IFD with 1 entry if (size < 18) return 0; return newIfdMn2(tag, group, nikon1Id); } // If the "Nikon" string is not followed by a TIFF header, we assume // Nikon2 format TiffHeader tiffHeader; if ( size < 18 || !tiffHeader.read(pData + 10, size - 10) || tiffHeader.tag() != 0x002a) { // Require at least the header and an IFD with 1 entry if (size < Nikon2MnHeader::sizeOfSignature() + 18) return 0; return newNikon2Mn2(tag, group, nikon2Id); } // Else we have a Nikon3 makernote // Require at least the header and an IFD with 1 entry if (size < Nikon3MnHeader::sizeOfSignature() + 18) return 0; return newNikon3Mn2(tag, group, nikon3Id); }
void TiffImage::writeMetadata() { #ifdef DEBUG std::cerr << "Writing TIFF file " << io_->path() << "\n"; #endif // Read existing image ByteOrder bo = byteOrder(); DataBuf buf; if (io_->open() == 0) { IoCloser closer(*io_); // Ensure that this is the correct image type if (isTiffType(*io_, false)) { // Read the image into a memory buffer buf.alloc(io_->size()); io_->read(buf.pData_, buf.size_); if (io_->error() || io_->eof()) { buf.reset(); } TiffHeader tiffHeader; if (0 == tiffHeader.read(buf.pData_, 8)) { bo = tiffHeader.byteOrder(); } } } if (bo == invalidByteOrder) { bo = littleEndian; } setByteOrder(bo); Blob blob; WriteMethod wm = TiffParser::encode(blob, buf.pData_, buf.size_, bo, exifData_, iptcData_, xmpData_); // Write updated or new buffer to file BasicIo::AutoPtr tempIo(io_->temporary()); // may throw assert(tempIo.get() != 0); if (wm == wmNonIntrusive) { // Buffer may be modified but size is unchanged, write buffer back tempIo->write(buf.pData_, buf.size_); } else { // Size of the buffer changed, write from blob tempIo->write(&blob[0], static_cast<long>(blob.size())); } io_->close(); io_->transfer(*tempIo); // may throw } // TiffImage::writeMetadata
bool Nikon3MnHeader::read(const byte* pData, uint32_t size, ByteOrder /*byteOrder*/) { if (!pData || size < sizeOfSignature()) return false; if (0 != memcmp(pData, signature_, 6)) return false; buf_.alloc(sizeOfSignature()); std::memcpy(buf_.pData_, pData, buf_.size_); TiffHeader th; if (!th.read(buf_.pData_ + 10, 8)) return false; byteOrder_ = th.byteOrder(); start_ = 10 + th.offset(); return true; } // Nikon3MnHeader::read
int Nikon3MakerNote::readHeader(const byte* buf, long len, ByteOrder byteOrder) { if (len < 18) return 1; header_.alloc(18); memcpy(header_.pData_, buf, header_.size_); TiffHeader tiffHeader; tiffHeader.read(header_.pData_ + 10); byteOrder_ = tiffHeader.byteOrder(); start_ = 10 + tiffHeader.offset(); shift_ = 10; return 0; }
bool isTiffType(BasicIo& iIo, bool advance) { const int32_t len = 8; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } TiffHeader tiffHeader; bool rc = tiffHeader.read(buf, len); if (!advance || !rc) { iIo.seek(-len, BasicIo::cur); } return rc; }
MakerNote::AutoPtr createNikonMakerNote(bool alloc, const byte* buf, long len, ByteOrder byteOrder, long offset) { // If there is no "Nikon" string it must be Nikon1 format if (len < 6 || std::string(reinterpret_cast<const char*>(buf), 6) != std::string("Nikon\0", 6)) { return MakerNote::AutoPtr(new Nikon1MakerNote(alloc)); } // If the "Nikon" string is not followed by a TIFF header, we assume // Nikon2 format TiffHeader tiffHeader; if ( len < 18 || tiffHeader.read(buf + 10) != 0 || tiffHeader.tag() != 0x002a) { return MakerNote::AutoPtr(new Nikon2MakerNote(alloc)); } // Else we have a Nikon3 makernote return MakerNote::AutoPtr(new Nikon3MakerNote(alloc)); }
TiffComponent* newNikonMn(uint16_t tag, uint16_t group, uint16_t /*mnGroup*/, const byte* pData, uint32_t size, ByteOrder /*byteOrder*/) { // If there is no "Nikon" string it must be Nikon1 format if (size < 6 || std::string(reinterpret_cast<const char*>(pData), 6) != std::string("Nikon\0", 6)) { return newIfdMn2(tag, group, Group::nikon1mn); } // If the "Nikon" string is not followed by a TIFF header, we assume // Nikon2 format TiffHeader tiffHeader; if ( size < 18 || !tiffHeader.read(pData + 10, size - 10) || tiffHeader.tag() != 0x002a) { return newNikon2Mn2(tag, group, Group::nikon2mn); } // Else we have a Nikon3 makernote return newNikon3Mn2(tag, group, Group::nikon3mn); }