Panda3D
Loading...
Searching...
No Matches
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 */
18INLINE 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 */
27INLINE 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 */
37INLINE 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 */
45INLINE 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 */
55INLINE float
56encode_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 */
68INLINE float
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 */
79INLINE unsigned char
80encode_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 */
94INLINE unsigned char
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 */
117INLINE void
118encode_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 */
141INLINE void
142encode_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 */
161INLINE void
162encode_sRGB_uchar(const LColord &color, xel &into) {
163 return encode_sRGB_uchar(LCAST(float, color), into);
164}
165
166INLINE void
167encode_sRGB_uchar(const LColord &color, xel &into, xelval &into_alpha) {
168 return encode_sRGB_uchar(LCAST(float, color), into, into_alpha);
169}
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...
float decode_sRGB_float(unsigned char val)
Decodes the sRGB-encoded unsigned char value to a linearized float in the range 0-1.
unsigned char decode_sRGB_uchar(unsigned char val)
Decodes the sRGB-encoded unsigned char value to a linearized unsigned char value.
unsigned char encode_sRGB_uchar(unsigned char val)
Encodes the linearized unsigned char value to an sRGB-encoded unsigned char value.