RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
KdcDecoder.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-2015 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
22#include "decoders/KdcDecoder.h"
23#include "adt/Casts.h"
24#include "adt/NORangesSet.h"
25#include "adt/Point.h"
27#include "common/RawImage.h"
30#include "io/Buffer.h"
31#include "io/ByteStream.h"
32#include "io/Endianness.h"
33#include "metadata/Camera.h"
35#include "tiff/TiffEntry.h"
36#include "tiff/TiffIFD.h"
37#include "tiff/TiffTag.h"
38#include <array>
39#include <cassert>
40#include <cstdint>
41#include <limits>
42#include <memory>
43#include <string>
44
45namespace rawspeed {
46
48 [[maybe_unused]] Buffer file) {
49 const auto id = rootIFD->getID();
50 const std::string& make = id.make;
51
52 // FIXME: magic
53
54 return make == "EASTMAN KODAK COMPANY";
55}
56
58 const TiffEntry* offset =
59 mRootIFD->getEntryRecursive(TiffTag::KODAK_KDC_OFFSET);
60 if (!offset || offset->count < 13)
61 ThrowRDE("Couldn't find the KDC offset");
62
63 assert(offset != nullptr);
64 uint64_t off = uint64_t(offset->getU32(4)) + uint64_t(offset->getU32(12));
65 if (off > std::numeric_limits<uint32_t>::max())
66 ThrowRDE("Offset is too large.");
67
68 // Offset hardcoding gotten from dcraw
69 if (hints.contains("easyshare_offset_hack"))
70 off = off < 0x15000 ? 0x15000 : 0x17000;
71
72 return mFile.getSubView(implicit_cast<Buffer::size_type>(off));
73}
74
76 if (!mRootIFD->hasEntryRecursive(TiffTag::COMPRESSION))
77 ThrowRDE("Couldn't find compression setting");
78
79 if (auto compression =
80 mRootIFD->getEntryRecursive(TiffTag::COMPRESSION)->getU32();
81 7 != compression)
82 ThrowRDE("Unsupported compression %u", compression);
83
84 const TiffEntry* ifdoffset = mRootIFD->getEntryRecursive(TiffTag::KODAK_IFD2);
85 if (!ifdoffset)
86 ThrowRDE("Couldn't find the Kodak IFD offset");
87
89
90 assert(ifdoffset != nullptr);
91 TiffRootIFD kodakifd(nullptr, &ifds, ifdoffset->getRootIfdData(),
92 ifdoffset->getU32());
93
94 const TiffEntry* ew =
96 const TiffEntry* eh =
98 if (!ew || !eh)
99 ThrowRDE("Unable to retrieve image size");
100
101 uint32_t width = ew->getU32();
102 uint32_t height = eh->getU32();
103
104 mRaw->dim = iPoint2D(width, height);
105
106 if (!mRaw->dim.hasPositiveArea() || !(mRaw->dim <= iPoint2D(4304, 3221)))
107 ThrowRDE("Unexpected image dimensions found: (%d; %d)", mRaw->dim.x,
108 mRaw->dim.y);
109
110 const Buffer inputBuffer = KdcDecoder::getInputBuffer();
111
114 iRectangle2D({0, 0}, iPoint2D(width, height)), 12 * width / 8, 12,
116 mRaw->createData();
117 u.readUncompressedRaw();
118
119 return mRaw;
120}
121
123 setMetaData(meta, "", 0);
124
125 // Try the kodak hidden IFD for WB
126 if (mRootIFD->hasEntryRecursive(TiffTag::KODAK_IFD2)) {
127 const TiffEntry* ifdoffset =
128 mRootIFD->getEntryRecursive(TiffTag::KODAK_IFD2);
129 try {
131
132 TiffRootIFD kodakifd(nullptr, &ifds, ifdoffset->getRootIfdData(),
133 ifdoffset->getU32());
134
137 if (wb->count == 3) {
138 std::array<float, 4> wbCoeffs = {};
139 wbCoeffs[0] = wb->getFloat(0);
140 wbCoeffs[1] = wb->getFloat(1);
141 wbCoeffs[2] = wb->getFloat(2);
142 mRaw->metadata.wbCoeffs = wbCoeffs;
143 }
144 }
145 } catch (const TiffParserException& e) {
146 mRaw->setError(e.what());
147 }
148 }
149
150 // Use the normal WB if available
151 if (mRootIFD->hasEntryRecursive(TiffTag::KODAKWB)) {
152 const TiffEntry* wb = mRootIFD->getEntryRecursive(TiffTag::KODAKWB);
153 if (wb->count == 734 || wb->count == 1502) {
154 std::array<float, 4> wbCoeffs = {};
155 wbCoeffs[0] =
156 static_cast<float>(((static_cast<uint16_t>(wb->getByte(148))) << 8) |
157 wb->getByte(149)) /
158 256.0F;
159 wbCoeffs[1] = 1.0F;
160 wbCoeffs[2] =
161 static_cast<float>(((static_cast<uint16_t>(wb->getByte(150))) << 8) |
162 wb->getByte(151)) /
163 256.0F;
164 mRaw->metadata.wbCoeffs = wbCoeffs;
165 }
166 }
167}
168
169} // namespace rawspeed
#define ThrowRDE(...)
assert(dim.area() >=area)
void setMetaData(const CameraMetaData *meta, const TiffID &id, const std::string &mode, int iso_speed)
void decodeMetaDataInternal(const CameraMetaData *meta) override
RawImage decodeRawInternal() override
Buffer getInputBuffer() const
static bool isAppropriateDecoder(const TiffRootIFD *rootIFD, Buffer file)
Definition TiffEntry.h:62
DataBuffer getRootIfdData() const
float getFloat(uint32_t index=0) const
uint32_t getU32(uint32_t index=0) const
uint32_t count
Definition TiffEntry.h:84
uint8_t getByte(uint32_t index=0) const
TiffEntry *RAWSPEED_READONLY getEntryRecursive(TiffTag tag) const
Definition TiffIFD.cpp:246
bool hasEntryRecursive(TiffTag tag) const
Definition TiffIFD.h:122
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