RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
RawImage.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#pragma once
22
23#include "rawspeedconfig.h"
26#include "adt/Array2DRef.h"
27#include "adt/Casts.h"
30#include "adt/Mutex.h"
31#include "adt/NotARational.h"
32#include "adt/Optional.h"
33#include "adt/Point.h"
34#include "common/Common.h"
35#include "common/ErrorLog.h"
36#include "common/TableLookUp.h"
37#include "metadata/BlackArea.h"
39#include <array>
40#include <cassert>
41#include <cmath>
42#include <cstddef>
43#include <cstdint>
44#include <memory>
45#include <string>
46#include <utility>
47#include <vector>
48
49namespace rawspeed {
50
51class RawImage;
52class RawImageData;
53
54enum class RawImageType : uint8_t { UINT16, F32 };
55
56class RawImageWorker final {
57public:
61 APPLY_LOOKUP = 3 | 0x1000,
62 FULL_IMAGE = 0x1000
63 };
64
65private:
69 int end_y;
70
71 void performTask() noexcept;
72
73public:
75 int end_y) noexcept;
76};
77
78class ImageMetaData final {
79public:
80 // Aspect ratio of the pixels, usually 1 but some cameras need scaling
81 // <1 means the image needs to be stretched vertically, (0.5 means 2x)
82 // >1 means the image needs to be stretched horizontally (2 mean 2x)
83 double pixelAspectRatio = 1;
84
85 // White balance coefficients of the image
87
88 // If not empty, a row-major color matrix,
89 // that converts XYZ values to reference camera native color space values,
90 // under calibration illuminant 21 (D65).
91 std::vector<NotARational<int>> colorMatrix;
92
93 // How many pixels far down the left edge and far up the right edge the image
94 // corners are when the image is rotated 45 degrees in Fuji rotated sensors.
96
98 std::string make;
99 std::string model;
100 std::string mode;
101
102 std::string canonical_make;
103 std::string canonical_model;
104 std::string canonical_alias;
105 std::string canonical_id;
106
107 // ISO speed. If known the value is set, otherwise it will be '0'.
108 int isoSpeed = 0;
109};
110
111class RawImageData : public ErrorLog {
112 virtual void anchor() const;
113
114 friend class RawImageWorker;
115
116public:
117 virtual ~RawImageData() = default;
118 [[nodiscard]] uint32_t RAWSPEED_READONLY getCpp() const { return cpp; }
119 [[nodiscard]] uint32_t RAWSPEED_READONLY getBpp() const { return bpp; }
120 void setCpp(uint32_t val);
121 void createData();
122 void poisonPadding();
123 void unpoisonPadding();
124
125 [[nodiscard]] rawspeed::RawImageType getDataType() const { return dataType; }
126
127 [[nodiscard]] Array2DRef<uint16_t> getU16DataAsUncroppedArray2DRef() noexcept;
128 [[nodiscard]] CroppedArray2DRef<uint16_t>
129 getU16DataAsCroppedArray2DRef() noexcept;
130 [[nodiscard]] Array2DRef<float> getF32DataAsUncroppedArray2DRef() noexcept;
131 [[nodiscard]] CroppedArray2DRef<float>
132 getF32DataAsCroppedArray2DRef() noexcept;
133
134 // WARNING: this is most certainly not what you want!
135 [[nodiscard]] Array2DRef<std::byte>
136 getByteDataAsUncroppedArray2DRef() noexcept;
137
138 void subFrame(iRectangle2D cropped);
139 void clearArea(iRectangle2D area);
140 [[nodiscard]] iPoint2D RAWSPEED_READONLY getUncroppedDim() const;
141 [[nodiscard]] iPoint2D RAWSPEED_READONLY getCropOffset() const;
142 virtual void scaleBlackWhite() = 0;
143 virtual void calculateBlackAreas() = 0;
144 virtual void setWithLookUp(uint16_t value, std::byte* dst,
145 uint32_t* random) = 0;
146 void sixteenBitLookup();
149 void setTable(const std::vector<uint16_t>& table_, bool dither);
150 void setTable(std::unique_ptr<TableLookUp> t);
151
152 [[nodiscard]] bool isAllocated() const { return !data.empty(); }
153 void createBadPixelMap();
155 int pitch = 0;
156
157 // padding is the size of the area after last pixel of line n
158 // and before the first pixel of line n+1
160
161 bool isCFA{true};
163 int blackLevel = -1;
164 std::array<int, 4> blackLevelSeparateStorage;
166
167 // A white level of the image, if known.
168 // NOTE: it is always correct to divide the pixel by `float(whiteLevel)`,
169 // to normalize the image.
170 // NOTE: for floating-point images, the white level is never non-integral,
171 // and thus >= 1.0f
173
174 std::vector<BlackArea> blackAreas;
175
176 /* Vector containing the positions of bad pixels */
177 /* Format is x | (y << 16), so maximum pixel position is 65535 */
178 // Positions of zeroes that must be interpolated
179 std::vector<uint32_t> mBadPixelPositions GUARDED_BY(mBadPixelMutex);
180 std::vector<uint8_t, AlignedAllocator<uint8_t, 16>> mBadPixelMap;
183 true; // Should upscaling be done with dither to minimize banding?
185
186 Mutex mBadPixelMutex; // Mutex for 'mBadPixelPositions, must be used if more
187 // than 1 thread is accessing vector
188
189protected:
191 RawImageData() = default;
192 RawImageData(RawImageType type, const iPoint2D& dim, int bpp, int cpp = 1);
193 virtual void scaleValues(int start_y, int end_y) = 0;
194 virtual void doLookup(int start_y, int end_y) = 0;
195 virtual void fixBadPixel(uint32_t x, uint32_t y, int component = 0) = 0;
196 void fixBadPixelsThread(int start_y, int end_y);
197 void startWorker(RawImageWorker::RawImageWorkerTask task, bool cropped);
198 std::vector<uint8_t, DefaultInitAllocatorAdaptor<
201 int cpp = 1; // Components per pixel
202 int bpp = 0; // Bytes per pixel.
203 friend class RawImage;
206 std::unique_ptr<TableLookUp> table;
207};
208
209class RawImageDataU16 final : public RawImageData {
210public:
212 explicit RawImageDataU16(const iPoint2D& dim_, uint32_t cpp_ = 1);
213
214 void scaleBlackWhite() override;
215 void calculateBlackAreas() override;
216 void setWithLookUp(uint16_t value, std::byte* dst, uint32_t* random) override;
217
218private:
219 void scaleValues_plain(int start_y, int end_y);
220#ifdef WITH_SSE2
221 void scaleValues_SSE2(int start_y, int end_y);
222#endif
223 void scaleValues(int start_y, int end_y) override;
224 void fixBadPixel(uint32_t x, uint32_t y, int component = 0) override;
225 void doLookup(int start_y, int end_y) override;
226
227 friend class RawImage;
228};
229
230class RawImageDataFloat final : public RawImageData {
231public:
233 explicit RawImageDataFloat(const iPoint2D& dim_, uint32_t cpp_ = 1);
234
235 void scaleBlackWhite() override;
236 void calculateBlackAreas() override;
237 void setWithLookUp(uint16_t value, std::byte* dst, uint32_t* random) override;
238
239private:
240 void scaleValues(int start_y, int end_y) override;
241 void fixBadPixel(uint32_t x, uint32_t y, int component = 0) override;
242 [[noreturn]] void doLookup(int start_y, int end_y) override;
243
244 friend class RawImage;
245};
246
247class RawImage final {
248public:
249 static RawImage create(RawImageType type = RawImageType::UINT16);
250 static RawImage create(const iPoint2D& dim,
251 RawImageType type = RawImageType::UINT16,
252 uint32_t componentsPerPixel = 1);
253 RawImageData* RAWSPEED_READONLY operator->() const { return &*p_; }
254 RawImageData& RAWSPEED_READONLY operator*() const { return *p_; }
255
256 explicit RawImage(RawImageData* p) = delete;
257 explicit RawImage(std::shared_ptr<RawImageData> p) : p_(std::move(p)) {}
258
259 RawImageData* get() { return &*p_; }
260
261private:
262 std::shared_ptr<RawImageData> p_; // p_ is never NULL
263};
264
266 switch (type) {
268 return RawImage(std::make_shared<RawImageDataU16>());
270 return RawImage(std::make_shared<RawImageDataFloat>());
271 }
272 writeLog(DEBUG_PRIO::ERROR, "RawImage::create: Unknown Image type!");
273 __builtin_unreachable();
274}
275
277 uint32_t componentsPerPixel) {
278 switch (type) {
280 return RawImage(std::make_shared<RawImageDataU16>(dim, componentsPerPixel));
282 return RawImage(
283 std::make_shared<RawImageDataFloat>(dim, componentsPerPixel));
284 }
285 writeLog(DEBUG_PRIO::ERROR, "RawImage::create: Unknown Image type!");
286 __builtin_unreachable();
287}
288
292 "Attempting to access floating-point buffer as uint16_t.");
293 assert(!data.empty() && "Data not yet allocated.");
294#pragma GCC diagnostic push
295#pragma GCC diagnostic ignored "-Wpragmas"
296#pragma GCC diagnostic ignored "-Wunknown-warning-option"
297#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
298 return {reinterpret_cast<uint16_t*>(data.data()), cpp * uncropped_dim.x,
299 uncropped_dim.y, static_cast<int>(pitch / sizeof(uint16_t))};
300#pragma GCC diagnostic pop
301}
302
308
312 "Attempting to access integer buffer as float.");
313 assert(!data.empty() && "Data not yet allocated.");
314#pragma GCC diagnostic push
315#pragma GCC diagnostic ignored "-Wpragmas"
316#pragma GCC diagnostic ignored "-Wunknown-warning-option"
317#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
318 return {reinterpret_cast<float*>(data.data()), cpp * uncropped_dim.x,
319 uncropped_dim.y, static_cast<int>(pitch / sizeof(float))};
320#pragma GCC diagnostic pop
321}
322
328
331 switch (dataType) {
336 }
337 __builtin_unreachable();
338}
339
340// setWithLookUp will set a single pixel by using the lookup table if supplied,
341// You must supply the destination where the value should be written, and a
342// pointer to a value that will be used to store a random counter that can be
343// reused between calls. this needs to be inline to speed up tight decompressor
344// loops
345inline void RawImageDataU16::setWithLookUp(uint16_t value, std::byte* dst,
346 uint32_t* random) {
347 auto* dest = reinterpret_cast<uint16_t*>(dst);
348 if (table == nullptr) {
349 *dest = value;
350 return;
351 }
352 if (table->dither) {
353 uint32_t base = table->tables[(2 * value) + 0];
354 uint32_t delta = table->tables[(2 * value) + 1];
355 uint32_t r = *random;
356
357 uint32_t pix = base + ((delta * (r & 2047) + 1024) >> 12);
358 *random = 15700 * (r & 65535) + (r >> 16);
359 *dest = implicit_cast<uint16_t>(pix);
360 return;
361 }
362 *dest = table->tables[value];
363}
364
367 const std::vector<uint16_t>& curve;
369
370public:
374 RawImageCurveGuard& operator=(const RawImageCurveGuard&) noexcept = delete;
375 RawImageCurveGuard& operator=(RawImageCurveGuard&&) noexcept = delete;
376
377 RawImageCurveGuard(const RawImage* raw, const std::vector<uint16_t>& curve_,
378 bool uncorrectedRawValues_)
379 : mRaw(raw), curve(curve_), uncorrectedRawValues(uncorrectedRawValues_) {
381 return;
382
383 (*mRaw)->setTable(curve, true);
384 }
385
387 // Set the table, if it should be needed later.
389 (*mRaw)->setTable(curve, false);
390 else
391 (*mRaw)->setTable(nullptr);
392 }
393};
394
395} // namespace rawspeed
#define REQUIRES(...)
iPoint2D dim(rawspeed::implicit_cast< int >(ceil(sqSide *sqARatio)), rawspeed::implicit_cast< int >(ceil(sqSide/sqARatio)))
Definition Common.cpp:55
assert(dim.area() >=area)
dim y
Definition Common.cpp:51
dim x
Definition Common.cpp:50
RawImage(RawImageData *p)=delete
static RawImage create(RawImageType type=RawImageType::UINT16)
Definition RawImage.h:265
std::string canonical_alias
Definition RawImage.h:104
Optional< std::array< float, 4 > > wbCoeffs
Definition RawImage.h:86
std::string canonical_model
Definition RawImage.h:103
std::string canonical_make
Definition RawImage.h:102
std::string canonical_id
Definition RawImage.h:105
std::vector< NotARational< int > > colorMatrix
Definition RawImage.h:91
const std::vector< uint16_t > & curve
Definition RawImage.h:367
const RawImage * mRaw
Definition RawImage.h:366
RawImageCurveGuard(RawImageCurveGuard &&) noexcept=delete
RawImageCurveGuard(const RawImageCurveGuard &)=delete
void doLookup(int start_y, int end_y) override
void fixBadPixel(uint32_t x, uint32_t y, int component=0) override
void setWithLookUp(uint16_t value, std::byte *dst, uint32_t *random) override
void scaleValues(int start_y, int end_y) override
void fixBadPixels() REQUIRES(!mBadPixelMutex)
Definition RawImage.cpp:232
rawspeed::RawImageType getDataType() const
Definition RawImage.h:125
std::array< int, 4 > blackLevelSeparateStorage
Definition RawImage.h:164
uint32_t RAWSPEED_READONLY getCpp() const
Definition RawImage.h:118
virtual ~RawImageData()=default
Optional< Array2DRef< int > > blackLevelSeparate
Definition RawImage.h:165
CroppedArray2DRef< float > getF32DataAsCroppedArray2DRef() noexcept
Definition RawImage.h:324
friend class RawImageWorker
Definition RawImage.h:114
std::vector< uint32_t > mBadPixelPositions GUARDED_BY(mBadPixelMutex)
void transferBadPixelsToMap() REQUIRES(!mBadPixelMutex)
Definition RawImage.cpp:211
virtual void setWithLookUp(uint16_t value, std::byte *dst, uint32_t *random)=0
Optional< int > whitePoint
Definition RawImage.h:172
virtual void fixBadPixel(uint32_t x, uint32_t y, int component=0)=0
Array2DRef< std::byte > getByteDataAsUncroppedArray2DRef() noexcept
Definition RawImage.h:330
virtual void scaleValues(int start_y, int end_y)=0
virtual void anchor() const
Definition RawImage.cpp:51
Array2DRef< float > getF32DataAsUncroppedArray2DRef() noexcept
Definition RawImage.h:310
bool isAllocated() const
Definition RawImage.h:152
void setTable(const std::vector< uint16_t > &table_, bool dither)
Definition RawImage.cpp:385
virtual void doLookup(int start_y, int end_y)=0
void fixBadPixelsThread(int start_y, int end_y)
Definition RawImage.cpp:298
std::vector< BlackArea > blackAreas
Definition RawImage.h:174
Array2DRef< uint16_t > getU16DataAsUncroppedArray2DRef() noexcept
Definition RawImage.h:290
uint32_t RAWSPEED_READONLY getBpp() const
Definition RawImage.h:119
std::vector< uint8_t, AlignedAllocator< uint8_t, 16 > > mBadPixelMap
Definition RawImage.h:180
friend class RawImage
Definition RawImage.h:203
void startWorker(RawImageWorker::RawImageWorkerTask task, bool cropped)
Definition RawImage.cpp:271
CroppedArray2DRef< uint16_t > getU16DataAsCroppedArray2DRef() noexcept
Definition RawImage.h:304
virtual void calculateBlackAreas()=0
ImageMetaData metadata
Definition RawImage.h:184
std::unique_ptr< TableLookUp > table
Definition RawImage.h:206
ColorFilterArray cfa
Definition RawImage.h:162
virtual void scaleBlackWhite()=0
uint32_t mBadPixelMapPitch
Definition RawImage.h:181
std::vector< uint8_t, DefaultInitAllocatorAdaptor< uint8_t, AlignedAllocator< uint8_t, 16 > > > data
Definition RawImage.h:200
RawImageType dataType
Definition RawImage.h:190
void scaleValues_plain(int start_y, int end_y)
void calculateBlackAreas() override
void scaleValues(int start_y, int end_y) override
void doLookup(int start_y, int end_y) override
void fixBadPixel(uint32_t x, uint32_t y, int component=0) override
void setWithLookUp(uint16_t value, std::byte *dst, uint32_t *random) override
Definition RawImage.h:345
RawImage(RawImageData *p)=delete
RawImage(std::shared_ptr< RawImageData > p)
Definition RawImage.h:257
RawImageData * get()
Definition RawImage.h:259
std::shared_ptr< RawImageData > p_
Definition RawImage.h:262
static RawImage create(RawImageType type=RawImageType::UINT16)
Definition RawImage.h:265
RawImageData *RAWSPEED_READONLY operator->() const
Definition RawImage.h:253
RawImageData &RAWSPEED_READONLY operator*() const
Definition RawImage.h:254
void performTask() noexcept
Definition RawImage.cpp:346
RawImageWorkerTask task
Definition RawImage.h:67
RawImageWorker(RawImageData *img, RawImageWorkerTask task, int start_y, int end_y) noexcept
Definition RawImage.cpp:340
RawImageData * data
Definition RawImage.h:66
STL class.
STL class.
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
void writeLog(DEBUG_PRIO priority, const char *format,...)
Definition Common.cpp:37