| 103 | } // WebPImage::writeMetadata |
| 104 | |
| 105 | void WebPImage::doWriteMetadata(BasicIo& outIo) { |
| 106 | if (!io_->isopen()) |
| 107 | throw Error(ErrorCode::kerInputDataReadFailed); |
| 108 | if (!outIo.isopen()) |
| 109 | throw Error(ErrorCode::kerImageWriteFailed); |
| 110 | |
| 111 | #ifdef EXIV2_DEBUG_MESSAGES |
| 112 | std::cout << "Writing metadata" << std::endl; |
| 113 | #endif |
| 114 | |
| 115 | byte data[WEBP_TAG_SIZE * 3]; |
| 116 | DataBuf chunkId(WEBP_TAG_SIZE + 1); |
| 117 | chunkId.write_uint8(WEBP_TAG_SIZE, '\0'); |
| 118 | |
| 119 | io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::ErrorCode::kerCorruptedMetadata); |
| 120 | uint64_t filesize = Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian); |
| 121 | |
| 122 | /* Set up header */ |
| 123 | if (outIo.write(data, WEBP_TAG_SIZE * 3) != WEBP_TAG_SIZE * 3) |
| 124 | throw Error(ErrorCode::kerImageWriteFailed); |
| 125 | |
| 126 | /* Parse Chunks */ |
| 127 | bool has_size = false; |
| 128 | bool has_xmp = false; |
| 129 | bool has_exif = false; |
| 130 | bool has_vp8x = false; |
| 131 | bool has_alpha = false; |
| 132 | bool has_icc = iccProfileDefined(); |
| 133 | |
| 134 | uint32_t width = 0; |
| 135 | uint32_t height = 0; |
| 136 | |
| 137 | byte size_buff[WEBP_TAG_SIZE]; |
| 138 | Blob blob; |
| 139 | |
| 140 | if (!exifData_.empty()) { |
| 141 | ExifParser::encode(blob, littleEndian, exifData_); |
| 142 | if (!blob.empty()) { |
| 143 | has_exif = true; |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | if (!xmpData_.empty() && !writeXmpFromPacket()) { |
| 148 | XmpParser::encode(xmpPacket_, xmpData_, XmpParser::useCompactFormat | XmpParser::omitAllFormatting); |
| 149 | } |
| 150 | has_xmp = !xmpPacket_.empty(); |
| 151 | std::string xmp(xmpPacket_); |
| 152 | |
| 153 | /* Verify for a VP8X Chunk First before writing in |
| 154 | case we have any exif or xmp data, also check |
| 155 | for any chunks with alpha frame/layer set */ |
| 156 | while (!io_->eof() && io_->tell() < filesize) { |
| 157 | io_->readOrThrow(chunkId.data(), WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata); |
| 158 | io_->readOrThrow(size_buff, WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata); |
| 159 | const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian); |
| 160 | |
| 161 | // Check that `size_u32` is within bounds. |
| 162 | Internal::enforce(size_u32 <= io_->size() - io_->tell(), Exiv2::ErrorCode::kerCorruptedMetadata); |
nothing calls this directly
no test coverage detected