Panda3D
convert_srgb.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file convert_srgb.I
10  * @author rdb
11  * @date 2014-10-29
12  */
13 
14 /**
15  * Decodes the sRGB-encoded unsigned char value to a linearized float in the
16  * range 0-1.
17  */
18 INLINE float decode_sRGB_float(unsigned char val) {
19  return to_linear_float_table[val];
20 }
21 
22 /**
23  * Decodes the sRGB-encoded floating-point value in the range 0-1 to a
24  * linearized float in the range 0-1. Inputs outside this range produce
25  * invalid results.
26  */
27 INLINE float decode_sRGB_float(float val) {
28  return (val <= 0.04045f)
29  ? (val * (1.f / 12.92f))
30  : cpow((val + 0.055f) * (1.f / 1.055f), 2.4f);
31 }
32 
33 /**
34  * Decodes the sRGB-encoded unsigned char value to a linearized unsigned char
35  * value.
36  */
37 INLINE unsigned char decode_sRGB_uchar(unsigned char val) {
38  return to_linear_uchar_table[val];
39 }
40 
41 /**
42  * Decodes the sRGB-encoded floating-point value in the range 0-1 to a
43  * linearized unsigned char value. Inputs outside this range are clamped.
44  */
45 INLINE unsigned char decode_sRGB_uchar(float val) {
46  return (val <= 0.04045f)
47  ? (unsigned char)(std::max(0.f, val) * (255.f / 12.92f) + 0.5f)
48  : (unsigned char)(cpow((std::min(val, 1.f) + 0.055f) * (1.f / 1.055f), 2.4f) * 255.f + 0.5f);
49 }
50 
51 /**
52  * Encodes the linearized unsigned char value to an sRGB-encoded floating-
53  * point value in ther range 0-1.
54  */
55 INLINE float
56 encode_sRGB_float(unsigned char val) {
57  // This seems like a very unlikely use case, so I didn't bother making a
58  // look-up table for this.
59  return (val == 0) ? 0
60  : (1.055f * cpow((float)val * (1.f / 255.f), 0.41666f) - 0.055f);
61 }
62 
63 /**
64  * Encodes the linearized floating-point value in the range 0-1 to an sRGB-
65  * encoded float in the range 0-1. Inputs outside this range produce invalid
66  * results.
67  */
68 INLINE float
69 encode_sRGB_float(float val) {
70  return (val < 0.0031308f)
71  ? (val * 12.92f)
72  : (1.055f * cpow(val, 0.41666f) - 0.055f);
73 }
74 
75 /**
76  * Encodes the linearized unsigned char value to an sRGB-encoded unsigned char
77  * value.
78  */
79 INLINE unsigned char
80 encode_sRGB_uchar(unsigned char val) {
81  return to_srgb8_table[val];
82 }
83 
84 /**
85  * Encodes the linearized floating-point value in the range 0-1 to an sRGB-
86  * encoded unsigned char value. Inputs outside this range are clamped.
87  *
88  * When SSE2 support is known at compile time, this automatically uses an
89  * optimized version. Otherwise, it does not attempt runtime CPU detection.
90  * If you know that SSE2 is supported (ie. if the function
91  * has_sse2_sRGB_encode() returns true) you should call encode_sRGB_uchar_sse2
92  * instead.
93  */
94 INLINE unsigned char
95 encode_sRGB_uchar(float val) {
96 #if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
97  // Use a highly optimized approximation that has more than enough accuracy
98  // for an unsigned char.
99  return encode_sRGB_uchar_sse2(val);
100 #else
101  return (val < 0.0031308f)
102  ? (unsigned char) (std::max(0.f, val) * 3294.6f + 0.5f)
103  : (unsigned char) (269.025f * cpow(std::min(val, 1.f), 0.41666f) - 13.525f);
104 #endif
105 }
106 
107 /**
108  * Encodes the linearized floating-point color value an sRGB-encoded xel in
109  * the range 0-255.
110  *
111  * When SSE2 support is known at compile time, this automatically uses an
112  * optimized version. Otherwise, it does not attempt runtime CPU detection.
113  * If you know that SSE2 is supported (ie. if the function
114  * has_sse2_sRGB_encode() returns true) you should call encode_sRGB_uchar_sse2
115  * instead.
116  */
117 INLINE void
118 encode_sRGB_uchar(const LColorf &color, xel &into) {
119 #if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
120  // SSE2 support compiled-in; we're guaranteed to have it.
121  encode_sRGB_uchar_sse2(color, into);
122 #else
123  // Boring, slow, non-SSE2 version.
124  PPM_ASSIGN(into,
125  encode_sRGB_uchar(color[0]),
126  encode_sRGB_uchar(color[1]),
127  encode_sRGB_uchar(color[2]));
128 #endif
129 }
130 
131 /**
132  * Encodes the linearized floating-point color value an sRGB-encoded xel and
133  * alpha in the range 0-255. The alpha value is not sRGB-encoded.
134  *
135  * When SSE2 support is known at compile time, this automatically uses an
136  * optimized version. Otherwise, it does not attempt runtime CPU detection.
137  * If you know that SSE2 is supported (ie. if the function
138  * has_sse2_sRGB_encode() returns true) you should call encode_sRGB_uchar_sse2
139  * instead.
140  */
141 INLINE void
142 encode_sRGB_uchar(const LColorf &color, xel &into, xelval &into_alpha) {
143 #if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
144  // SSE2 support compiled-in; we're guaranteed to have it.
145  encode_sRGB_uchar_sse2(color, into, into_alpha);
146 #else
147  // Boring, slow, non-SSE2 version.
148  PPM_ASSIGN(into,
149  encode_sRGB_uchar(color[0]),
150  encode_sRGB_uchar(color[1]),
151  encode_sRGB_uchar(color[2]));
152 
153  into_alpha = (xelval) (color[3] * 255.f + 0.5f);
154 #endif
155 }
156 
157 
158 /**
159  * Double-precision versions of the above.
160  */
161 INLINE void
162 encode_sRGB_uchar(const LColord &color, xel &into) {
163  return encode_sRGB_uchar(LCAST(float, color), into);
164 }
165 
166 INLINE void
167 encode_sRGB_uchar(const LColord &color, xel &into, xelval &into_alpha) {
168  return encode_sRGB_uchar(LCAST(float, color), into, into_alpha);
169 }
float decode_sRGB_float(unsigned char val)
Decodes the sRGB-encoded unsigned char value to a linearized float in the range 0-1.
Definition: convert_srgb.I:18
unsigned char decode_sRGB_uchar(unsigned char val)
Decodes the sRGB-encoded unsigned char value to a linearized unsigned char value.
Definition: convert_srgb.I:37
unsigned char encode_sRGB_uchar(unsigned char val)
Encodes the linearized unsigned char value to an sRGB-encoded unsigned char value.
Definition: convert_srgb.I:80
float encode_sRGB_float(unsigned char val)
Encodes the linearized unsigned char value to an sRGB-encoded floating- point value in ther range 0-1...
Definition: convert_srgb.I:56