54573d740454f3eb218f03b047e388b6d921d13f
[WebKit-https.git] / Source / WebCore / platform / graphics / ColorUtilities.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "Color.h"
29 #include <algorithm>
30 #include <math.h>
31
32 namespace WebCore {
33
34 struct FloatComponents {
35     FloatComponents(float a = 0, float b = 0, float c = 0, float d = 0)
36     {
37         components[0] = a;
38         components[1] = b;
39         components[2] = c;
40         components[3] = d;
41     }
42
43     FloatComponents& operator+=(const FloatComponents& rhs)
44     {
45         components[0] += rhs.components[0];
46         components[1] += rhs.components[1];
47         components[2] += rhs.components[2];
48         components[3] += rhs.components[3];
49         return *this;
50     }
51
52     FloatComponents operator+(float rhs) const
53     {
54         FloatComponents result;
55         result.components[0] = components[0] + rhs;
56         result.components[1] = components[1] + rhs;
57         result.components[2] = components[2] + rhs;
58         result.components[3] = components[3] + rhs;
59         return result;
60     }
61
62     FloatComponents operator/(float denominator) const
63     {
64         FloatComponents result;
65         result.components[0] = components[0] / denominator;
66         result.components[1] = components[1] / denominator;
67         result.components[2] = components[2] / denominator;
68         result.components[3] = components[3] / denominator;
69         return result;
70     }
71
72     FloatComponents operator*(float factor) const
73     {
74         FloatComponents result;
75         result.components[0] = components[0] * factor;
76         result.components[1] = components[1] * factor;
77         result.components[2] = components[2] * factor;
78         result.components[3] = components[3] * factor;
79         return result;
80     }
81
82     FloatComponents abs() const
83     {
84         FloatComponents result;
85         result.components[0] = fabs(components[0]);
86         result.components[1] = fabs(components[1]);
87         result.components[2] = fabs(components[2]);
88         result.components[3] = fabs(components[3]);
89         return result;
90     }
91
92     float components[4];
93 };
94
95 struct ColorComponents {
96     ColorComponents(const FloatComponents&);
97     
98     static ColorComponents fromRGBA(unsigned pixel)
99     {
100         return ColorComponents((pixel >> 24) & 0xFF, (pixel >> 16) & 0xFF, (pixel >> 8) & 0xFF, pixel & 0xFF);
101     }
102     
103     ColorComponents(uint8_t a = 0, uint8_t b = 0, uint8_t c = 0, uint8_t d = 0)
104     {
105         components[0] = a;
106         components[1] = b;
107         components[2] = c;
108         components[3] = d;
109     }
110     
111     unsigned toRGBA() const
112     {
113         return components[0] << 24 | components[1] << 16 | components[2] << 8 | components[3];
114     }
115
116     uint8_t components[4] { };
117 };
118
119 inline ColorComponents perComponentMax(const ColorComponents& a, const ColorComponents& b)
120 {
121     return {
122         std::max(a.components[0], b.components[0]),
123         std::max(a.components[1], b.components[1]),
124         std::max(a.components[2], b.components[2]),
125         std::max(a.components[3], b.components[3])
126     };
127 }
128
129 inline ColorComponents perComponentMin(const ColorComponents& a, const ColorComponents& b)
130 {
131     return {
132         std::min(a.components[0], b.components[0]),
133         std::min(a.components[1], b.components[1]),
134         std::min(a.components[2], b.components[2]),
135         std::min(a.components[3], b.components[3])
136     };
137 }
138
139 inline uint8_t clampedColorComponent(float f)
140 {
141     // See also colorFloatToRGBAByte().
142     return std::max(0, std::min(static_cast<int>(lroundf(255.0f * f)), 255));
143 }
144
145 inline unsigned byteOffsetOfPixel(unsigned x, unsigned y, unsigned rowBytes)
146 {
147     const unsigned bytesPerPixel = 4;
148     return x * bytesPerPixel + y * rowBytes;
149 }
150
151 // 0-1 components, result is clamped.
152 float linearToSRGBColorComponent(float);
153 float sRGBToLinearColorComponent(float);
154     
155 Color linearToSRGBColor(const Color&);
156 Color sRGBToLinearColor(const Color&);
157
158 } // namespace WebCore
159