Suggest P3 for wide gamut images in SkAndroidCodec
This will prevent us from clipping the gamut to sRGB. BUG=skia: Change-Id: Ifc34369d96aa9dd92ae2af72aac1cfa17fdc4b94 Reviewed-on: https://skia-review.googlesource.com/8025 Commit-Queue: Matt Sarett <msarett@google.com> Reviewed-by: Leon Scroggins <scroggo@google.com>
This commit is contained in:
parent
3f405985be
commit
2ae3a2ec29
@ -79,9 +79,6 @@ public:
|
|||||||
* @param outputColorType Color type that the client will decode to
|
* @param outputColorType Color type that the client will decode to
|
||||||
*
|
*
|
||||||
* Returns the appropriate color space to decode to.
|
* Returns the appropriate color space to decode to.
|
||||||
*
|
|
||||||
* For now, this just returns a default. This could be updated to take
|
|
||||||
* requests for wide gamut modes or specific output spaces.
|
|
||||||
*/
|
*/
|
||||||
sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType);
|
sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType);
|
||||||
|
|
||||||
|
@ -17,6 +17,49 @@ static bool is_valid_sample_size(int sampleSize) {
|
|||||||
return sampleSize > 0;
|
return sampleSize > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the gamut as a set of three points (triangle).
|
||||||
|
*/
|
||||||
|
static void load_gamut(SkPoint rgb[], const SkMatrix44& xyz) {
|
||||||
|
// rx = rX / (rX + rY + rZ)
|
||||||
|
// ry = rY / (rX + rY + rZ)
|
||||||
|
// gx, gy, bx, and gy are calulcated similarly.
|
||||||
|
float rSum = xyz.get(0, 0) + xyz.get(1, 0) + xyz.get(2, 0);
|
||||||
|
float gSum = xyz.get(0, 1) + xyz.get(1, 1) + xyz.get(2, 1);
|
||||||
|
float bSum = xyz.get(0, 2) + xyz.get(1, 2) + xyz.get(2, 2);
|
||||||
|
rgb[0].fX = xyz.get(0, 0) / rSum;
|
||||||
|
rgb[0].fY = xyz.get(1, 0) / rSum;
|
||||||
|
rgb[1].fX = xyz.get(0, 1) / gSum;
|
||||||
|
rgb[1].fY = xyz.get(1, 1) / gSum;
|
||||||
|
rgb[2].fX = xyz.get(0, 2) / bSum;
|
||||||
|
rgb[2].fY = xyz.get(1, 2) / bSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the area of the triangular gamut.
|
||||||
|
*/
|
||||||
|
static float calculate_area(SkPoint abc[]) {
|
||||||
|
SkPoint a = abc[0];
|
||||||
|
SkPoint b = abc[1];
|
||||||
|
SkPoint c = abc[2];
|
||||||
|
return 0.5f * SkTAbs(a.fX*b.fY + b.fX*c.fY - a.fX*c.fY - c.fX*b.fY - b.fX*a.fY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const float kSRGB_D50_GamutArea = 0.084f;
|
||||||
|
|
||||||
|
static bool is_wide_gamut(const SkColorSpace* colorSpace) {
|
||||||
|
// Determine if the source image has a gamut that is wider than sRGB. If so, we
|
||||||
|
// will use P3 as the output color space to avoid clipping the gamut.
|
||||||
|
const SkMatrix44* toXYZD50 = as_CSB(colorSpace)->toXYZD50();
|
||||||
|
if (toXYZD50) {
|
||||||
|
SkPoint rgb[3];
|
||||||
|
load_gamut(rgb, *toXYZD50);
|
||||||
|
return calculate_area(rgb) > kSRGB_D50_GamutArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SkAndroidCodec::SkAndroidCodec(SkCodec* codec)
|
SkAndroidCodec::SkAndroidCodec(SkCodec* codec)
|
||||||
: fInfo(codec->getInfo())
|
: fInfo(codec->getInfo())
|
||||||
, fCodec(codec)
|
, fCodec(codec)
|
||||||
@ -131,6 +174,11 @@ sk_sp<SkColorSpace> SkAndroidCodec::computeOutputColorSpace(SkColorType outputCo
|
|||||||
case kRGBA_8888_SkColorType:
|
case kRGBA_8888_SkColorType:
|
||||||
case kBGRA_8888_SkColorType:
|
case kBGRA_8888_SkColorType:
|
||||||
case kIndex_8_SkColorType:
|
case kIndex_8_SkColorType:
|
||||||
|
if (is_wide_gamut(fCodec->getInfo().colorSpace())) {
|
||||||
|
return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
|
||||||
|
SkColorSpace::kDCIP3_D65_Gamut);
|
||||||
|
}
|
||||||
|
|
||||||
return SkColorSpace::MakeSRGB();
|
return SkColorSpace::MakeSRGB();
|
||||||
case kRGBA_F16_SkColorType:
|
case kRGBA_F16_SkColorType:
|
||||||
return SkColorSpace::MakeSRGBLinear();
|
return SkColorSpace::MakeSRGBLinear();
|
||||||
|
Loading…
Reference in New Issue
Block a user