1 /**************************************************************************
3 * Copyright 2010 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
26 **************************************************************************/
30 #include "u_format_other.h"
31 #include "../../../mesa/main/rgb9e5.h"
35 util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row
, unsigned dst_stride
,
36 const uint8_t *src_row
, unsigned src_stride
,
37 unsigned width
, unsigned height
)
40 for(y
= 0; y
< height
; y
+= 1) {
42 const uint8_t *src
= src_row
;
43 for(x
= 0; x
< width
; x
+= 1) {
44 uint32_t value
= *(const uint32_t *)src
;
45 #ifdef PIPE_ARCH_BIG_ENDIAN
46 value
= util_bswap32(value
);
48 rgb9e5_to_float3(value
, dst
);
53 src_row
+= src_stride
;
54 dst_row
+= dst_stride
/sizeof(*dst_row
);
59 util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row
, unsigned dst_stride
,
60 const float *src_row
, unsigned src_stride
,
61 unsigned width
, unsigned height
)
64 for(y
= 0; y
< height
; y
+= 1) {
65 const float *src
= src_row
;
66 uint8_t *dst
= dst_row
;
67 for(x
= 0; x
< width
; x
+= 1) {
68 uint32_t value
= float3_to_rgb9e5(src
);
69 #ifdef PIPE_ARCH_BIG_ENDIAN
70 value
= util_bswap32(value
);
72 *(uint32_t *)dst
= value
;
76 dst_row
+= dst_stride
;
77 src_row
+= src_stride
/sizeof(*src_row
);
82 util_format_r9g9b9e5_float_fetch_rgba_float(float *dst
, const uint8_t *src
,
83 unsigned i
, unsigned j
)
85 uint32_t value
= *(const uint32_t *)src
;
86 #ifdef PIPE_ARCH_BIG_ENDIAN
87 value
= util_bswap32(value
);
89 rgb9e5_to_float3(value
, dst
);
95 util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row
, unsigned dst_stride
,
96 const uint8_t *src_row
, unsigned src_stride
,
97 unsigned width
, unsigned height
)
101 for(y
= 0; y
< height
; y
+= 1) {
102 uint8_t *dst
= dst_row
;
103 const uint8_t *src
= src_row
;
104 for(x
= 0; x
< width
; x
+= 1) {
105 uint32_t value
= *(const uint32_t *)src
;
106 #ifdef PIPE_ARCH_BIG_ENDIAN
107 value
= util_bswap32(value
);
109 rgb9e5_to_float3(value
, p
);
110 dst
[0] = float_to_ubyte(p
[0]); /* r */
111 dst
[1] = float_to_ubyte(p
[1]); /* g */
112 dst
[2] = float_to_ubyte(p
[2]); /* b */
113 dst
[3] = 255; /* a */
117 src_row
+= src_stride
;
118 dst_row
+= dst_stride
/sizeof(*dst_row
);
124 util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row
, unsigned dst_stride
,
125 const uint8_t *src_row
, unsigned src_stride
,
126 unsigned width
, unsigned height
)
130 for(y
= 0; y
< height
; y
+= 1) {
131 const uint8_t *src
= src_row
;
132 uint8_t *dst
= dst_row
;
133 for(x
= 0; x
< width
; x
+= 1) {
135 p
[0] = ubyte_to_float(src
[0]);
136 p
[1] = ubyte_to_float(src
[1]);
137 p
[2] = ubyte_to_float(src
[2]);
138 value
= float3_to_rgb9e5(p
);
139 #ifdef PIPE_ARCH_BIG_ENDIAN
140 value
= util_bswap32(value
);
142 *(uint32_t *)dst
= value
;
146 dst_row
+= dst_stride
;
147 src_row
+= src_stride
/sizeof(*src_row
);
153 util_format_r1_unorm_unpack_rgba_float(float *dst_row
, unsigned dst_stride
,
154 const uint8_t *src_row
, unsigned src_stride
,
155 unsigned width
, unsigned height
)
162 util_format_r1_unorm_pack_rgba_float(uint8_t *dst_row
, unsigned dst_stride
,
163 const float *src_row
, unsigned src_stride
,
164 unsigned width
, unsigned height
)
171 util_format_r1_unorm_fetch_rgba_float(float *dst
, const uint8_t *src
,
172 unsigned i
, unsigned j
)
179 util_format_r1_unorm_unpack_rgba_8unorm(uint8_t *dst_row
, unsigned dst_stride
,
180 const uint8_t *src_row
, unsigned src_stride
,
181 unsigned width
, unsigned height
)
188 util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row
, unsigned dst_stride
,
189 const uint8_t *src_row
, unsigned src_stride
,
190 unsigned width
, unsigned height
)
196 * PIPE_FORMAT_R8G8Bx_SNORM
198 * A.k.a. D3DFMT_CxV8U8
202 r8g8bx_derive(int16_t r
, int16_t g
)
204 /* Derive blue from red and green components.
205 * Apparently, we must always use integers to perform calculations,
206 * otherwise the results won't match D3D's CxV8U8 definition.
208 return (uint8_t)sqrtf(0x7f * 0x7f - r
* r
- g
* g
) * 0xff / 0x7f;
212 util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row
, unsigned dst_stride
,
213 const uint8_t *src_row
, unsigned src_stride
,
214 unsigned width
, unsigned height
)
218 for(y
= 0; y
< height
; y
+= 1) {
219 float *dst
= dst_row
;
220 const uint16_t *src
= (const uint16_t *)src_row
;
221 for(x
= 0; x
< width
; x
+= 1) {
222 uint16_t value
= *src
++;
225 #ifdef PIPE_ARCH_BIG_ENDIAN
226 value
= util_bswap32(value
);
229 r
= ((int16_t)(value
<< 8)) >> 8;
230 g
= ((int16_t)(value
<< 0)) >> 8;
232 dst
[0] = (float)(r
* (1.0f
/0x7f)); /* r */
233 dst
[1] = (float)(g
* (1.0f
/0x7f)); /* g */
234 dst
[2] = r8g8bx_derive(r
, g
) * (1.0f
/0xff); /* b */
235 dst
[3] = 1.0f
; /* a */
238 src_row
+= src_stride
;
239 dst_row
+= dst_stride
/sizeof(*dst_row
);
245 util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row
, unsigned dst_stride
,
246 const uint8_t *src_row
, unsigned src_stride
,
247 unsigned width
, unsigned height
)
250 for(y
= 0; y
< height
; y
+= 1) {
251 uint8_t *dst
= dst_row
;
252 const uint16_t *src
= (const uint16_t *)src_row
;
253 for(x
= 0; x
< width
; x
+= 1) {
254 uint16_t value
= *src
++;
257 #ifdef PIPE_ARCH_BIG_ENDIAN
258 value
= util_bswap32(value
);
261 r
= ((int16_t)(value
<< 8)) >> 8;
262 g
= ((int16_t)(value
<< 0)) >> 8;
264 dst
[0] = (uint8_t)(((uint16_t)MAX2(r
, 0)) * 0xff / 0x7f); /* r */
265 dst
[1] = (uint8_t)(((uint16_t)MAX2(g
, 0)) * 0xff / 0x7f); /* g */
266 dst
[2] = r8g8bx_derive(r
, g
); /* b */
267 dst
[3] = 255; /* a */
270 src_row
+= src_stride
;
271 dst_row
+= dst_stride
/sizeof(*dst_row
);
277 util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *dst_row
, unsigned dst_stride
,
278 const float *src_row
, unsigned src_stride
,
279 unsigned width
, unsigned height
)
282 for(y
= 0; y
< height
; y
+= 1) {
283 const float *src
= src_row
;
284 uint16_t *dst
= (uint16_t *)dst_row
;
285 for(x
= 0; x
< width
; x
+= 1) {
288 value
|= (uint16_t)(((int8_t)(CLAMP(src
[0], -1, 1) * 0x7f)) & 0xff) ;
289 value
|= (uint16_t)((((int8_t)(CLAMP(src
[1], -1, 1) * 0x7f)) & 0xff) << 8) ;
291 #ifdef PIPE_ARCH_BIG_ENDIAN
292 value
= util_bswap32(value
);
299 dst_row
+= dst_stride
;
300 src_row
+= src_stride
/sizeof(*src_row
);
306 util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *dst_row
, unsigned dst_stride
,
307 const uint8_t *src_row
, unsigned src_stride
,
308 unsigned width
, unsigned height
)
312 for(y
= 0; y
< height
; y
+= 1) {
313 const uint8_t *src
= src_row
;
314 uint16_t *dst
= (uint16_t *)dst_row
;
315 for(x
= 0; x
< width
; x
+= 1) {
318 value
|= src
[0] >> 1;
319 value
|= (src
[1] >> 1) << 8;
321 #ifdef PIPE_ARCH_BIG_ENDIAN
322 value
= util_bswap32(value
);
329 dst_row
+= dst_stride
;
330 src_row
+= src_stride
/sizeof(*src_row
);
336 util_format_r8g8bx_snorm_fetch_rgba_float(float *dst
, const uint8_t *src
,
337 unsigned i
, unsigned j
)
339 uint16_t value
= *(const uint16_t *)src
;
342 #ifdef PIPE_ARCH_BIG_ENDIAN
343 value
= util_bswap32(value
);
346 r
= ((int16_t)(value
<< 8)) >> 8;
347 g
= ((int16_t)(value
<< 0)) >> 8;
349 dst
[0] = r
* (1.0f
/0x7f); /* r */
350 dst
[1] = g
* (1.0f
/0x7f); /* g */
351 dst
[2] = r8g8bx_derive(r
, g
) * (1.0f
/0xff); /* b */
352 dst
[3] = 1.0f
; /* a */