54 [[maybe_unused]]
Buffer file) {
55 const auto id = rootIFD->
getID();
56 const std::string& make =
id.
make;
60 return make ==
"OLYMPUS IMAGING CORP." || make ==
"OLYMPUS CORPORATION" ||
61 make ==
"OLYMPUS OPTICAL CO.,LTD" || make ==
"OM Digital Solutions";
72 "Byte count number does not match strip size: count:%u, strips:%u ",
78 auto end = [&off, &size]() {
return off + size; };
81 const auto offset = offsets->
getU32(i);
82 const auto count = counts->
getU32(i);
83 if (!
mFile.isValid(offset, count))
98 const uint32_t padding = offset - end();
115 ThrowRDE(
"Unsupported compression");
120 if (!width || !height || width % 2 != 0 || width > 10400 || height > 7796)
121 ThrowRDE(
"Unexpected image dimensions found: (%u; %u)", width, height);
131 ThrowRDE(
"%u stripes, and not uncompressed. Unsupported.",
136 }
else if (bitsPerPixel == 14) {
139 ThrowRDE(
"%i-bit images are not supported currently.", bitsPerPixel);
164 result = validBits->
getU16();
173 int inputPitchBits = 12 * w;
174 assert(inputPitchBits % 8 == 0);
176 int inputPitchBytes = inputPitchBits / 8;
179 const auto evenLinesInput =
s.getStream(numEvenLines, inputPitchBytes)
180 .peekRemainingBuffer()
183 const auto oddLinesInputBegin =
185 assert(oddLinesInputBegin >= evenLinesInput.size());
186 int padding = oddLinesInputBegin - evenLinesInput.size();
188 s.skipBytes(padding);
190 const int numOddLines = h - numEvenLines;
191 const auto oddLinesInput =
s.getStream(numOddLines, inputPitchBytes)
192 .peekRemainingBuffer()
201 for (
int i = 0; i != numEvenLines; ++i) {
202 for (
unsigned col = 0; col != w; ++col) {
210 for (
int i = 0; i != numOddLines; ++i) {
211 for (
unsigned col = 0; col != w; ++col) {
212 int row = 1 + (2 * i);
224 if (size == h * ((w * 12 / 8) + ((w + 2) / 10))) {
227 (12 * w / 8) + ((w + 2) / 10), 12,
236 if (size == w * h * 12 / 8) {
240 u.readUncompressedRaw();
244 if (size == w * h * 2) {
260 if (size > w * h * 3 / 2) {
272 ThrowRDE(
"No EXIFCFAPATTERN entry found!");
276 ThrowRDE(
"Bad EXIFCFAPATTERN entry (type %u, count %u).",
277 static_cast<unsigned>(CFA->
type), CFA->
count);
282 ThrowRDE(
"Bad CFA size: (%i, %i)", cfaSize.
x, cfaSize.
y);
284 mRaw->cfa.setSize(cfaSize);
286 auto int2enum = [](uint8_t i) {
296 ThrowRDE(
"Unexpected CFA color: %u", i);
300 for (
int y = 0;
y < cfaSize.
y;
y++) {
301 for (
int x = 0;
x < cfaSize.
x;
x++) {
302 uint8_t c1 = CFA->
getByte(4 +
x + (
y * cfaSize.
x));
310 mRaw->whitePoint = (1U << 12) - 1;
323 std::array<float, 4> wbCoeffs = {};
324 wbCoeffs[0] =
static_cast<float>(
326 wbCoeffs[1] = 256.0F;
327 wbCoeffs[2] =
static_cast<float>(
329 mRaw->metadata.wbCoeffs = wbCoeffs;
345 std::array<float, 4> wbCoeffs = {};
347 wbCoeffs[1] = 256.0F;
349 mRaw->metadata.wbCoeffs = wbCoeffs;
358 if (blackEntry->
count == 4) {
359 mRaw->blackLevelSeparate =
361 auto blackLevelSeparate1D =
362 *
mRaw->blackLevelSeparate->getAsArray1DRef();
363 for (
int i = 0; i < 4; i++) {
364 auto c =
mRaw->cfa.getColorAt(i & 1, i >> 1);
378 ThrowRDE(
"Unexpected CFA color: %u",
static_cast<unsigned>(c));
381 blackLevelSeparate1D(i) = blackEntry->
getU16(j);
386 *
mRaw->whitePoint - (
mRaw->blackLevel - blackLevelSeparate1D(0));
388 mRaw->whitePoint = *
mRaw->whitePoint * 4;
389 mRaw->blackLevel =
mRaw->blackLevel * 4;
390 for (
int i = 0; i < 4; i++) {
391 blackLevelSeparate1D(i) = blackLevelSeparate1D(i) * 4;
assert(dim.area() >=area)
void setMetaData(const CameraMetaData *meta, const TiffID &id, const std::string &mode, int iso_speed)
TiffRootIFDOwner mRootIFD
uint32_t getBits(int nbits)
size_type RAWSPEED_READONLY getSize() const
void setPosition(size_type newPos)
ByteStream getStream(size_type size_)
void skipBytes(size_type nbytes)
void decompress(const ByteStream &input) const
RawImage decodeRawInternal() override
void decodeUncompressedInterleaved(ByteStream s, uint32_t w, uint32_t h, uint32_t size) const
void decodeMetaDataInternal(const CameraMetaData *meta) override
ByteStream handleSlices() const
bool decodeUncompressed(ByteStream s, uint32_t w, uint32_t h, uint32_t size) const
int getBitsPerPixel() const
static bool isAppropriateDecoder(const TiffRootIFD *rootIFD, Buffer file)
DataBuffer getRootIfdData() const
float getFloat(uint32_t index=0) const
uint32_t getU32(uint32_t index=0) const
uint16_t getU16(uint32_t index=0) const
uint8_t getByte(uint32_t index=0) const
bool RAWSPEED_READONLY hasEntry(TiffTag tag) const
TiffEntry * getEntry(TiffTag tag) const
constexpr uint64_t RAWSPEED_READNONE roundUpDivisionSafe(uint64_t value, uint64_t div)
constexpr uint64_t RAWSPEED_READNONE roundUp(uint64_t value, uint64_t multiple)
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Array2DRef(Array1DRef< T > data, int width, int height, int pitch) -> Array2DRef< T >
Endianness getHostEndianness()