Expand Up
@@ -25,6 +25,7 @@
#include " adt/Array2DRef.h"
#include " adt/Casts.h"
#include " adt/Point.h"
#include " common/Common.h"
#include " common/RawImage.h"
#include " decoders/RawDecoderException.h"
#include " decompressors/Cr2Decompressor.h"
Expand All
@@ -45,6 +46,7 @@
#include < memory>
#include < optional>
#include < string>
#include < utility>
#include < vector>
namespace rawspeed {
Expand Down
Expand Up
@@ -99,6 +101,7 @@
Cr2SliceWidths slicing (/* numSlices=*/ 1 , /* sliceWidth=don't care*/ 0 ,
/* lastSliceWidth=*/ implicit_cast<uint16_t >(width));
l.decode (slicing);
ljpegSamplePrecision = l.getSamplePrecision ();
Check warning
on line 104
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L104
Added line #L104 was not covered by tests
// deal with D2000 GrayResponseCurve
if (const TiffEntry* curve =
Expand Down
Expand Up
@@ -193,6 +196,7 @@
Cr2LJpegDecoder d (bs, mRaw );
mRaw ->createData ();
d.decode (slicing);
ljpegSamplePrecision = d.getSamplePrecision ();
assert (getSubSampling () == mRaw ->metadata .subsampling );
Expand Down
Expand Up
@@ -231,51 +235,51 @@
ColorData6,
ColorData7,
ColorData8,
ColorData9,
ColorData10,
};
[[nodiscard]] std::optional<ColorDataFormat>
[[nodiscard]] std::optional<std::pair< ColorDataFormat, std::optional< int >> >
deduceColorDataFormat (const TiffEntry* ccd) {
// The original ColorData, detect by it's fixed size.
if (ccd->count == 582 )
return ColorDataFormat::ColorData1;
return {{ ColorDataFormat::ColorData1, {}}} ;
Check warning
on line 244
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L244
Added line #L244 was not covered by tests
// Second incarnation of ColorData, still size-only detection.
if (ccd->count == 653 )
return ColorDataFormat::ColorData2;
return {{ ColorDataFormat::ColorData2, {}}} ;
Check warning
on line 247
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L247
Added line #L247 was not covered by tests
// From now onwards, Canon has finally added a `version` field, use it.
switch (int colorDataVersion = static_cast <int16_t >(ccd->getU16 (0 ));
colorDataVersion) {
case 1 :
return ColorDataFormat::ColorData3;
return {{ ColorDataFormat::ColorData3, colorDataVersion}} ;
Check warning
on line 252
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L252
Added line #L252 was not covered by tests
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 9 :
return ColorDataFormat::ColorData4;
return {{ ColorDataFormat::ColorData4, colorDataVersion}} ;
case -4 :
case -3 :
return ColorDataFormat::ColorData5;
case 10 :
return ColorDataFormat::ColorData6;
return {{ColorDataFormat::ColorData5, colorDataVersion}};
case 10 : {
ColorDataFormat f = [count = ccd->count ]() {
switch (count) {
case 1273 :
Check warning
on line 267
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L263-L267
Added lines #L263 - L267 were not covered by tests
case 1275 :
return ColorDataFormat::ColorData6;
default :
return ColorDataFormat::ColorData7;
Check warning
on line 271
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L269-L271
Added lines #L269 - L271 were not covered by tests
}
}();
return {{f, colorDataVersion}};
Check warning
on line 274
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L273-L274
Added lines #L273 - L274 were not covered by tests
}
case 11 :
return ColorDataFormat::ColorData7;
return {{ ColorDataFormat::ColorData7, colorDataVersion}} ;
Check warning
on line 277
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L277
Added line #L277 was not covered by tests
case 12 :
case 13 :
case 14 :
case 15 :
return ColorDataFormat::ColorData8;
case 16 :
case 17 :
case 18 :
case 19 :
return ColorDataFormat::ColorData9;
case 32 :
case 33 :
return ColorDataFormat::ColorData10;
return {{ColorDataFormat::ColorData8, colorDataVersion}};
default :
break ;
}
Expand All
@@ -296,32 +300,125 @@
case ColorData8:
return 126 ;
case ColorData5:
case ColorData9:
return 142 ;
case ColorData10:
return 170 ;
}
__builtin_unreachable ();
}
[[nodiscard]] std::optional<std::pair<int , int >>
getBlackAndWhiteLevelOffsetsInColorData (ColorDataFormat f,
int colorDataVersion) {
switch (f) {
using enum ColorDataFormat;
case ColorData1:
Check warning
on line 313
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L313
Added line #L313 was not covered by tests
case ColorData2:
case ColorData3:
// These seemingly did not contain `SpecularWhiteLevel` yet.
return std::nullopt;
Check warning
on line 317
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L317
Added line #L317 was not covered by tests
case ColorData4:
switch (colorDataVersion) {
case 2 :
return std::nullopt; // Still no `SpecularWhiteLevel`.
Check warning
on line 321
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L320-L321
Added lines #L320 - L321 were not covered by tests
case 3 :
return {{231 , 617 }};
case 4 :
Check warning
on line 324
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L324
Added line #L324 was not covered by tests
case 5 :
return {{692 , 697 }};
Check warning
on line 326
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L326
Added line #L326 was not covered by tests
case 6 :
case 7 :
return {{715 , 720 }};
case 9 :
return {{719 , 724 }};
default :
__builtin_unreachable ();
Check warning
on line 333
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L330-L333
Added lines #L330 - L333 were not covered by tests
}
case ColorData5:
switch (colorDataVersion) {
case -4 :
return {{333 , 1386 }};
case -3 :
return {{264 , 662 }};
default :
__builtin_unreachable ();
Check warning
on line 342
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L335-L342
Added lines #L335 - L342 were not covered by tests
}
case ColorData6:
Check warning
on line 344
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L344
Added line #L344 was not covered by tests
// NOLINTNEXTLINE(hicpp-multiway-paths-covered)
switch (colorDataVersion) {
case 10 :
return {{479 , 484 }};
default :
__builtin_unreachable ();
Check warning
on line 350
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L346-L350
Added lines #L346 - L350 were not covered by tests
}
case ColorData7:
switch (colorDataVersion) {
case 10 :
return {{504 , 509 }};
case 11 :
return {{728 , 733 }};
default :
__builtin_unreachable ();
Check warning
on line 359
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L352-L359
Added lines #L352 - L359 were not covered by tests
}
case ColorData8:
switch (colorDataVersion) {
case 12 :
case 13 :
case 15 :
return {{778 , 783 }};
case 14 :
return {{556 , 561 }};
default :
__builtin_unreachable ();
Check warning
on line 370
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L367-L370
Added lines #L367 - L370 were not covered by tests
}
}
__builtin_unreachable ();
Check warning
on line 373
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L373
Added line #L373 was not covered by tests
}
[[nodiscard]] bool shouldRescaleBlackLevels (ColorDataFormat f,
Check warning
on line 376
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L376
Added line #L376 was not covered by tests
int colorDataVersion) {
return f != ColorDataFormat::ColorData5 || colorDataVersion != -3 ;
Check warning
on line 378
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L378
Added line #L378 was not covered by tests
}
} // namespace
bool Cr2Decoder::decodeCanonColorData () const {
const TiffEntry* wb = mRootIFD ->getEntryRecursive (TiffTag::CANONCOLORDATA);
if (!wb)
return false ;
auto f = deduceColorDataFormat (wb);
if (!f )
auto dsc = deduceColorDataFormat (wb);
if (!dsc )
return false ;
int offset = getWhiteBalanceOffsetInColorData (*f);
auto [f, ver] = *dsc;
int offset = getWhiteBalanceOffsetInColorData (f);
offset /= 2 ;
mRaw ->metadata .wbCoeffs [0 ] = static_cast <float >(wb->getU16 (offset + 0 ));
mRaw ->metadata .wbCoeffs [1 ] = static_cast <float >(wb->getU16 (offset + 1 ));
mRaw ->metadata .wbCoeffs [2 ] = static_cast <float >(wb->getU16 (offset + 3 ));
auto levelOffsets = getBlackAndWhiteLevelOffsetsInColorData (f, *ver);
if (!levelOffsets)
return false ;
Check warning
on line 403
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L403
Added line #L403 was not covered by tests
mRaw ->whitePoint = wb->getU16 (levelOffsets->second );
for (int c = 0 ; c != 4 ; ++c)
mRaw ->blackLevelSeparate [c] = wb->getU16 (c + levelOffsets->first );
// In Canon MakerNotes, the levels are always unscaled, and are 14-bit,
// and so if the LJpeg precision was lower, we need to adjust.
constexpr int makernotesPrecision = 14 ;
if (makernotesPrecision > ljpegSamplePrecision) {
int bitDepthDiff = makernotesPrecision - ljpegSamplePrecision;
assert (bitDepthDiff >= 1 && bitDepthDiff <= 12 );
Check warning
on line 414
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L413-L414
Added lines #L413 - L414 were not covered by tests
if (shouldRescaleBlackLevels (f, *ver)) {
for (int c = 0 ; c != 4 ; ++c)
mRaw ->blackLevelSeparate [c] >>= bitDepthDiff;
Check warning
on line 417
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L417
Added line #L417 was not covered by tests
}
mRaw ->whitePoint >>= bitDepthDiff;
Check warning
on line 419
in src/librawspeed/decoders/Cr2Decoder.cpp
View check run for this annotation
Codecov / codecov/patch
src/librawspeed/decoders/Cr2Decoder.cpp#L419
Added line #L419 was not covered by tests
}
return true ;
}
Expand Down
Expand Up
@@ -388,7 +485,11 @@
}
setMetaData (meta, mode, iso);
assert (mShiftUpScaleForExif == 0 || mShiftUpScaleForExif == 2 );
mRaw ->blackLevel <<= mShiftUpScaleForExif ;
if (mShiftUpScaleForExif ) {
mRaw ->blackLevel = 0 ;
for (int c = 0 ; c != 4 ; ++c)
mRaw ->blackLevelSeparate [c] = -1 ;
}
if (mShiftUpScaleForExif != 0 && isPowerOfTwo (1 + mRaw ->whitePoint ))
mRaw ->whitePoint = ((1 + mRaw ->whitePoint ) << mShiftUpScaleForExif ) - 1 ;
else
Expand Down