RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
ThreefrDecoder.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5 Copyright (C) 2014 Pedro CĂ´rte-Real
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
23#include "adt/Casts.h"
24#include "adt/Point.h"
26#include "common/RawImage.h"
30#include "io/Buffer.h"
31#include "io/ByteStream.h"
32#include "io/Endianness.h"
34#include "tiff/TiffEntry.h"
35#include "tiff/TiffIFD.h"
36#include "tiff/TiffTag.h"
37#include <array>
38#include <cstdint>
39#include <memory>
40#include <string>
41
42namespace rawspeed {
43
44class CameraMetaData;
45
47 [[maybe_unused]] Buffer file) {
48 const auto id = rootIFD->getID();
49 const std::string& make = id.make;
50
51 // FIXME: magic
52
53 return make == "Hasselblad";
54}
55
57 const auto* raw = mRootIFD->getIFDWithTag(TiffTag::STRIPOFFSETS, 1);
58 uint32_t width = raw->getEntry(TiffTag::IMAGEWIDTH)->getU32();
59 uint32_t height = raw->getEntry(TiffTag::IMAGELENGTH)->getU32();
60 uint32_t compression = raw->getEntry(TiffTag::COMPRESSION)->getU32();
61
62 mRaw->dim = iPoint2D(width, height);
63
64 if (1 == compression) {
66 return mRaw;
67 }
68
69 if (compression != 7) // LJpeg
70 ThrowRDE("Unexpected compression type.");
71
72 uint32_t off = raw->getEntry(TiffTag::STRIPOFFSETS)->getU32();
73 // STRIPBYTECOUNTS is strange/invalid for the existing (compressed?) 3FR
74 // samples...
75
76 const ByteStream bs(DataBuffer(mFile.getSubView(off), Endianness::little));
77
79 mRaw->createData();
80
81 l.decode();
82
83 return mRaw;
84}
85
87 if (mRaw->getDataType() != RawImageType::UINT16)
88 ThrowRDE("Unexpected data type");
89
90 if (mRaw->getCpp() != 1 || mRaw->getBpp() != sizeof(uint16_t))
91 ThrowRDE("Unexpected cpp: %u", mRaw->getCpp());
92
93 // FIXME: could be wrong. max "active pixels" - "100 MP"
94 if (!mRaw->dim.hasPositiveArea() || mRaw->dim.x % 2 != 0 ||
95 mRaw->dim.x > 12000 || mRaw->dim.y > 8842) {
96 ThrowRDE("Unexpected image dimensions found: (%d; %d)", mRaw->dim.x,
97 mRaw->dim.y);
98 }
99
101 // STRIPBYTECOUNTS looks valid for the existing uncompressed 3FR samples
103
104 const ByteStream bs(
105 DataBuffer(mFile.getSubView(off, count), Endianness::little));
106
107 UncompressedDecompressor u(bs, mRaw, iRectangle2D({0, 0}, mRaw->dim),
108 2 * mRaw->dim.x, 16, BitOrder::LSB);
109 mRaw->createData();
110 u.readUncompressedRaw();
111}
112
114 mRaw->cfa.setCFA(iPoint2D(2, 2), CFAColor::RED, CFAColor::GREEN,
116
117 setMetaData(meta, "", 0);
118
119 if (mRootIFD->hasEntryRecursive(TiffTag::BLACKLEVEL)) {
120 const TiffEntry* bl = mRootIFD->getEntryRecursive(TiffTag::BLACKLEVEL);
121 if (bl->count == 1)
122 mRaw->blackLevel = implicit_cast<int>(bl->getFloat());
123 }
124
125 if (mRootIFD->hasEntryRecursive(TiffTag::WHITELEVEL)) {
126 const TiffEntry* wl = mRootIFD->getEntryRecursive(TiffTag::WHITELEVEL);
127 if (wl->count == 1)
128 mRaw->whitePoint = implicit_cast<int>(wl->getFloat());
129 }
130
131 // Fetch the white balance
132 if (mRootIFD->hasEntryRecursive(TiffTag::ASSHOTNEUTRAL)) {
133 const TiffEntry* wb = mRootIFD->getEntryRecursive(TiffTag::ASSHOTNEUTRAL);
134 if (wb->count == 3) {
135 std::array<float, 4> wbCoeffs = {};
136 for (uint32_t i = 0; i < 3; i++) {
137 const float div = wb->getFloat(i);
138 if (div == 0.0F)
139 ThrowRDE("Can not decode WB, multiplier is zero/");
140
141 wbCoeffs[i] = 1.0F / div;
142 }
143 mRaw->metadata.wbCoeffs = wbCoeffs;
144 }
145 }
146}
147
148} // namespace rawspeed
#define ThrowRDE(...)
void setMetaData(const CameraMetaData *meta, const TiffID &id, const std::string &mode, int iso_speed)
void DecodeUncompressed(const TiffIFD *raw) const
void decodeMetaDataInternal(const CameraMetaData *meta) override
static bool isAppropriateDecoder(const TiffRootIFD *rootIFD, Buffer file)
RawImage decodeRawInternal() override
Definition TiffEntry.h:62
float getFloat(uint32_t index=0) const
uint32_t getU32(uint32_t index=0) const
uint32_t count
Definition TiffEntry.h:84
TiffEntry * getEntry(TiffTag tag) const
Definition TiffIFD.cpp:313
TiffID getID() const
Definition TiffIFD.cpp:325
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
std::string make
Definition TiffIFD.h:134