Coverage Report

Created: 2026-08-25 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/src/orfimage.cpp
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
// included header files
4
#include "orfimage.hpp"
5
6
#include "basicio.hpp"
7
#include "config.h"
8
#include "error.hpp"
9
#include "futils.hpp"
10
#include "image.hpp"
11
#include "orfimage_int.hpp"
12
#include "tags.hpp"
13
#include "tiffcomposite_int.hpp"
14
#include "tiffimage.hpp"
15
#include "tiffimage_int.hpp"
16
17
#include <iostream>
18
19
// *****************************************************************************
20
// class member definitions
21
namespace Exiv2 {
22
using namespace Internal;
23
24
OrfImage::OrfImage(BasicIo::UniquePtr io, const ImageCtorParams& params) :
25
41
    TiffImage(/*ImageType::orf, mdExif | mdIptc | mdXmp,*/ std::move(io), params) {
26
41
  setTypeSupported(ImageType::orf, mdExif | mdIptc | mdXmp);
27
41
}  // OrfImage::OrfImage
28
29
0
std::string OrfImage::mimeType() const {
30
0
  return "image/x-olympus-orf";
31
0
}
32
33
45
uint32_t OrfImage::pixelWidth() const {
34
45
  auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth"));
35
45
  if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
36
11
    return imageWidth->toUint32();
37
11
  }
38
34
  return 0;
39
45
}
40
41
47
uint32_t OrfImage::pixelHeight() const {
42
47
  auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageLength"));
43
47
  if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
44
12
    return imageHeight->toUint32();
45
12
  }
46
35
  return 0;
47
47
}
48
49
0
void OrfImage::setComment(const std::string&) {
50
  // not supported
51
0
  throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "ORF"));
52
0
}
53
54
0
void OrfImage::printStructure(std::ostream& out, PrintStructureOption option, size_t depth) {
55
0
  out << "ORF IMAGE" << '\n';
56
0
  if (io_->open() != 0)
57
0
    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
58
  // Ensure that this is the correct image type
59
0
  if (imageType() == ImageType::none && !isOrfType(*io_, false)) {
60
0
    if (io_->error() || io_->eof())
61
0
      throw Error(ErrorCode::kerFailedToReadImageData);
62
0
    throw Error(ErrorCode::kerNotAJpeg);
63
0
  }
64
65
0
  io_->seek(0, BasicIo::beg);
66
67
0
  printTiffStructure(io(), out, option, depth);
68
0
}  // OrfImage::printStructure
69
70
41
void OrfImage::readMetadata() {
71
#ifdef EXIV2_DEBUG_MESSAGES
72
  std::cerr << "Reading ORF file " << io_->path() << "\n";
73
#endif
74
41
  if (io_->open() != 0) {
75
0
    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
76
0
  }
77
41
  IoCloser closer(*io_);
78
  // Ensure that this is the correct image type
79
41
  if (!isOrfType(*io_, false)) {
80
0
    if (io_->error() || io_->eof())
81
0
      throw Error(ErrorCode::kerFailedToReadImageData);
82
0
    throw Error(ErrorCode::kerNotAnImage, "ORF");
83
0
  }
84
41
  clearMetadata();
85
41
  const DecodeParams dp(max_recursion_depth_);
86
41
  ByteOrder bo = OrfParser::decode(exifData_, iptcData_, xmpData_, io_->mmap(), io_->size(), dp);
87
41
  setByteOrder(bo);
88
41
}
89
90
0
void OrfImage::writeMetadata() {
91
#ifdef EXIV2_DEBUG_MESSAGES
92
  std::cerr << "Writing ORF file " << io_->path() << "\n";
93
#endif
94
0
  ByteOrder bo = byteOrder();
95
0
  const byte* pData = nullptr;
96
0
  size_t size = 0;
97
0
  IoCloser closer(*io_);
98
  // Ensure that this is the correct image type
99
0
  if (io_->open() == 0 && isOrfType(*io_, false)) {
100
0
    pData = io_->mmap(true);
101
0
    size = io_->size();
102
0
    OrfHeader orfHeader;
103
0
    if (0 == orfHeader.read(pData, 8)) {
104
0
      bo = orfHeader.byteOrder();
105
0
    }
106
0
  }
107
0
  if (bo == invalidByteOrder) {
108
0
    bo = littleEndian;
109
0
  }
110
0
  setByteOrder(bo);
111
0
  OrfParser::encode(*io_, pData, size, bo, exifData_, iptcData_, xmpData_);  // may throw
112
0
}  // OrfImage::writeMetadata
113
114
ByteOrder OrfParser::decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size,
115
41
                            const DecodeParams& dp) {
116
41
  OrfHeader orfHeader;
117
41
  return TiffParserWorker::decode(exifData, iptcData, xmpData, pData, size, Tag::root, TiffMapping::findDecoder, dp,
118
41
                                  &orfHeader);
119
41
}
120
121
WriteMethod OrfParser::encode(BasicIo& io, const byte* pData, size_t size, ByteOrder byteOrder, ExifData& exifData,
122
0
                              const IptcData& iptcData, const XmpData& xmpData) {
123
  // Delete IFDs which do not occur in TIFF images
124
0
  static constexpr auto filteredIfds = {
125
0
      IfdId::panaRawId,
126
0
  };
127
0
  for (auto&& filteredIfd : filteredIfds) {
128
#ifdef EXIV2_DEBUG_MESSAGES
129
    std::cerr << "Warning: Exif IFD " << filteredIfd << " not encoded\n";
130
#endif
131
0
    exifData.erase(std::remove_if(exifData.begin(), exifData.end(), FindExifdatum(filteredIfd)), exifData.end());
132
0
  }
133
134
0
  OrfHeader header(byteOrder);
135
0
  return TiffParserWorker::encode(io, pData, size, exifData, iptcData, xmpData, Tag::root, TiffMapping::findEncoder,
136
0
                                  &header, nullptr);
137
0
}
138
139
// *************************************************************************
140
// free functions
141
41
Image::UniquePtr newOrfInstance(BasicIo::UniquePtr io, const ImageCtorParams& params) {
142
41
  auto image = std::make_unique<OrfImage>(std::move(io), params);
143
41
  if (!image->good()) {
144
0
    return nullptr;
145
0
  }
146
41
  return image;
147
41
}
148
149
4.03k
bool isOrfType(BasicIo& iIo, bool advance) {
150
4.03k
  const int32_t len = 8;
151
4.03k
  byte buf[len];
152
4.03k
  iIo.read(buf, len);
153
4.03k
  if (iIo.error() || iIo.eof()) {
154
0
    return false;
155
0
  }
156
4.03k
  OrfHeader orfHeader;
157
4.03k
  bool rc = orfHeader.read(buf, len);
158
4.03k
  if (!advance || !rc) {
159
4.03k
    iIo.seek(-len, BasicIo::cur);
160
4.03k
  }
161
4.03k
  return rc;
162
4.03k
}
163
164
}  // namespace Exiv2