67 const auto id = rootIFD->
getID();
68 const std::string& make =
id.
make;
71 (make ==
"Phase One A/S" || make ==
"Phase One" || make ==
"Leaf");
75std::vector<PhaseOneStrip>
79 assert(offsets.size() == (1 + height));
88 std::sort(offsets.begin(), offsets.end(),
90 if (a.offset == b.offset && &a != &b)
91 ThrowRDE(
"Two identical offsets found. Corrupt raw.");
92 return a.offset < b.offset;
95 std::vector<PhaseOneStrip> slices;
96 slices.reserve(height);
98 auto offset_iterator = std::begin(offsets);
101 auto next_offset_iterator = std::next(offset_iterator);
102 while (next_offset_iterator < std::end(offsets)) {
103 assert(next_offset_iterator->offset > offset_iterator->offset);
104 const auto size = next_offset_iterator->offset - offset_iterator->offset;
107 slices.emplace_back(offset_iterator->n, bs.
getStream(size));
109 std::advance(offset_iterator, 1);
110 std::advance(next_offset_iterator, 1);
113 assert(slices.size() == height);
187 for (
uint32_t entry = 0; entry < entries_count; entry++) {
205 ThrowRDE(
"Duplicate RawFormat tag.");
206 format = getAsIIQFormat(data);
207 if (!format || *format != IIQFormat::IIQ_L)
208 ThrowRDE(
"Unsupported RawFormat: %u", data);
237 if (width == 0 || height == 0 || width > 11976 || height > 8854)
238 ThrowRDE(
"Unexpected image dimensions found: (%u; %u)", width, height);
246 if (split_col > width || split_row > height)
247 ThrowRDE(
"Invalid sensor quadrant split values (%u, %u)", split_row,
252 std::vector<IiqOffset> offsets;
253 offsets.reserve(1 + height);
255 for (
uint32_t row = 0; row < height; row++)
256 offsets.emplace_back(row, block_offsets.
getU32());
260 offsets.emplace_back(height, raw_data->getSize());
262 std::vector<PhaseOneStrip> strips(
271 if (correction_meta_data.
getSize() != 0 &&
iiq)
274 std::array<float, 4> wbCoeffs = {};
275 for (
int i = 0; i < 3; i++)
277 mRaw->metadata.wbCoeffs = wbCoeffs;
294 bool QuadrantMultipliersSeen =
false;
295 bool SensorDefectsSeen =
false;
297 for (
uint32_t entry = 0; entry < entries_count; entry++) {
304 if (SensorDefectsSeen)
305 ThrowRDE(
"Second sensor defects entry seen. Unexpected.");
307 SensorDefectsSeen =
true;
316 if (QuadrantMultipliersSeen)
317 ThrowRDE(
"Second quadrant multipliers entry seen. Unexpected.");
318 if (
iiq.quadrantMultipliers)
320 split_row, split_col);
321 QuadrantMultipliersSeen =
true;
340 std::array<uint32_t, 9> shared_x_coords;
343 std::generate_n(std::next(shared_x_coords.begin()), 7,
344 [&data] { return data.getU32(); });
348 shared_x_coords.front() = 0;
349 shared_x_coords.back() = 65535;
352 if (std::adjacent_find(shared_x_coords.cbegin(), shared_x_coords.cend(),
353 std::greater_equal<>()) != shared_x_coords.cend())
354 ThrowRDE(
"The X coordinates must all be strictly increasing");
356 std::array<std::array<std::vector<iPoint2D>, 2>, 2> control_points;
357 for (
auto& quadRow : control_points) {
358 for (
auto& quadrant : quadRow) {
360 quadrant.emplace_back(0, 0);
362 for (
int i = 1; i < 8; i++) {
368 ThrowRDE(
"The Y coordinate %" PRIu64
" is too large", y_coord);
369 quadrant.emplace_back(shared_x_coords[i], y_coord);
372 quadrant.emplace_back(65535, 65535);
373 assert(quadrant.size() == 9);
377 for (
int quadRow = 0; quadRow < 2; quadRow++) {
378 for (
int quadCol = 0; quadCol < 2; quadCol++) {
381 const Spline<> s(control_points[quadRow][quadCol]);
382 const std::vector<uint16_t> curve =
s.calculateCurve();
384 int row_start = quadRow == 0 ? 0 : split_row;
385 int row_end = quadRow == 0 ? split_row : img.
height();
386 int col_start = quadCol == 0 ? 0 : split_col;
387 int col_end = quadCol == 0 ? split_col : img.
width();
389 for (
int row = row_start; row < row_end; row++) {
390 for (
int col = col_start; col < col_end; col++) {
402 pixel = curve[pixel - diff] + diff;
422 ThrowRDE(
"Unsupported IIQ correction");
425 std::array<uint16_t, 8> head;
426 for (
int i = 0; i < 8; i++)
429 if (head[2] == 0 || head[3] == 0 || head[4] == 0 || head[5] == 0)
435 std::vector<float> mrow_storage;
437 mrow_storage, wide * nc, 1);
440 for (
int y = 0;
y < high;
y++) {
441 for (
int x = 0;
x < wide;
x++) {
442 for (
int c = 0; c < nc; c += 2) {
443 float num = data.
getU16() / 32768.0F;
447 mrow(
x, c + 1) = (num - mrow(
x, c)) / head[5];
452 for (
int rend = head[1] + (
y * head[5]), row = rend - head[5];
453 row <
mRaw->dim.y && row < rend && row < (head[1] + head[3] - head[5]);
455 for (
int x = 1;
x < wide;
x++) {
456 std::array<float, 4> mult;
457 for (
int c = 0; c < nc; c += 2) {
458 mult[c] = mrow(
x - 1, c);
459 mult[c + 1] = (mrow(
x, c) - mult[c]) / head[4];
461 for (
int cend = head[0] + (
x * head[4]), col = cend - head[4];
462 col <
mRaw->dim.x && col < cend &&
463 col < head[0] + head[2] - head[4];
466 nc > 2 ?
static_cast<unsigned>(
mRaw->cfa.getColorAt(row, col))
472 for (
int c = 0; c < nc; c += 2)
473 mult[c] += mult[c + 1];
476 for (
int x = 0;
x < wide;
x++)
477 for (
int c = 0; c < nc; c += 2)
478 mrow(
x, c) += mrow(
x, c + 1);
489 ThrowRDE(
"Couldn't find camera %s %s",
id.make.c_str(),
id.model.c_str());
508 if (col >=
mRaw->dim.x)
526 mRaw->mBadPixelPositions.insert(
mRaw->mBadPixelPositions.end(),
527 (
static_cast<uint32_t>(row) << 16) + col);
533 for (
int row = 2; row <
mRaw->dim.y - 2; row++) {
544 std::array<uint16_t, 4>
val;
545 std::array<int32_t, 4> dev;
547 sum +=
val[0] = img(row - 1, col - 1);
548 sum +=
val[1] = img(row + 1, col - 1);
549 sum +=
val[2] = img(row - 1, col + 1);
550 sum +=
val[3] = img(row + 1, col + 1);
551 for (
int i = 0; i < 4; i++) {
552 dev[i] = std::abs((
val[i] * 4) - sum);
553 if (dev[max] < dev[i])
556 const int three_pixels = sum -
val[max];
570 uint32_t diags = img(row + 2, col - 2) + img(row - 2, col - 2) +
571 img(row + 2, col + 2) + img(row - 2, col + 2);
572 uint32_t horiz = img(row, col - 2) + img(row, col + 2);
575 std::lround((diags * 0.0732233) + (horiz * 0.3535534)));
assert(dim.area() >=area)
bool checkCameraSupported(const CameraMetaData *meta, const TiffID &id, const std::string &mode)
void setMetaData(const CameraMetaData *meta, const TiffID &id, const std::string &mode, int iso_speed)
TiffRootIFDOwner mRootIFD
int RAWSPEED_READONLY height() const
static Array2DRef< T > create(std::vector< cvless_value_type, AllocatorType > &storage, int width, int height)
int RAWSPEED_READONLY width() const
Buffer getSubView(size_type offset, size_type size_) const
size_type RAWSPEED_READONLY getSize() const
size_type RAWSPEED_READONLY getRemainSize() const
void setPosition(size_type newPos)
ByteStream getSubStream(size_type offset, size_type size_) const
ByteStream getStream(size_type size_)
void skipBytes(size_type nbytes)
size_type getPosition() const
T get(size_type offset, size_type index=0) const
RawImage decodeRawInternal() override
void handleBadPixel(uint16_t col, uint16_t row) const
void decodeMetaDataInternal(const CameraMetaData *meta) override
static bool isAppropriateDecoder(Buffer file)
void checkSupportInternal(const CameraMetaData *meta) override
static std::vector< PhaseOneStrip > computeSripes(Buffer raw_data, std::vector< IiqOffset > offsets, uint32_t height)
void correctSensorDefects(ByteStream data) const
void PhaseOneFlatField(ByteStream data, IiqCorr corr) const
void CorrectQuadrantMultipliersCombined(ByteStream data, uint32_t split_row, uint32_t split_col) const
void correctBadColumn(uint16_t col) const
void CorrectPhaseOneC(ByteStream meta_data, uint32_t split_row, uint32_t split_col) const
struct rawspeed::RawDecoder::@224365236145247220354374363215210370336104332222 iiq
Optional< IIQFormat > getAsIIQFormat(uint32_t v)
constexpr uint64_t RAWSPEED_READNONE roundUpDivisionSafe(uint64_t value, uint64_t div)
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Array2DRef(Array1DRef< T > data, int width, int height, int pitch) -> Array2DRef< T >
void RAWSPEED_UNLIKELY_FUNCTION RAWSPEED_NOINLINE static char buf[bufSize]