23#include "rawspeedconfig.h"
78 for (
int* col : {&rect.
pos.
x, &rect.
dim.
x}) {
79 assert(*col % ri->
getCpp() == 0 &&
"Column is width * cpp");
88 if constexpr (std::is_same<T, uint16_t>())
90 if constexpr (std::is_same<T, float>())
92 __builtin_unreachable();
103 virtual void anchor()
const;
111 assert(std::uncaught_exceptions() == 0 &&
112 "Creating DngOpcode during call stack unwinding?");
123 "Derived classes did not call our setup()!");
133 "Current image sub-crop does not match the expected one!");
152 void anchor()
const override;
166 ThrowRDE(
"Only 16 bit images supported");
169 ThrowRDE(
"Only 1 component images supported");
179 if (img(row, col) ==
value)
180 ri->mBadPixelPositions.push_back(offset + (row << 16 | col));
196 void anchor()
const override;
210 const iPoint2D bottomRight(right, bottom);
214 bottomRight >= topLeft)) {
215 ThrowRDE(
"Rectangle (%d, %d, %d, %d) not inside image (%d, %d, %d, %d).",
216 topLeft.
x, topLeft.
y, bottomRight.
x, bottomRight.
y,
221 roi.setTopLeft(topLeft);
222 roi.setBottomRightAbsolute(bottomRight);
239 void anchor()
const override;
244 :
ROIOpcode(ri, bs, integrated_subimg_) {
251 assert(
false &&
"You should not be calling this.");
252 __builtin_unreachable();
266 void anchor()
const override;
278 auto badPointCount = bs.
getU32();
279 auto badRectCount = bs.
getU32();
289 for (
auto i = 0U; i < badPointCount; ++i) {
294 ThrowRDE(
"Bad point not inside image.");
300 for (
auto i = 0U; i < badRectCount; ++i) {
320 ri->mBadPixelPositions.insert(ri->mBadPixelPositions.begin(),
333 void anchor()
const override;
338 :
ROIOpcode(ri, bs, integrated_subimg_) {
359 void anchor()
const override;
369 ThrowRDE(
"Bad plane params (first %u, num %u), got planes = %u",
370 firstPlane, planes, ri->getCpp());
378 if (rowPitch < 1 || rowPitch >
static_cast<uint32_t>(ROI.getHeight()) ||
379 colPitch < 1 || colPitch >
static_cast<uint32_t>(ROI.getWidth()))
390 template <
typename T,
typename OP>
398 for (
int y = 0;
y < numAffected.
y; ++
y) {
399 for (
int x = 0;
x < numAffected.
x; ++
x) {
400 for (
auto p = 0U; p <
planes; ++p) {
404 pixel = op(
x,
y, pixel);
419 void anchor()
const override;
422 vector<uint16_t>
lookup = vector<uint16_t>(65536);
430 ThrowRDE(
"Only 16 bit images supported");
448 void anchor()
const override;
456 if (count == 0 || count > 65536)
457 ThrowRDE(
"Invalid size of lookup table");
459 for (
auto i = 0U; i < count; ++i)
462 if (count <
lookup.size())
475 void anchor()
const override;
481 vector<double> polynomial;
483 const auto polynomial_size = bs.
getU32() + 1UL;
485 if (polynomial_size > 9)
486 ThrowRDE(
"A polynomial with more than 8 degrees not allowed");
488 polynomial.reserve(polynomial_size);
489 std::generate_n(std::back_inserter(polynomial), polynomial_size,
490 [&bs]() {
return bs.
get<
double>(); });
494 for (
auto i = 0UL; i <
lookup.size(); ++i) {
495 double val = polynomial[0];
496 for (
auto j = 1UL; j < polynomial.size(); ++j)
500 val * 65535.5, std::numeric_limits<uint16_t>::min(),
501 std::numeric_limits<uint16_t>::max()));
514 void anchor()
const final;
547 for (
const auto f :
deltaF) {
549 ThrowRDE(
"Got float %f which is unacceptable.",
564 const iRectangle2D& integrated_subimg_,
float f2iScale_)
566 const auto deltaF_count = bs.
getU32();
567 (void)bs.
check(deltaF_count, 4);
575 expectedSize != deltaF_count) {
576 ThrowRDE(
"Got unexpected number of elements (%" PRIu64
"), expected %u.",
577 expectedSize, deltaF_count);
580 deltaF.reserve(deltaF_count);
581 std::generate_n(std::back_inserter(
deltaF), deltaF_count, [&bs]() {
582 const auto F = bs.
get<
float>();
583 switch (std::fpclassify(F)) {
625 return this->
deltaF[S::select(
x,
y)] + v;
664 return this->
deltaF[S::select(
x,
y)] * v;
676 const auto opcode_count = bs.
getU32();
680 for (
auto i = 0U; i < opcode_count; i++) {
684 const auto opcode_size = bs.
getU32();
693 iRectangle2D integrated_subimg = getImageCropAsRectangle(ri);
695 for (
auto i = 0U; i < opcode_count; i++) {
703 const auto opcode_size = bs.
getU32();
706 const char* opName =
nullptr;
708 if (
auto Op =
Map(code))
709 std::tie(opName, opConstructor) = *Op;
711 ThrowRDE(
"Unknown unhandled Opcode: %u", code);
713 if (opConstructor !=
nullptr)
714 opcodes.emplace_back(opConstructor(ri, opcode_bs, integrated_subimg));
720 ThrowRDE(
"Unsupported Opcode: %u (%s)", code, opName);
724 ThrowRDE(
"Inconsistent length of opcode");
737 for (
const auto& code :
opcodes) {
743template <
class Opcode>
744std::unique_ptr<DngOpcodes::DngOpcode>
747 return std::make_unique<Opcode>(ri, bs, integrated_subimg);
756 return make_pair(
"WarpRectilinear",
nullptr);
758 return make_pair(
"WarpFisheye",
nullptr);
760 return make_pair(
"FixVignetteRadial",
nullptr);
763 "FixBadPixelsConstant",
766 return make_pair(
"FixBadPixelsList",
769 return make_pair(
"TrimBounds",
772 return make_pair(
"MapTable",
775 return make_pair(
"MapPolynomial",
778 return make_pair(
"GainMap",
nullptr);
constexpr auto RAWSPEED_READNONE clampBits(T value, unsigned int nBits)
constexpr uint64_t RAWSPEED_READNONE roundUpDivisionSafe(uint64_t value, uint64_t div)
iPoint2D dim(rawspeed::implicit_cast< int >(ceil(sqSide *sqARatio)), rawspeed::implicit_cast< int >(ceil(sqSide/sqARatio)))
assert(dim.area() >=area)
size_type check(size_type bytes) const
size_type RAWSPEED_READONLY getRemainSize() const
void setPosition(size_type newPos)
ByteStream getStream(size_type size_)
void skipBytes(size_type nbytes)
size_type getPosition() const
Endianness setByteOrder(Endianness endianness_)
void anchor() const final
DeltaRowOrColBase(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
void setup(const RawImage &ri) final
virtual bool valueIsOk(float value)=0
DeltaRowOrCol(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_, float f2iScale_)
const iRectangle2D integrated_subimg
DngOpcode(DngOpcode &&) noexcept=delete
virtual void apply(const RawImage &ri)=0
virtual void setup(const RawImage &ri)
virtual void anchor() const
DngOpcode(const DngOpcode &)=delete
DngOpcode(const iRectangle2D &integrated_subimg_)
void apply(const RawImage &ri) override
DummyROIOpcode(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
const iRectangle2D &RAWSPEED_READONLY getRoi() const
void anchor() const override
void apply(const RawImage &ri) override
FixBadPixelsConstant(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
void setup(const RawImage &ri) override
void anchor() const override
void anchor() const override
FixBadPixelsList(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
std::vector< uint32_t > badPixels
void apply(const RawImage &ri) override
vector< uint16_t > lookup
void setup(const RawImage &ri) final
PixelOpcode(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
void apply(const RawImage &ri) final
void anchor() const override
bool valueIsOk(float value) override
OffsetPerRowOrCol(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
void apply(const RawImage &ri) override
iPoint2D RAWSPEED_READONLY getPitch() const
void applyOP(const RawImage &ri, OP op) const
void anchor() const override
PixelOpcode(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
PolynomialMap(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
void anchor() const override
ROIOpcode(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
void anchor() const override
const iRectangle2D &RAWSPEED_READONLY getRoi() const
ScalePerRowOrCol(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
static constexpr int rounding
static constexpr const float minLimit
bool valueIsOk(float value) override
void apply(const RawImage &ri) override
TableMap(const RawImage &ri, ByteStream &bs, const iRectangle2D &integrated_subimg_)
void anchor() const override
void anchor() const override
void apply(const RawImage &ri) override
TrimBounds(const RawImage &ri, ByteStream &bs, iRectangle2D &integrated_subimg_)
DngOpcodes(const RawImage &ri, ByteStream bs)
std::vector< std::unique_ptr< DngOpcode > > opcodes
static std::unique_ptr< DngOpcode > constructor(const RawImage &ri, ByteStream &bs, iRectangle2D &integrated_subimg)
static Optional< std::pair< const char *, DngOpcodes::constructor_t > > Map(uint32_t code)
std::unique_ptr< DngOpcode >(*)( const RawImage &ri, ByteStream &bs, iRectangle2D &integrated_subimg) constructor_t
void applyOpCodes(const RawImage &ri) const
rawspeed::RawImageType getDataType() const
uint32_t RAWSPEED_READONLY getCpp() const
CroppedArray2DRef< float > getF32DataAsCroppedArray2DRef() noexcept
iPoint2D RAWSPEED_READONLY getCropOffset() const
iPoint2D RAWSPEED_READONLY getUncroppedDim() const
void subFrame(iRectangle2D cropped)
CroppedArray2DRef< uint16_t > getU16DataAsCroppedArray2DRef() noexcept
constexpr bool RAWSPEED_READONLY isPointInsideInclusive(const iPoint2D &subPoint) const
constexpr int getTop() const
constexpr bool RAWSPEED_READONLY isPointInside(const iPoint2D &subPoint) const
constexpr bool RAWSPEED_READONLY isThisInside(const iRectangle2D &superRect) const
constexpr int getHeight() const
constexpr iPoint2D getTopLeft() const
constexpr int getWidth() const
constexpr int getLeft() const
constexpr iPoint2D getBottomRight() const
CroppedArray2DRef< T > getDataAsCroppedArray2DRef(const RawImage &ri)
iRectangle2D getImageCropAsRectangle(CroppedArray2DRef< T > img)
constexpr uint64_t RAWSPEED_READNONE roundUpDivisionSafe(uint64_t value, uint64_t div)
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
constexpr auto RAWSPEED_READNONE clampBits(T value, unsigned int nBits)
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
static uint32_t select(uint32_t x, uint32_t)
static uint32_t select(uint32_t, uint32_t y)