u_format_other.c revision 349184be36e59f49309b8c1f371d99efceaf6d5f
1/************************************************************************** 2 * 3 * Copyright 2010 VMware, Inc. 4 * All Rights Reserved. 5 * 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: 13 * 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. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 **************************************************************************/ 27 28 29#include "u_math.h" 30#include "u_format_other.h" 31#include "../../../mesa/main/rgb9e5.h" 32 33 34void 35util_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) 38{ 39 unsigned x, y; 40 for(y = 0; y < height; y += 1) { 41 float *dst = dst_row; 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); 47#endif 48 rgb9e5_to_float3(value, dst); 49 dst[3] = 1; /* a */ 50 src += 4; 51 dst += 4; 52 } 53 src_row += src_stride; 54 dst_row += dst_stride/sizeof(*dst_row); 55 } 56} 57 58void 59util_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) 62{ 63 unsigned x, y; 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); 71#endif 72 *(uint32_t *)dst = value; 73 src += 4; 74 dst += 4; 75 } 76 dst_row += dst_stride; 77 src_row += src_stride/sizeof(*src_row); 78 } 79} 80 81void 82util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, 83 unsigned i, unsigned j) 84{ 85 uint32_t value = *(const uint32_t *)src; 86#ifdef PIPE_ARCH_BIG_ENDIAN 87 value = util_bswap32(value); 88#endif 89 rgb9e5_to_float3(value, dst); 90 dst[3] = 1; /* a */ 91} 92 93 94void 95util_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) 98{ 99 unsigned x, y; 100 float p[3]; 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); 108#endif 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 */ 114 src += 4; 115 dst += 4; 116 } 117 src_row += src_stride; 118 dst_row += dst_stride/sizeof(*dst_row); 119 } 120} 121 122 123void 124util_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) 127{ 128 unsigned x, y; 129 float p[3]; 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) { 134 uint32_t value; 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); 141#endif 142 *(uint32_t *)dst = value; 143 src += 4; 144 dst += 4; 145 } 146 dst_row += dst_stride; 147 src_row += src_stride/sizeof(*src_row); 148 } 149} 150 151 152void 153util_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) 156{ 157 158} 159 160 161void 162util_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) 165{ 166 167} 168 169 170void 171util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, 172 unsigned i, unsigned j) 173{ 174 175} 176 177 178void 179util_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) 182{ 183 184} 185 186 187void 188util_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) 191{ 192} 193 194 195/* 196 * PIPE_FORMAT_R8G8Bx_SNORM 197 * 198 * A.k.a. D3DFMT_CxV8U8 199 */ 200 201static uint8_t 202r8g8bx_derive(int16_t r, int16_t g) 203{ 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. 207 */ 208 return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f; 209} 210 211void 212util_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) 215{ 216 unsigned x, y; 217 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++; 223 int16_t r, g; 224 225#ifdef PIPE_ARCH_BIG_ENDIAN 226 value = util_bswap32(value); 227#endif 228 229 r = ((int16_t)(value << 8)) >> 8; 230 g = ((int16_t)(value << 0)) >> 8; 231 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 */ 236 dst += 4; 237 } 238 src_row += src_stride; 239 dst_row += dst_stride/sizeof(*dst_row); 240 } 241} 242 243 244void 245util_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) 248{ 249 unsigned x, y; 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++; 255 int16_t r, g; 256 257#ifdef PIPE_ARCH_BIG_ENDIAN 258 value = util_bswap32(value); 259#endif 260 261 r = ((int16_t)(value << 8)) >> 8; 262 g = ((int16_t)(value << 0)) >> 8; 263 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 */ 268 dst += 4; 269 } 270 src_row += src_stride; 271 dst_row += dst_stride/sizeof(*dst_row); 272 } 273} 274 275 276void 277util_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) 280{ 281 unsigned x, y; 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) { 286 uint16_t value = 0; 287 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) ; 290 291#ifdef PIPE_ARCH_BIG_ENDIAN 292 value = util_bswap32(value); 293#endif 294 295 *dst++ = value; 296 297 src += 4; 298 } 299 dst_row += dst_stride; 300 src_row += src_stride/sizeof(*src_row); 301 } 302} 303 304 305void 306util_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) 309{ 310 unsigned x, y; 311 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) { 316 uint16_t value = 0; 317 318 value |= src[0] >> 1; 319 value |= (src[1] >> 1) << 8; 320 321#ifdef PIPE_ARCH_BIG_ENDIAN 322 value = util_bswap32(value); 323#endif 324 325 *dst++ = value; 326 327 src += 4; 328 } 329 dst_row += dst_stride; 330 src_row += src_stride/sizeof(*src_row); 331 } 332} 333 334 335void 336util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, 337 unsigned i, unsigned j) 338{ 339 uint16_t value = *(const uint16_t *)src; 340 int16_t r, g; 341 342#ifdef PIPE_ARCH_BIG_ENDIAN 343 value = util_bswap32(value); 344#endif 345 346 r = ((int16_t)(value << 8)) >> 8; 347 g = ((int16_t)(value << 0)) >> 8; 348 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 */ 353} 354