| Index: ui/gfx/color_transform.cc
|
| diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc
|
| index c6a114e94cdb471e8ab33fa5c7e0ffa48adcb857..1467ad23141a8bba38a3a9be75e247dc63f76c60 100644
|
| --- a/ui/gfx/color_transform.cc
|
| +++ b/ui/gfx/color_transform.cc
|
| @@ -652,7 +652,7 @@ class ColorSpaceToColorSpaceTransform : public ColorTransform {
|
| }
|
| }
|
|
|
| - void transform(TriStim* colors, size_t num) override {
|
| + void transform(TriStim* colors, size_t num) const override {
|
| for (size_t i = 0; i < num; i++) {
|
| TriStim c = colors[i];
|
| a_.TransformPoint(&c);
|
| @@ -685,7 +685,7 @@ class QCMSColorTransform : public ColorTransform {
|
| qcms_profile_release(from_);
|
| qcms_profile_release(to_);
|
| }
|
| - void transform(TriStim* colors, size_t num) override {
|
| + void transform(TriStim* colors, size_t num) const override {
|
| CHECK(sizeof(TriStim) == sizeof(float[3]));
|
| // QCMS doesn't like numbers outside 0..1
|
| for (size_t i = 0; i < num; i++) {
|
| @@ -708,7 +708,7 @@ class ChainColorTransform : public ColorTransform {
|
| : a_(std::move(a)), b_(std::move(b)) {}
|
|
|
| private:
|
| - void transform(TriStim* colors, size_t num) override {
|
| + void transform(TriStim* colors, size_t num) const override {
|
| a_->transform(colors, num);
|
| b_->transform(colors, num);
|
| }
|
| @@ -776,4 +776,81 @@ std::unique_ptr<ColorTransform> ColorTransform::NewColorTransform(
|
| }
|
| }
|
|
|
| +namespace {
|
| +
|
| +float TriStimChannel(const ColorTransform::TriStim& t, int c) {
|
| + switch (c) {
|
| + case 0:
|
| + return t.x();
|
| + case 1:
|
| + return t.y();
|
| + case 2:
|
| + return t.z();
|
| + case 3:
|
| + return 1.0f;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| + return 0.0f;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +bool ColorTransform::GetAffineApproximation(Transform* transform) const {
|
| + const int num_points = 4;
|
| + std::vector<TriStim> input(num_points * num_points * num_points);
|
| + int i = 0;
|
| + float offset = 0.1;
|
| + float mult = 0.8 / num_points;
|
| + for (int x = 0; x < num_points; x++) {
|
| + for (int y = 0; y < num_points; y++) {
|
| + for (int z = 0; z < num_points; z++) {
|
| + input[i++] = ColorTransform::TriStim(
|
| + offset + x * mult, offset + y * mult, offset + z * mult);
|
| + }
|
| + }
|
| + }
|
| +
|
| + std::vector<TriStim> output(input);
|
| + this->transform(output.data(), output.size());
|
| + SkMatrix44 XtX;
|
| + for (int x = 0; x < 4; x++) {
|
| + for (int y = 0; y < 4; y++) {
|
| + double tmp = 0.0;
|
| + for (int z = 0; z < num_points * num_points * num_points; z++) {
|
| + tmp += TriStimChannel(input[z], x) * TriStimChannel(input[z], y);
|
| + }
|
| + XtX.setDouble(x, y, tmp);
|
| + }
|
| + }
|
| +
|
| + SkMatrix44 XtXinv;
|
| + if (!XtX.invert(&XtXinv))
|
| + return false;
|
| +
|
| + SkVector4 results[4];
|
| +
|
| + for (int x = 0; x < 4; x++) {
|
| + double Xty[4];
|
| + for (int y = 0; y < 4; y++) {
|
| + double tmp = 0.0;
|
| + for (int z = 0; z < num_points * num_points * num_points; z++) {
|
| + tmp += TriStimChannel(output[z], x) * TriStimChannel(input[z], y);
|
| + }
|
| + Xty[y] = tmp;
|
| + }
|
| + results[x] = XtXinv * SkVector4(Xty[0], Xty[1], Xty[2], Xty[3]);
|
| + }
|
| +
|
| + *transform =
|
| + Transform(results[0].fData[0], results[0].fData[1], results[0].fData[2],
|
| + results[0].fData[3], results[1].fData[0], results[1].fData[1],
|
| + results[1].fData[2], results[1].fData[3], results[2].fData[0],
|
| + results[2].fData[1], results[2].fData[2], results[2].fData[3],
|
| + results[3].fData[0], results[3].fData[1], results[3].fData[2],
|
| + results[3].fData[3]);
|
| + return true;
|
| +}
|
| +
|
| } // namespace gfx
|
|
|