Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Unified Diff: ui/gfx/color_transform.cc

Issue 2203213002: ICC profile color translations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@color_correction7
Patch Set: win compile fix Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/DEPS ('k') | ui/gfx/color_transform_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/color_transform.cc
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc
index f513d4de6d1763f2277b10ebda9f1d8177616d3b..7e5f05a7178a61582a7cb96fd2ad96109ce16442 100644
--- a/ui/gfx/color_transform.cc
+++ b/ui/gfx/color_transform.cc
@@ -8,7 +8,15 @@
#include "base/logging.h"
#include "ui/gfx/color_space.h"
+#include "ui/gfx/icc_profile.h"
#include "ui/gfx/transform.h"
+#include "third_party/qcms/src/qcms.h"
+
+#ifndef THIS_MUST_BE_INCLUDED_AFTER_QCMS_H
+extern "C" {
+#include "third_party/qcms/src/chain.h"
+};
+#endif
namespace gfx {
@@ -178,7 +186,7 @@ GFX_EXPORT Transform GetPrimaryMatrix(ColorSpace::PrimaryID id) {
dest_response.y() / source_response.y(),
dest_response.z() / source_response.z());
- return bradford * adapter * Invert(bradford) * ret;
+ return Invert(bradford) * adapter * bradford * ret;
}
GFX_EXPORT float FromLinear(ColorSpace::TransferID id, float v) {
@@ -547,14 +555,104 @@ class ColorSpaceToColorSpaceTransform : public ColorTransform {
Transform c_;
};
+class QCMSColorTransform : public ColorTransform {
+ public:
+ // Takes ownership of the profiles
+ QCMSColorTransform(qcms_profile* from, qcms_profile* to)
+ : from_(from), to_(to) {}
+ ~QCMSColorTransform() {
+ qcms_profile_release(from_);
+ qcms_profile_release(to_);
+ }
+ void transform(TriStim* colors, size_t num) override {
+ CHECK(sizeof(TriStim) == sizeof(float[3]));
+ // QCMS doesn't like numbers outside 0..1
+ for (size_t i = 0; i < num; i++) {
+ colors[i].set_x(fmin(1.0f, fmax(0.0f, colors[i].x())));
+ colors[i].set_y(fmin(1.0f, fmax(0.0f, colors[i].y())));
+ colors[i].set_z(fmin(1.0f, fmax(0.0f, colors[i].z())));
+ }
+ qcms_chain_transform(from_, to_, reinterpret_cast<float*>(colors),
+ reinterpret_cast<float*>(colors), num * 3);
+ }
+
+ private:
+ qcms_profile *from_, *to_;
+};
+
+class ChainColorTransform : public ColorTransform {
+ public:
+ ChainColorTransform(std::unique_ptr<ColorTransform> a,
+ std::unique_ptr<ColorTransform> b)
+ : a_(std::move(a)), b_(std::move(b)) {}
+
+ private:
+ void transform(TriStim* colors, size_t num) override {
+ a_->transform(colors, num);
+ b_->transform(colors, num);
+ }
+ std::unique_ptr<ColorTransform> a_;
+ std::unique_ptr<ColorTransform> b_;
+};
+
+qcms_profile* GetQCMSProfileIfAvailable(const ColorSpace& color_space) {
+ ICCProfile icc_profile = ICCProfile::FromColorSpace(color_space);
+ if (icc_profile.GetData().empty())
+ return nullptr;
+ return qcms_profile_from_memory(icc_profile.GetData().data(),
+ icc_profile.GetData().size());
+}
+
+qcms_profile* GetXYZD50Profile() {
+ // QCMS is trixy, it has a datatype called qcms_CIE_xyY, but what it expects
+ // is in fact not xyY color coordinates, it just wants the x/y values of the
+ // primaries with Y equal to 1.0.
+ qcms_CIE_xyYTRIPLE xyz;
+ qcms_CIE_xyY w;
+ xyz.red.x = 1.0f;
+ xyz.red.y = 0.0f;
+ xyz.red.Y = 1.0f;
+ xyz.green.x = 0.0f;
+ xyz.green.y = 1.0f;
+ xyz.green.Y = 1.0f;
+ xyz.blue.x = 0.0f;
+ xyz.blue.y = 0.0f;
+ xyz.blue.Y = 1.0f;
+ w.x = 0.34567f;
+ w.y = 0.35850f;
+ w.Y = 1.0f;
+ return qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f);
+}
+
std::unique_ptr<ColorTransform> ColorTransform::NewColorTransform(
const ColorSpace& from,
const ColorSpace& to,
Intent intent) {
- // TODO(Hubbe): Check if from and/or to can be mapped to ICC profiles and
- // provide better transforms in those cases.
- return std::unique_ptr<ColorTransform>(
- new ColorSpaceToColorSpaceTransform(from, to, intent));
+ qcms_profile* from_profile = GetQCMSProfileIfAvailable(from);
+ qcms_profile* to_profile = GetQCMSProfileIfAvailable(to);
+ if (from_profile) {
+ if (to_profile) {
+ return std::unique_ptr<ColorTransform>(
+ new QCMSColorTransform(from_profile, to_profile));
+ } else {
+ return std::unique_ptr<ColorTransform>(new ChainColorTransform(
+ std::unique_ptr<ColorTransform>(
+ new QCMSColorTransform(from_profile, GetXYZD50Profile())),
+ std::unique_ptr<ColorTransform>(new ColorSpaceToColorSpaceTransform(
+ ColorSpace::CreateXYZD50(), to, intent))));
+ }
+ } else {
+ if (to_profile) {
+ return std::unique_ptr<ColorTransform>(new ChainColorTransform(
+ std::unique_ptr<ColorTransform>(new ColorSpaceToColorSpaceTransform(
+ from, ColorSpace::CreateXYZD50(), intent)),
+ std::unique_ptr<ColorTransform>(
+ new QCMSColorTransform(GetXYZD50Profile(), to_profile))));
+ } else {
+ return std::unique_ptr<ColorTransform>(
+ new ColorSpaceToColorSpaceTransform(from, to, intent));
+ }
+ }
}
} // namespace gfx
« no previous file with comments | « ui/gfx/DEPS ('k') | ui/gfx/color_transform_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698