| 222 | } // RafImage::printStructure |
| 223 | |
| 224 | void RafImage::readMetadata() { |
| 225 | #ifdef EXIV2_DEBUG_MESSAGES |
| 226 | std::cerr << "Reading RAF file " << io_->path() << "\n"; |
| 227 | #endif |
| 228 | if (io_->open() != 0) |
| 229 | throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError()); |
| 230 | IoCloser closer(*io_); |
| 231 | // Ensure that this is the correct image type |
| 232 | if (!isRafType(*io_, false)) { |
| 233 | if (io_->error() || io_->eof()) |
| 234 | throw Error(ErrorCode::kerFailedToReadImageData); |
| 235 | throw Error(ErrorCode::kerNotAnImage, "RAF"); |
| 236 | } |
| 237 | |
| 238 | clearMetadata(); |
| 239 | |
| 240 | if (io_->seek(84, BasicIo::beg) != 0) |
| 241 | throw Error(ErrorCode::kerFailedToReadImageData); |
| 242 | byte jpg_img_offset[4]; |
| 243 | if (io_->read(jpg_img_offset, 4) != 4) |
| 244 | throw Error(ErrorCode::kerFailedToReadImageData); |
| 245 | byte jpg_img_length[4]; |
| 246 | if (io_->read(jpg_img_length, 4) != 4) |
| 247 | throw Error(ErrorCode::kerFailedToReadImageData); |
| 248 | uint32_t jpg_img_off_u32 = Exiv2::getULong(jpg_img_offset, bigEndian); |
| 249 | uint32_t jpg_img_len_u32 = Exiv2::getULong(jpg_img_length, bigEndian); |
| 250 | |
| 251 | Internal::enforce(Safe::add(jpg_img_off_u32, jpg_img_len_u32) <= io_->size(), ErrorCode::kerCorruptedMetadata); |
| 252 | |
| 253 | auto jpg_img_off = static_cast<long>(jpg_img_off_u32); |
| 254 | auto jpg_img_len = static_cast<long>(jpg_img_len_u32); |
| 255 | |
| 256 | Internal::enforce(jpg_img_len >= 12, ErrorCode::kerCorruptedMetadata); |
| 257 | |
| 258 | DataBuf jpg_buf(jpg_img_len); |
| 259 | if (io_->seek(jpg_img_off, BasicIo::beg) != 0) |
| 260 | throw Error(ErrorCode::kerFailedToReadImageData); |
| 261 | |
| 262 | if (!jpg_buf.empty()) { |
| 263 | io_->read(jpg_buf.data(), jpg_buf.size()); |
| 264 | if (io_->error() || io_->eof()) |
| 265 | throw Error(ErrorCode::kerFailedToReadImageData); |
| 266 | } |
| 267 | |
| 268 | // Retrieve metadata from embedded JPEG preview image. |
| 269 | try { |
| 270 | auto jpg_io = std::make_unique<Exiv2::MemIo>(jpg_buf.data(), jpg_buf.size()); |
| 271 | auto jpg_img = JpegImage(std::move(jpg_io), false); |
| 272 | jpg_img.readMetadata(); |
| 273 | setByteOrder(jpg_img.byteOrder()); |
| 274 | xmpData_ = jpg_img.xmpData(); |
| 275 | exifData_ = jpg_img.exifData(); |
| 276 | iptcData_ = jpg_img.iptcData(); |
| 277 | comment_ = jpg_img.comment(); |
| 278 | } catch (const Exiv2::Error&) { |
| 279 | } |
| 280 | |
| 281 | exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian); |
nothing calls this directly
no test coverage detected