RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
PefDecoder.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) 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/PefDecoder.h"
23#include "adt/Array1DRef.h"
24#include "adt/Array2DRef.h"
25#include "adt/Casts.h"
26#include "adt/Optional.h"
27#include "adt/Point.h"
29#include "common/Common.h"
30#include "common/RawImage.h"
33#include "io/Buffer.h"
34#include "io/ByteStream.h"
35#include "io/Endianness.h"
37#include "tiff/TiffEntry.h"
38#include "tiff/TiffIFD.h"
39#include "tiff/TiffTag.h"
40#include <array>
41#include <cstdint>
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 == "PENTAX Corporation" ||
55 make == "RICOH IMAGING COMPANY, LTD." || make == "PENTAX" ||
56 make == "SAMSUNG TECHWIN";
57}
58
60 const auto* raw = mRootIFD->getIFDWithTag(TiffTag::STRIPOFFSETS);
61
62 int compression = raw->getEntry(TiffTag::COMPRESSION)->getU32();
63
64 if (1 == compression || compression == 32773) {
66 return mRaw;
67 }
68
69 if (65535 != compression)
70 ThrowRDE("Unsupported compression");
71
72 if (raw->hasEntry(TiffTag::PHOTOMETRICINTERPRETATION)) {
73 mRaw->isCFA =
74 (raw->getEntry(TiffTag::PHOTOMETRICINTERPRETATION)->getU16() != 34892);
75 }
76
77 if (mRaw->isCFA)
78 writeLog(DEBUG_PRIO::EXTRA, "This is a CFA image");
79 else {
80 writeLog(DEBUG_PRIO::EXTRA, "This is NOT a CFA image");
81 }
82
83 const TiffEntry* offsets = raw->getEntry(TiffTag::STRIPOFFSETS);
84 const TiffEntry* counts = raw->getEntry(TiffTag::STRIPBYTECOUNTS);
85
86 if (offsets->count != 1) {
87 ThrowRDE("Multiple Strips found: %u", offsets->count);
88 }
89 if (counts->count != offsets->count) {
91 "Byte count number does not match strip size: count:%u, strips:%u ",
92 counts->count, offsets->count);
93 }
94 ByteStream bs(
95 DataBuffer(mFile.getSubView(offsets->getU32(), counts->getU32()),
97
98 uint32_t width = raw->getEntry(TiffTag::IMAGEWIDTH)->getU32();
99 uint32_t height = raw->getEntry(TiffTag::IMAGELENGTH)->getU32();
100
101 mRaw->dim = iPoint2D(width, height);
102
103 Optional<ByteStream> metaData;
104 if (getRootIFD()->hasEntryRecursive(static_cast<TiffTag>(0x220))) {
105 /* Attempt to read huffman table, if found in makernote */
106 const TiffEntry* t =
107 getRootIFD()->getEntryRecursive(static_cast<TiffTag>(0x220));
109 ThrowRDE("Unknown Huffman table type.");
110
111 metaData = t->getData();
112 }
113
114 PentaxDecompressor p(mRaw, metaData);
115 mRaw->createData();
116 p.decompress(bs);
117
118 return mRaw;
119}
120
122 int iso = 0;
123 mRaw->cfa.setCFA(iPoint2D(2, 2), CFAColor::RED, CFAColor::GREEN,
125
126 if (mRootIFD->hasEntryRecursive(TiffTag::ISOSPEEDRATINGS))
127 iso = mRootIFD->getEntryRecursive(TiffTag::ISOSPEEDRATINGS)->getU32();
128
129 setMetaData(meta, "", iso);
130
131 // Read black level
132 if (mRootIFD->hasEntryRecursive(static_cast<TiffTag>(0x200))) {
133 const TiffEntry* black =
134 mRootIFD->getEntryRecursive(static_cast<TiffTag>(0x200));
135 if (black->count == 4) {
136 mRaw->blackLevelSeparate =
137 Array2DRef(mRaw->blackLevelSeparateStorage.data(), 2, 2);
138 auto blackLevelSeparate1D = *mRaw->blackLevelSeparate->getAsArray1DRef();
139 for (int i = 0; i < 4; i++)
140 blackLevelSeparate1D(i) = black->getU32(i);
141 }
142 }
143
144 // Set the whitebalance
145 if (mRootIFD->hasEntryRecursive(static_cast<TiffTag>(0x0201))) {
146 const TiffEntry* wb =
147 mRootIFD->getEntryRecursive(static_cast<TiffTag>(0x0201));
148 if (wb->count == 4) {
149 std::array<float, 4> wbCoeffs = {};
150 wbCoeffs[0] = implicit_cast<float>(wb->getU32(0));
151 wbCoeffs[1] = implicit_cast<float>(wb->getU32(1));
152 wbCoeffs[2] = implicit_cast<float>(wb->getU32(3));
153 mRaw->metadata.wbCoeffs = wbCoeffs;
154 }
155 }
156}
157
158} // namespace rawspeed
#define ThrowRDE(...)
void setMetaData(const CameraMetaData *meta, const TiffID &id, const std::string &mode, int iso_speed)
static bool isAppropriateDecoder(const TiffRootIFD *rootIFD, Buffer file)
RawImage decodeRawInternal() override
void decodeMetaDataInternal(const CameraMetaData *meta) override
void decodeUncompressed(const TiffIFD *rawIFD, BitOrder order) const
Definition TiffEntry.h:62
uint32_t getU32(uint32_t index=0) const
ByteStream getData() const
Definition TiffEntry.h:129
uint32_t count
Definition TiffEntry.h:84
TiffDataType type
Definition TiffEntry.h:83
TiffEntry *RAWSPEED_READONLY getEntryRecursive(TiffTag tag) const
Definition TiffIFD.cpp:246
TiffID getID() const
Definition TiffIFD.cpp:325
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
void writeLog(DEBUG_PRIO priority, const char *format,...)
Definition Common.cpp:37
Array2DRef(Array1DRef< T > data, int width, int height, int pitch) -> Array2DRef< T >
@ PHOTOMETRICINTERPRETATION
Definition TiffTag.h:46
std::string make
Definition TiffIFD.h:134