| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/color_transform.h" | 5 #include "ui/gfx/color_transform.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <list> | 9 #include <list> |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/strings/stringprintf.h" |
| 14 #include "third_party/qcms/src/qcms.h" | 15 #include "third_party/qcms/src/qcms.h" |
| 15 #include "ui/gfx/color_space.h" | 16 #include "ui/gfx/color_space.h" |
| 16 #include "ui/gfx/icc_profile.h" | 17 #include "ui/gfx/icc_profile.h" |
| 17 #include "ui/gfx/skia_color_space_util.h" | 18 #include "ui/gfx/skia_color_space_util.h" |
| 18 #include "ui/gfx/transform.h" | 19 #include "ui/gfx/transform.h" |
| 19 | 20 |
| 20 #ifndef THIS_MUST_BE_INCLUDED_AFTER_QCMS_H | 21 #ifndef THIS_MUST_BE_INCLUDED_AFTER_QCMS_H |
| 21 extern "C" { | 22 extern "C" { |
| 22 #include "third_party/qcms/src/chain.h" | 23 #include "third_party/qcms/src/chain.h" |
| 23 }; | 24 }; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 virtual ColorTransformNull* GetNull() { return nullptr; } | 244 virtual ColorTransformNull* GetNull() { return nullptr; } |
| 244 virtual QCMSColorTransform* GetQCMS() { return nullptr; } | 245 virtual QCMSColorTransform* GetQCMS() { return nullptr; } |
| 245 | 246 |
| 246 // Join methods, returns true if the |next| transform was successfully | 247 // Join methods, returns true if the |next| transform was successfully |
| 247 // assimilated into |this|. | 248 // assimilated into |this|. |
| 248 // If Join() returns true, |next| is no longer needed and can be deleted. | 249 // If Join() returns true, |next| is no longer needed and can be deleted. |
| 249 virtual bool Join(ColorTransformStep* next) { return false; } | 250 virtual bool Join(ColorTransformStep* next) { return false; } |
| 250 | 251 |
| 251 // Return true if this is a null transform. | 252 // Return true if this is a null transform. |
| 252 virtual bool IsNull() { return false; } | 253 virtual bool IsNull() { return false; } |
| 253 | 254 virtual void Transform(ColorTransform::TriStim* color, size_t num) const = 0; |
| 254 virtual void Transform(ColorTransform::TriStim* color, size_t num) = 0; | 255 virtual bool CanAppendShaderSource() { return false; } |
| 256 virtual void AppendShaderSource(std::string* result) { NOTREACHED(); } |
| 255 | 257 |
| 256 private: | 258 private: |
| 257 DISALLOW_COPY_AND_ASSIGN(ColorTransformStep); | 259 DISALLOW_COPY_AND_ASSIGN(ColorTransformStep); |
| 258 }; | 260 }; |
| 259 | 261 |
| 260 class ColorTransformInternal : public ColorTransform { | 262 class ColorTransformInternal : public ColorTransform { |
| 261 public: | 263 public: |
| 262 ColorTransformInternal(const ColorSpace& from, | 264 ColorTransformInternal(const ColorSpace& from, |
| 263 const ColorSpace& to, | 265 const ColorSpace& to, |
| 264 Intent intent); | 266 Intent intent); |
| 265 ~ColorTransformInternal() override; | 267 ~ColorTransformInternal() override; |
| 266 | 268 |
| 267 // Perform transformation of colors, |colors| is both input and output. | 269 gfx::ColorSpace GetSrcColorSpace() const override { return src_; }; |
| 268 void Transform(TriStim* colors, size_t num) override { | 270 gfx::ColorSpace GetDstColorSpace() const override { return dst_; }; |
| 271 |
| 272 void Transform(TriStim* colors, size_t num) const override { |
| 269 for (const auto& step : steps_) | 273 for (const auto& step : steps_) |
| 270 step->Transform(colors, num); | 274 step->Transform(colors, num); |
| 271 } | 275 } |
| 276 bool CanGetShaderSource() const override; |
| 277 std::string GetShaderSource() const override; |
| 278 bool IsIdentity() const override { return steps_.empty(); } |
| 272 size_t NumberOfStepsForTesting() const override { return steps_.size(); } | 279 size_t NumberOfStepsForTesting() const override { return steps_.size(); } |
| 273 | 280 |
| 274 private: | 281 private: |
| 275 void AppendColorSpaceToColorSpaceTransform(ColorSpace from, | 282 void AppendColorSpaceToColorSpaceTransform(ColorSpace from, |
| 276 const ColorSpace& to, | 283 const ColorSpace& to, |
| 277 ColorTransform::Intent intent); | 284 ColorTransform::Intent intent); |
| 278 void Simplify(); | 285 void Simplify(); |
| 279 | 286 |
| 280 // Retrieve the ICC profile from which |color_space| was created, only if that | 287 // Retrieve the ICC profile from which |color_space| was created, only if that |
| 281 // is a more precise representation of the color space than the primaries and | 288 // is a more precise representation of the color space than the primaries and |
| 282 // transfer function in |color_space|. | 289 // transfer function in |color_space|. |
| 283 ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space); | 290 ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space); |
| 284 | 291 |
| 285 std::list<std::unique_ptr<ColorTransformStep>> steps_; | 292 std::list<std::unique_ptr<ColorTransformStep>> steps_; |
| 293 gfx::ColorSpace src_; |
| 294 gfx::ColorSpace dst_; |
| 286 }; | 295 }; |
| 287 | 296 |
| 297 #define SRC(...) \ |
| 298 do { \ |
| 299 *result += std::string(" ") + base::StringPrintf(__VA_ARGS__) + \ |
| 300 std::string("\n"); \ |
| 301 } while (0) |
| 302 |
| 288 class ColorTransformNull : public ColorTransformStep { | 303 class ColorTransformNull : public ColorTransformStep { |
| 289 public: | 304 public: |
| 290 ColorTransformNull* GetNull() override { return this; } | 305 ColorTransformNull* GetNull() override { return this; } |
| 291 bool IsNull() override { return true; } | 306 bool IsNull() override { return true; } |
| 292 void Transform(ColorTransform::TriStim* color, size_t num) override {} | 307 void Transform(ColorTransform::TriStim* color, size_t num) const override {} |
| 308 bool CanAppendShaderSource() override { return true; } |
| 309 void AppendShaderSource(std::string* result) override {} |
| 293 }; | 310 }; |
| 294 | 311 |
| 295 class ColorTransformMatrix : public ColorTransformStep { | 312 class ColorTransformMatrix : public ColorTransformStep { |
| 296 public: | 313 public: |
| 297 explicit ColorTransformMatrix(const class Transform& matrix) | 314 explicit ColorTransformMatrix(const class Transform& matrix) |
| 298 : matrix_(matrix) {} | 315 : matrix_(matrix) {} |
| 299 ColorTransformMatrix* GetMatrix() override { return this; } | 316 ColorTransformMatrix* GetMatrix() override { return this; } |
| 300 bool Join(ColorTransformStep* next_untyped) override { | 317 bool Join(ColorTransformStep* next_untyped) override { |
| 301 ColorTransformMatrix* next = next_untyped->GetMatrix(); | 318 ColorTransformMatrix* next = next_untyped->GetMatrix(); |
| 302 if (!next) | 319 if (!next) |
| 303 return false; | 320 return false; |
| 304 class Transform tmp = next->matrix_; | 321 class Transform tmp = next->matrix_; |
| 305 tmp *= matrix_; | 322 tmp *= matrix_; |
| 306 matrix_ = tmp; | 323 matrix_ = tmp; |
| 307 return true; | 324 return true; |
| 308 } | 325 } |
| 309 | 326 |
| 310 bool IsNull() override { | 327 bool IsNull() override { |
| 311 return SkMatrixIsApproximatelyIdentity(matrix_.matrix()); | 328 return SkMatrixIsApproximatelyIdentity(matrix_.matrix()); |
| 312 } | 329 } |
| 313 | 330 |
| 314 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 331 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
| 315 for (size_t i = 0; i < num; i++) | 332 for (size_t i = 0; i < num; i++) |
| 316 matrix_.TransformPoint(colors + i); | 333 matrix_.TransformPoint(colors + i); |
| 317 } | 334 } |
| 318 | 335 |
| 336 bool CanAppendShaderSource() override { return true; } |
| 337 |
| 338 void AppendShaderSource(std::string* result) override { |
| 339 const SkMatrix44& m = matrix_.matrix(); |
| 340 SRC("color = mat3(%1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, " |
| 341 "%1.8e) * color;", |
| 342 m.get(0, 0), m.get(1, 0), m.get(2, 0), // column 1 |
| 343 m.get(0, 1), m.get(1, 1), m.get(2, 1), // column 2 |
| 344 m.get(0, 2), m.get(1, 2), m.get(2, 2)); // column 3 |
| 345 SRC("color += vec3(%1.8e, %1.8e, %1.8e);", m.get(0, 3), m.get(1, 3), |
| 346 m.get(2, 3)); |
| 347 } |
| 348 |
| 319 private: | 349 private: |
| 320 class Transform matrix_; | 350 class Transform matrix_; |
| 321 }; | 351 }; |
| 322 | 352 |
| 323 class ColorTransformFromLinear : public ColorTransformStep { | 353 class ColorTransformFromLinear : public ColorTransformStep { |
| 324 public: | 354 public: |
| 325 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer, | 355 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer, |
| 326 const SkColorSpaceTransferFn& fn, | 356 const SkColorSpaceTransferFn& fn, |
| 327 bool fn_valid) | 357 bool fn_valid) |
| 328 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) { | 358 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) { |
| 329 if (transfer_ == ColorSpace::TransferID::LINEAR_HDR) | 359 if (transfer_ == ColorSpace::TransferID::LINEAR_HDR) |
| 330 transfer_ = ColorSpace::TransferID::LINEAR; | 360 transfer_ = ColorSpace::TransferID::LINEAR; |
| 331 } | 361 } |
| 332 ColorTransformFromLinear* GetFromLinear() override { return this; } | 362 ColorTransformFromLinear* GetFromLinear() override { return this; } |
| 333 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } | 363 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } |
| 334 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 364 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
| 335 if (fn_valid_) { | 365 if (fn_valid_) { |
| 336 for (size_t i = 0; i < num; i++) { | 366 for (size_t i = 0; i < num; i++) { |
| 337 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); | 367 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); |
| 338 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); | 368 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); |
| 339 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); | 369 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); |
| 340 } | 370 } |
| 341 } else { | 371 } else { |
| 342 for (size_t i = 0; i < num; i++) { | 372 for (size_t i = 0; i < num; i++) { |
| 343 colors[i].set_x(FromLinear(transfer_, colors[i].x())); | 373 colors[i].set_x(FromLinear(transfer_, colors[i].x())); |
| 344 colors[i].set_y(FromLinear(transfer_, colors[i].y())); | 374 colors[i].set_y(FromLinear(transfer_, colors[i].y())); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 return false; | 422 return false; |
| 393 } | 423 } |
| 394 | 424 |
| 395 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } | 425 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } |
| 396 | 426 |
| 397 // Assumes BT2020 primaries. | 427 // Assumes BT2020 primaries. |
| 398 static float Luma(const ColorTransform::TriStim& c) { | 428 static float Luma(const ColorTransform::TriStim& c) { |
| 399 return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f; | 429 return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f; |
| 400 } | 430 } |
| 401 | 431 |
| 402 ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { | 432 static ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { |
| 403 float maximum = max(max(c.x(), c.y()), c.z()); | 433 float maximum = max(max(c.x(), c.y()), c.z()); |
| 404 if (maximum > 1.0f) { | 434 if (maximum > 1.0f) { |
| 405 float l = Luma(c); | 435 float l = Luma(c); |
| 406 c.Scale(1.0f / maximum); | 436 c.Scale(1.0f / maximum); |
| 407 ColorTransform::TriStim white(1.0f, 1.0f, 1.0f); | 437 ColorTransform::TriStim white(1.0f, 1.0f, 1.0f); |
| 408 white.Scale((1.0f - 1.0f / maximum) * l / Luma(white)); | 438 white.Scale((1.0f - 1.0f / maximum) * l / Luma(white)); |
| 409 ColorTransform::TriStim black(0.0f, 0.0f, 0.0f); | 439 ColorTransform::TriStim black(0.0f, 0.0f, 0.0f); |
| 410 c += white - black; | 440 c += white - black; |
| 411 } | 441 } |
| 412 return c; | 442 return c; |
| 413 } | 443 } |
| 414 | 444 |
| 415 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 445 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
| 416 if (fn_valid_) { | 446 if (fn_valid_) { |
| 417 for (size_t i = 0; i < num; i++) { | 447 for (size_t i = 0; i < num; i++) { |
| 418 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); | 448 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); |
| 419 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); | 449 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); |
| 420 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); | 450 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); |
| 421 } | 451 } |
| 422 } else if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) { | 452 } else if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) { |
| 423 for (size_t i = 0; i < num; i++) { | 453 for (size_t i = 0; i < num; i++) { |
| 424 ColorTransform::TriStim ret(ToLinear(transfer_, colors[i].x()), | 454 ColorTransform::TriStim ret(ToLinear(transfer_, colors[i].x()), |
| 425 ToLinear(transfer_, colors[i].y()), | 455 ToLinear(transfer_, colors[i].y()), |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 if (!next) | 499 if (!next) |
| 470 return false; | 500 return false; |
| 471 if (null_) | 501 if (null_) |
| 472 return false; | 502 return false; |
| 473 null_ = true; | 503 null_ = true; |
| 474 return true; | 504 return true; |
| 475 } | 505 } |
| 476 | 506 |
| 477 bool IsNull() override { return null_; } | 507 bool IsNull() override { return null_; } |
| 478 | 508 |
| 479 void Transform(ColorTransform::TriStim* RYB, size_t num) override { | 509 void Transform(ColorTransform::TriStim* RYB, size_t num) const override { |
| 480 for (size_t i = 0; i < num; i++) { | 510 for (size_t i = 0; i < num; i++) { |
| 481 float U, V; | 511 float U, V; |
| 482 float B_Y = RYB[i].z() - RYB[i].y(); | 512 float B_Y = RYB[i].z() - RYB[i].y(); |
| 483 if (B_Y <= 0) { | 513 if (B_Y <= 0) { |
| 484 U = B_Y / (-2.0 * -0.9702); | 514 U = B_Y / (-2.0 * -0.9702); |
| 485 } else { | 515 } else { |
| 486 U = B_Y / (2.0 * 0.7910); | 516 U = B_Y / (2.0 * 0.7910); |
| 487 } | 517 } |
| 488 float R_Y = RYB[i].x() - RYB[i].y(); | 518 float R_Y = RYB[i].x() - RYB[i].y(); |
| 489 if (R_Y <= 0) { | 519 if (R_Y <= 0) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 507 if (!next) | 537 if (!next) |
| 508 return false; | 538 return false; |
| 509 if (null_) | 539 if (null_) |
| 510 return false; | 540 return false; |
| 511 null_ = true; | 541 null_ = true; |
| 512 return true; | 542 return true; |
| 513 } | 543 } |
| 514 | 544 |
| 515 bool IsNull() override { return null_; } | 545 bool IsNull() override { return null_; } |
| 516 | 546 |
| 517 void Transform(ColorTransform::TriStim* YUV, size_t num) override { | 547 void Transform(ColorTransform::TriStim* YUV, size_t num) const override { |
| 518 if (null_) | 548 if (null_) |
| 519 return; | 549 return; |
| 520 for (size_t i = 0; i < num; i++) { | 550 for (size_t i = 0; i < num; i++) { |
| 521 float Y = YUV[i].x(); | 551 float Y = YUV[i].x(); |
| 522 float U = YUV[i].y(); | 552 float U = YUV[i].y(); |
| 523 float V = YUV[i].z(); | 553 float V = YUV[i].z(); |
| 524 float B_Y, R_Y; | 554 float B_Y, R_Y; |
| 525 if (U <= 0) { | 555 if (U <= 0) { |
| 526 B_Y = Y * (-2.0 * -0.9702); | 556 B_Y = Y * (-2.0 * -0.9702); |
| 527 } else { | 557 } else { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 | 610 |
| 581 // TODO(hubbe): shrink gamuts here (never stretch gamuts) | 611 // TODO(hubbe): shrink gamuts here (never stretch gamuts) |
| 582 } | 612 } |
| 583 | 613 |
| 584 steps_.push_back( | 614 steps_.push_back( |
| 585 base::MakeUnique<ColorTransformMatrix>(GetRangeAdjustMatrix(from))); | 615 base::MakeUnique<ColorTransformMatrix>(GetRangeAdjustMatrix(from))); |
| 586 | 616 |
| 587 steps_.push_back( | 617 steps_.push_back( |
| 588 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); | 618 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); |
| 589 | 619 |
| 620 // If the target color space is not defined, just apply the adjust and |
| 621 // tranfer matrices. |
| 622 if (!to.IsValid()) |
| 623 return; |
| 624 |
| 590 SkColorSpaceTransferFn to_linear_fn; | 625 SkColorSpaceTransferFn to_linear_fn; |
| 591 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); | 626 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); |
| 592 steps_.push_back(base::MakeUnique<ColorTransformToLinear>( | 627 steps_.push_back(base::MakeUnique<ColorTransformToLinear>( |
| 593 from.transfer_, to_linear_fn, to_linear_fn_valid)); | 628 from.transfer_, to_linear_fn, to_linear_fn_valid)); |
| 594 | 629 |
| 595 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { | 630 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { |
| 596 // BT2020 CL is a special case. | 631 // BT2020 CL is a special case. |
| 597 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>()); | 632 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>()); |
| 598 } | 633 } |
| 599 steps_.push_back( | 634 steps_.push_back( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 to_ = std::move(next->to_); | 668 to_ = std::move(next->to_); |
| 634 return true; | 669 return true; |
| 635 } | 670 } |
| 636 return false; | 671 return false; |
| 637 } | 672 } |
| 638 bool IsNull() override { | 673 bool IsNull() override { |
| 639 if (qcms_profile_match(from_.get(), to_.get())) | 674 if (qcms_profile_match(from_.get(), to_.get())) |
| 640 return true; | 675 return true; |
| 641 return false; | 676 return false; |
| 642 } | 677 } |
| 643 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 678 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
| 644 CHECK(sizeof(ColorTransform::TriStim) == sizeof(float[3])); | 679 CHECK(sizeof(ColorTransform::TriStim) == sizeof(float[3])); |
| 645 // QCMS doesn't like numbers outside 0..1 | 680 // QCMS doesn't like numbers outside 0..1 |
| 646 for (size_t i = 0; i < num; i++) { | 681 for (size_t i = 0; i < num; i++) { |
| 647 colors[i].set_x(min(1.0f, max(0.0f, colors[i].x()))); | 682 colors[i].set_x(min(1.0f, max(0.0f, colors[i].x()))); |
| 648 colors[i].set_y(min(1.0f, max(0.0f, colors[i].y()))); | 683 colors[i].set_y(min(1.0f, max(0.0f, colors[i].y()))); |
| 649 colors[i].set_z(min(1.0f, max(0.0f, colors[i].z()))); | 684 colors[i].set_z(min(1.0f, max(0.0f, colors[i].z()))); |
| 650 } | 685 } |
| 651 qcms_chain_transform(from_.get(), to_.get(), | 686 qcms_chain_transform(from_.get(), to_.get(), |
| 652 reinterpret_cast<float*>(colors), | 687 reinterpret_cast<float*>(colors), |
| 653 reinterpret_cast<float*>(colors), num * 3); | 688 reinterpret_cast<float*>(colors), num * 3); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 681 xyz.green.Y = 1.0f; | 716 xyz.green.Y = 1.0f; |
| 682 xyz.blue.x = 0.0f; | 717 xyz.blue.x = 0.0f; |
| 683 xyz.blue.y = 0.0f; | 718 xyz.blue.y = 0.0f; |
| 684 xyz.blue.Y = 1.0f; | 719 xyz.blue.Y = 1.0f; |
| 685 w.x = 0.34567f; | 720 w.x = 0.34567f; |
| 686 w.y = 0.35850f; | 721 w.y = 0.35850f; |
| 687 w.Y = 1.0f; | 722 w.Y = 1.0f; |
| 688 return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); | 723 return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); |
| 689 } | 724 } |
| 690 | 725 |
| 691 ColorTransformInternal::ColorTransformInternal(const ColorSpace& from, | 726 ColorTransformInternal::ColorTransformInternal(const ColorSpace& src, |
| 692 const ColorSpace& to, | 727 const ColorSpace& dst, |
| 693 Intent intent) { | 728 Intent intent) |
| 729 : src_(src), dst_(dst) { |
| 694 // If no source color space is specified, do no transformation. | 730 // If no source color space is specified, do no transformation. |
| 695 // TODO(ccameron): We may want to assume sRGB at some point in the future. | 731 // TODO(ccameron): We may want dst assume sRGB at some point in the future. |
| 696 if (!from.IsValid()) | 732 if (!src_.IsValid()) |
| 697 return; | 733 return; |
| 698 | 734 |
| 699 ScopedQcmsProfile from_profile = GetQCMSProfileIfNecessary(from); | 735 ScopedQcmsProfile src_profile = GetQCMSProfileIfNecessary(src_); |
| 700 ScopedQcmsProfile to_profile = GetQCMSProfileIfNecessary(to); | 736 ScopedQcmsProfile dst_profile = GetQCMSProfileIfNecessary(dst_); |
| 701 bool has_from_profile = !!from_profile; | 737 bool has_src_profile = !!src_profile; |
| 702 bool has_to_profile = !!to_profile; | 738 bool has_dst_profile = !!dst_profile; |
| 703 | 739 |
| 704 if (from_profile) { | 740 if (src_profile) { |
| 705 steps_.push_back(base::MakeUnique<QCMSColorTransform>( | 741 steps_.push_back(base::MakeUnique<QCMSColorTransform>( |
| 706 std::move(from_profile), GetXYZD50Profile())); | 742 std::move(src_profile), GetXYZD50Profile())); |
| 707 } | 743 } |
| 708 | 744 |
| 709 AppendColorSpaceToColorSpaceTransform( | 745 AppendColorSpaceToColorSpaceTransform( |
| 710 has_from_profile ? ColorSpace::CreateXYZD50() : from, | 746 has_src_profile ? ColorSpace::CreateXYZD50() : src_, |
| 711 has_to_profile ? ColorSpace::CreateXYZD50() : to, intent); | 747 has_dst_profile ? ColorSpace::CreateXYZD50() : dst_, intent); |
| 712 | 748 |
| 713 if (to_profile) { | 749 if (dst_profile) { |
| 714 steps_.push_back(base::MakeUnique<QCMSColorTransform>( | 750 steps_.push_back(base::MakeUnique<QCMSColorTransform>( |
| 715 GetXYZD50Profile(), std::move(to_profile))); | 751 GetXYZD50Profile(), std::move(dst_profile))); |
| 716 } | 752 } |
| 717 | 753 |
| 718 if (intent != Intent::TEST_NO_OPT) | 754 if (intent != Intent::TEST_NO_OPT) |
| 719 Simplify(); | 755 Simplify(); |
| 720 } | 756 } |
| 721 | 757 |
| 758 std::string ColorTransformInternal::GetShaderSource() const { |
| 759 std::string result; |
| 760 result += "vec3 DoColorConversion(vec3 color) {\n"; |
| 761 for (const auto& step : steps_) |
| 762 step->AppendShaderSource(&result); |
| 763 result += " return color;\n"; |
| 764 result += "}\n"; |
| 765 return result; |
| 766 } |
| 767 |
| 768 bool ColorTransformInternal::CanGetShaderSource() const { |
| 769 for (const auto& step : steps_) { |
| 770 if (!step->CanAppendShaderSource()) |
| 771 return false; |
| 772 } |
| 773 return true; |
| 774 } |
| 775 |
| 722 ColorTransformInternal::~ColorTransformInternal() {} | 776 ColorTransformInternal::~ColorTransformInternal() {} |
| 723 | 777 |
| 724 void ColorTransformInternal::Simplify() { | 778 void ColorTransformInternal::Simplify() { |
| 725 for (auto iter = steps_.begin(); iter != steps_.end();) { | 779 for (auto iter = steps_.begin(); iter != steps_.end();) { |
| 726 std::unique_ptr<ColorTransformStep>& this_step = *iter; | 780 std::unique_ptr<ColorTransformStep>& this_step = *iter; |
| 727 | 781 |
| 728 // Try to Join |next_step| into |this_step|. If successful, re-visit the | 782 // Try to Join |next_step| into |this_step|. If successful, re-visit the |
| 729 // step before |this_step|. | 783 // step before |this_step|. |
| 730 auto iter_next = iter; | 784 auto iter_next = iter; |
| 731 iter_next++; | 785 iter_next++; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 758 const ColorSpace& to, | 812 const ColorSpace& to, |
| 759 Intent intent) { | 813 Intent intent) { |
| 760 return std::unique_ptr<ColorTransform>( | 814 return std::unique_ptr<ColorTransform>( |
| 761 new ColorTransformInternal(from, to, intent)); | 815 new ColorTransformInternal(from, to, intent)); |
| 762 } | 816 } |
| 763 | 817 |
| 764 ColorTransform::ColorTransform() {} | 818 ColorTransform::ColorTransform() {} |
| 765 ColorTransform::~ColorTransform() {} | 819 ColorTransform::~ColorTransform() {} |
| 766 | 820 |
| 767 } // namespace gfx | 821 } // namespace gfx |
| OLD | NEW |