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 <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 } | 185 } |
186 | 186 |
187 default: | 187 default: |
188 // Handled by SkColorSpaceTransferFn. | 188 // Handled by SkColorSpaceTransferFn. |
189 break; | 189 break; |
190 } | 190 } |
191 NOTREACHED(); | 191 NOTREACHED(); |
192 return 0; | 192 return 0; |
193 } | 193 } |
194 | 194 |
195 GFX_EXPORT Transform GetTransferMatrix(ColorSpace::MatrixID id) { | 195 Transform GetTransferMatrix(const gfx::ColorSpace& color_space) { |
196 // Default values for BT709; | 196 SkMatrix44 transfer_matrix; |
197 float Kr = 0.2126f; | 197 color_space.GetTransferMatrix(&transfer_matrix); |
198 float Kb = 0.0722f; | 198 return Transform(transfer_matrix); |
199 switch (id) { | |
200 case ColorSpace::MatrixID::RGB: | |
201 return Transform(); | |
202 | |
203 case ColorSpace::MatrixID::BT709: | |
204 case ColorSpace::MatrixID::UNSPECIFIED: | |
205 case ColorSpace::MatrixID::RESERVED: | |
206 case ColorSpace::MatrixID::UNKNOWN: | |
207 // Default values are already set. | |
208 break; | |
209 | |
210 case ColorSpace::MatrixID::FCC: | |
211 Kr = 0.30f; | |
212 Kb = 0.11f; | |
213 break; | |
214 | |
215 case ColorSpace::MatrixID::BT470BG: | |
216 case ColorSpace::MatrixID::SMPTE170M: | |
217 Kr = 0.299f; | |
218 Kb = 0.144f; | |
219 break; | |
220 | |
221 case ColorSpace::MatrixID::SMPTE240M: | |
222 Kr = 0.212f; | |
223 Kb = 0.087f; | |
224 break; | |
225 | |
226 case ColorSpace::MatrixID::YCOCG: | |
227 return Transform(0.25f, 0.5f, 0.25f, 0.5f, // 1 | |
228 -0.25f, 0.5f, -0.25f, 0.5f, // 2 | |
229 0.5f, 0.0f, -0.5f, 0.0f, // 3 | |
230 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
231 | |
232 case ColorSpace::MatrixID::BT2020_NCL: | |
233 Kr = 0.2627f; | |
234 Kb = 0.0593f; | |
235 break; | |
236 | |
237 // BT2020_CL is a special case. | |
238 // Basically we return a matrix that transforms RGB values | |
239 // to RYB values. (We replace the green component with the | |
240 // the luminance.) Later steps will compute the Cb & Cr values. | |
241 case ColorSpace::MatrixID::BT2020_CL: | |
242 Kr = 0.2627f; | |
243 Kb = 0.0593f; | |
244 return Transform(1.0f, 0.0f, 0.0f, 0.0f, // R | |
245 Kr, 1.0f - Kr - Kb, Kb, 0.0f, // Y | |
246 0.0f, 0.0f, 1.0f, 0.0f, // B | |
247 0.0f, 0.0f, 0.0f, 1.0f); | |
248 | |
249 case ColorSpace::MatrixID::YDZDX: | |
250 return Transform(0.0f, 1.0f, 0.0f, 0.0f, // 1 | |
251 0.0f, -0.5f, 0.986566f / 2.0f, 0.5f, // 2 | |
252 0.5f, -0.991902f / 2.0f, 0.0f, 0.5f, // 3 | |
253 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
254 } | |
255 float u_m = 0.5f / (1.0f - Kb); | |
256 float v_m = 0.5f / (1.0f - Kr); | |
257 return Transform( | |
258 Kr, 1.0f - Kr - Kb, Kb, 0.0f, // 1 | |
259 u_m * -Kr, u_m * -(1.0f - Kr - Kb), u_m * (1.0f - Kb), 0.5f, // 2 | |
260 v_m * (1.0f - Kr), v_m * -(1.0f - Kr - Kb), v_m * -Kb, 0.5f, // 3 | |
261 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
262 } | 199 } |
263 | 200 |
264 Transform GetRangeAdjustMatrix(ColorSpace::RangeID range, | 201 Transform GetRangeAdjustMatrix(const gfx::ColorSpace& color_space) { |
265 ColorSpace::MatrixID matrix) { | 202 SkMatrix44 range_adjust_matrix; |
266 switch (range) { | 203 color_space.GetRangeAdjustMatrix(&range_adjust_matrix); |
267 case ColorSpace::RangeID::FULL: | 204 return Transform(range_adjust_matrix); |
268 case ColorSpace::RangeID::UNSPECIFIED: | |
269 return Transform(); | |
270 | |
271 case ColorSpace::RangeID::DERIVED: | |
272 case ColorSpace::RangeID::LIMITED: | |
273 break; | |
274 } | |
275 switch (matrix) { | |
276 case ColorSpace::MatrixID::RGB: | |
277 case ColorSpace::MatrixID::YCOCG: | |
278 // TODO(hubbe): Use Transform:Scale3d / Transform::Translate3d here. | |
279 return Transform(255.0f / 219.0f, 0.0f, 0.0f, -16.0f / 219.0f, // 1 | |
280 0.0f, 255.0f / 219.0f, 0.0f, -16.0f / 219.0f, // 2 | |
281 0.0f, 0.0f, 255.0f / 219.0f, -16.0f / 219.0f, // 3 | |
282 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
283 | |
284 case ColorSpace::MatrixID::BT709: | |
285 case ColorSpace::MatrixID::UNSPECIFIED: | |
286 case ColorSpace::MatrixID::RESERVED: | |
287 case ColorSpace::MatrixID::FCC: | |
288 case ColorSpace::MatrixID::BT470BG: | |
289 case ColorSpace::MatrixID::SMPTE170M: | |
290 case ColorSpace::MatrixID::SMPTE240M: | |
291 case ColorSpace::MatrixID::BT2020_NCL: | |
292 case ColorSpace::MatrixID::BT2020_CL: | |
293 case ColorSpace::MatrixID::YDZDX: | |
294 case ColorSpace::MatrixID::UNKNOWN: | |
295 // TODO(hubbe): Use Transform:Scale3d / Transform::Translate3d here. | |
296 return Transform(255.0f / 219.0f, 0.0f, 0.0f, -16.0f / 219.0f, // 1 | |
297 0.0f, 255.0f / 224.0f, 0.0f, -15.5f / 224.0f, // 2 | |
298 0.0f, 0.0f, 255.0f / 224.0f, -15.5f / 224.0f, // 3 | |
299 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
300 } | |
301 NOTREACHED(); | |
302 return Transform(); | |
303 } | 205 } |
304 | 206 |
305 class ColorTransformMatrix; | 207 class ColorTransformMatrix; |
306 class ColorTransformToLinear; | 208 class ColorTransformToLinear; |
307 class ColorTransformFromLinear; | 209 class ColorTransformFromLinear; |
308 class ColorTransformToBT2020CL; | 210 class ColorTransformToBT2020CL; |
309 class ColorTransformFromBT2020CL; | 211 class ColorTransformFromBT2020CL; |
310 class ColorTransformNull; | 212 class ColorTransformNull; |
311 | 213 |
312 class ColorTransformInternal : public ColorTransform { | 214 class ColorTransformInternal : public ColorTransform { |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 break; | 600 break; |
699 | 601 |
700 default: // Do nothing | 602 default: // Do nothing |
701 break; | 603 break; |
702 } | 604 } |
703 | 605 |
704 // TODO(hubbe): shrink gamuts here (never stretch gamuts) | 606 // TODO(hubbe): shrink gamuts here (never stretch gamuts) |
705 } | 607 } |
706 | 608 |
707 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 609 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
708 GetRangeAdjustMatrix(from.range_, from.matrix_))); | 610 GetRangeAdjustMatrix(from))); |
709 | 611 |
710 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 612 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
711 Invert(GetTransferMatrix(from.matrix_)))); | 613 Invert(GetTransferMatrix(from)))); |
712 | 614 |
713 SkColorSpaceTransferFn to_linear_fn; | 615 SkColorSpaceTransferFn to_linear_fn; |
714 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); | 616 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); |
715 builder->Append(base::MakeUnique<ColorTransformToLinear>( | 617 builder->Append(base::MakeUnique<ColorTransformToLinear>( |
716 from.transfer_, to_linear_fn, to_linear_fn_valid)); | 618 from.transfer_, to_linear_fn, to_linear_fn_valid)); |
717 | 619 |
718 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { | 620 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { |
719 // BT2020 CL is a special case. | 621 // BT2020 CL is a special case. |
720 builder->Append(base::MakeUnique<ColorTransformFromBT2020CL>()); | 622 builder->Append(base::MakeUnique<ColorTransformFromBT2020CL>()); |
721 } | 623 } |
722 builder->Append( | 624 builder->Append( |
723 base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from))); | 625 base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from))); |
724 | 626 |
725 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 627 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
726 Invert(GetPrimaryTransform(to)))); | 628 Invert(GetPrimaryTransform(to)))); |
727 if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) { | 629 if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) { |
728 // BT2020 CL is a special case. | 630 // BT2020 CL is a special case. |
729 builder->Append(base::MakeUnique<ColorTransformToBT2020CL>()); | 631 builder->Append(base::MakeUnique<ColorTransformToBT2020CL>()); |
730 } | 632 } |
731 | 633 |
732 SkColorSpaceTransferFn from_linear_fn; | 634 SkColorSpaceTransferFn from_linear_fn; |
733 bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn); | 635 bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn); |
734 builder->Append(base::MakeUnique<ColorTransformFromLinear>( | 636 builder->Append(base::MakeUnique<ColorTransformFromLinear>( |
735 to.transfer_, from_linear_fn, from_linear_fn_valid)); | 637 to.transfer_, from_linear_fn, from_linear_fn_valid)); |
736 | 638 |
737 builder->Append( | 639 builder->Append( |
738 base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to.matrix_))); | 640 base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to))); |
739 | 641 |
740 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 642 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
741 Invert(GetRangeAdjustMatrix(to.range_, to.matrix_)))); | 643 Invert(GetRangeAdjustMatrix(to)))); |
742 } | 644 } |
743 }; | 645 }; |
744 | 646 |
745 class QCMSColorTransform : public ColorTransformInternal { | 647 class QCMSColorTransform : public ColorTransformInternal { |
746 public: | 648 public: |
747 // Takes ownership of the profiles | 649 // Takes ownership of the profiles |
748 QCMSColorTransform(qcms_profile* from, qcms_profile* to) | 650 QCMSColorTransform(qcms_profile* from, qcms_profile* to) |
749 : from_(from), to_(to) {} | 651 : from_(from), to_(to) {} |
750 ~QCMSColorTransform() override { | 652 ~QCMSColorTransform() override { |
751 qcms_profile_release(from_); | 653 qcms_profile_release(from_); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 bool from_linear_fn_valid = space.GetInverseTransferFunction(&from_linear_fn); | 757 bool from_linear_fn_valid = space.GetInverseTransferFunction(&from_linear_fn); |
856 | 758 |
857 ColorTransformFromLinear from_linear_transform(transfer, from_linear_fn, | 759 ColorTransformFromLinear from_linear_transform(transfer, from_linear_fn, |
858 from_linear_fn_valid); | 760 from_linear_fn_valid); |
859 TriStim color(v, v, v); | 761 TriStim color(v, v, v); |
860 from_linear_transform.transform(&color, 1); | 762 from_linear_transform.transform(&color, 1); |
861 return color.x(); | 763 return color.x(); |
862 } | 764 } |
863 | 765 |
864 } // namespace gfx | 766 } // namespace gfx |
OLD | NEW |