void TiffParser::decode(Image* pImage, const byte* pData, uint32_t size, TiffCompFactoryFct createFct, FindDecoderFct findDecoderFct, TiffHeaderBase* pHeader) { assert(pImage != 0); assert(pData != 0); std::auto_ptr<TiffHeaderBase> ph; if (!pHeader) { ph = std::auto_ptr<TiffHeaderBase>(new TiffHeade2); pHeader = ph.get(); } if (!pHeader->read(pData, size) || pHeader->offset() >= size) { throw Error(3, "TIFF"); } TiffComponent::AutoPtr rootDir = createFct(Tag::root, Group::none); if (0 == rootDir.get()) return; rootDir->setStart(pData + pHeader->offset()); TiffRwState::AutoPtr state( new TiffRwState(pHeader->byteOrder(), 0, createFct)); TiffReader reader(pData, size, rootDir.get(), state); rootDir->accept(reader); TiffMetadataDecoder decoder(pImage, rootDir.get(), findDecoderFct, 4096); rootDir->accept(decoder); } // TiffParser::decode
ByteOrder TiffParserWorker::decode( ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, uint32_t size, TiffCompFactoryFct createFct, FindDecoderFct findDecoderFct, TiffHeaderBase* pHeader ) { // Create standard TIFF header if necessary std::auto_ptr<TiffHeaderBase> ph; if (!pHeader) { ph = std::auto_ptr<TiffHeaderBase>(new TiffHeader); pHeader = ph.get(); } TiffComponent::AutoPtr rootDir = parse(pData, size, createFct, pHeader); if (0 != rootDir.get()) { TiffDecoder decoder(exifData, iptcData, xmpData, rootDir.get(), findDecoderFct); rootDir->accept(decoder); } return pHeader->byteOrder(); } // TiffParserWorker::decode
TiffComponent::AutoPtr TiffParserWorker::parse( const byte* pData, uint32_t size, TiffCompFactoryFct createFct, TiffHeaderBase* pHeader ) { if (pData == 0 || size == 0) return TiffComponent::AutoPtr(0); if (!pHeader->read(pData, size) || pHeader->offset() >= size) { throw Error(3, "TIFF"); } TiffComponent::AutoPtr rootDir = createFct(Tag::root, Group::none); if (0 != rootDir.get()) { rootDir->setStart(pData + pHeader->offset()); TiffRwState::AutoPtr state( new TiffRwState(pHeader->byteOrder(), 0, createFct)); TiffReader reader(pData, size, rootDir.get(), state); rootDir->accept(reader); } return rootDir; } // TiffParserWorker::parse
WriteMethod TiffParserWorker::encode( Blob& blob, const byte* pData, uint32_t size, const ExifData& exifData, const IptcData& iptcData, const XmpData& xmpData, TiffCompFactoryFct createFct, FindEncoderFct findEncoderFct, TiffHeaderBase* pHeader ) { /* 1) parse the binary image, if one is provided, and 2) attempt updating the parsed tree in-place ("non-intrusive writing") 3) else, create a new tree and write a new TIFF structure ("intrusive writing"). If there is a parsed tree, it is only used to access the image data in this case. */ assert(pHeader); assert(pHeader->byteOrder() != invalidByteOrder); blob.clear(); WriteMethod writeMethod = wmIntrusive; TiffComponent::AutoPtr createdTree; TiffComponent::AutoPtr parsedTree = parse(pData, size, createFct, pHeader); if (0 != parsedTree.get()) { // Attempt to update existing TIFF components based on metadata entries TiffEncoder encoder(exifData, iptcData, xmpData, parsedTree.get(), pHeader->byteOrder(), findEncoderFct); parsedTree->accept(encoder); if (!encoder.dirty()) writeMethod = wmNonIntrusive; } if (writeMethod == wmIntrusive) { createdTree = createFct(Tag::root, Group::none); TiffEncoder encoder(exifData, iptcData, xmpData, createdTree.get(), pHeader->byteOrder(), findEncoderFct); // Add entries from metadata to composite encoder.add(createdTree.get(), parsedTree.get(), createFct); // Write binary representation from the composite tree uint32_t offset = pHeader->write(blob); uint32_t imageIdx(uint32_t(-1)); uint32_t len = createdTree->write(blob, pHeader->byteOrder(), offset, uint32_t(-1), uint32_t(-1), imageIdx); // Avoid writing just the header if there is no IFD data if (len == 0) blob.clear(); #ifdef DEBUG std::cerr << "Intrusive writing\n"; #endif } #ifdef DEBUG else { std::cerr << "Non-intrusive writing\n"; } #endif return writeMethod; } // TiffParserWorker::encode