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