| 2043 | } // TiffParserWorker::decode |
| 2044 | |
| 2045 | WriteMethod TiffParserWorker::encode(BasicIo& io, const byte* pData, size_t size, ExifData& exifData, |
| 2046 | IptcData& iptcData, XmpData& xmpData, uint32_t root, FindEncoderFct findEncoderFct, |
| 2047 | TiffHeaderBase* pHeader, OffsetWriter* pOffsetWriter) { |
| 2048 | /* |
| 2049 | 1) parse the binary image, if one is provided, and |
| 2050 | 2) attempt updating the parsed tree in-place ("non-intrusive writing") |
| 2051 | 3) else, create a new tree and write a new TIFF structure ("intrusive |
| 2052 | writing"). If there is a parsed tree, it is only used to access the |
| 2053 | image data in this case. |
| 2054 | */ |
| 2055 | WriteMethod writeMethod = wmIntrusive; |
| 2056 | auto parsedTree = parse(pData, size, root, pHeader); |
| 2057 | auto primaryGroups = findPrimaryGroups(parsedTree.get()); |
| 2058 | if (parsedTree) { |
| 2059 | // Attempt to update existing TIFF components based on metadata entries |
| 2060 | TiffEncoder encoder(exifData, iptcData, xmpData, parsedTree.get(), false, &primaryGroups, pHeader, findEncoderFct); |
| 2061 | parsedTree->accept(encoder); |
| 2062 | if (!encoder.dirty()) |
| 2063 | writeMethod = wmNonIntrusive; |
| 2064 | } |
| 2065 | if (writeMethod == wmIntrusive) { |
| 2066 | auto createdTree = TiffCreator::create(root, IfdId::ifdIdNotSet); |
| 2067 | if (parsedTree) { |
| 2068 | // Copy image tags from the original image to the composite |
| 2069 | TiffCopier copier(createdTree.get(), root, pHeader, &primaryGroups); |
| 2070 | parsedTree->accept(copier); |
| 2071 | } |
| 2072 | // Add entries from metadata to composite |
| 2073 | TiffEncoder encoder(exifData, iptcData, xmpData, createdTree.get(), !parsedTree, &primaryGroups, pHeader, |
| 2074 | findEncoderFct); |
| 2075 | encoder.add(createdTree.get(), parsedTree.get(), root); |
| 2076 | // Write binary representation from the composite tree |
| 2077 | DataBuf header = pHeader->write(); |
| 2078 | auto tempIo = MemIo(); |
| 2079 | IoWrapper ioWrapper(tempIo, header.c_data(), header.size(), pOffsetWriter); |
| 2080 | auto imageIdx(std::string::npos); |
| 2081 | createdTree->write(ioWrapper, pHeader->byteOrder(), header.size(), std::string::npos, std::string::npos, imageIdx); |
| 2082 | if (pOffsetWriter) |
| 2083 | pOffsetWriter->writeOffsets(tempIo); |
| 2084 | io.transfer(tempIo); // may throw |
| 2085 | #ifndef SUPPRESS_WARNINGS |
| 2086 | EXV_INFO << "Write strategy: Intrusive\n"; |
| 2087 | #endif |
| 2088 | } |
| 2089 | #ifndef SUPPRESS_WARNINGS |
| 2090 | else { |
| 2091 | EXV_INFO << "Write strategy: Non-intrusive\n"; |
| 2092 | } |
| 2093 | #endif |
| 2094 | return writeMethod; |
| 2095 | } // TiffParserWorker::encode |
| 2096 | |
| 2097 | TiffComponent::UniquePtr TiffParserWorker::parse(const byte* pData, size_t size, uint32_t root, |
| 2098 | TiffHeaderBase* pHeader) { |