Home | History | Annotate | Download | only in util
      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 "u_format_rgb9e5.h"
     32 #include "u_format_r11g11b10f.h"
     33 
     34 
     35 void
     36 util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride,
     37                                         const uint8_t *src_row, unsigned src_stride,
     38                                         unsigned width, unsigned height)
     39 {
     40    unsigned x, y;
     41    for(y = 0; y < height; y += 1) {
     42       float *dst = dst_row;
     43       const uint8_t *src = src_row;
     44       for(x = 0; x < width; x += 1) {
     45          uint32_t value = *(const uint32_t *)src;
     46 #ifdef PIPE_ARCH_BIG_ENDIAN
     47          value = util_bswap32(value);
     48 #endif
     49          rgb9e5_to_float3(value, dst);
     50          dst[3] = 1; /* a */
     51          src += 4;
     52          dst += 4;
     53       }
     54       src_row += src_stride;
     55       dst_row += dst_stride/sizeof(*dst_row);
     56    }
     57 }
     58 
     59 void
     60 util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
     61                                       const float *src_row, unsigned src_stride,
     62                                       unsigned width, unsigned height)
     63 {
     64    unsigned x, y;
     65    for(y = 0; y < height; y += 1) {
     66       const float *src = src_row;
     67       uint8_t *dst = dst_row;
     68       for(x = 0; x < width; x += 1) {
     69          uint32_t value = float3_to_rgb9e5(src);
     70 #ifdef PIPE_ARCH_BIG_ENDIAN
     71          value = util_bswap32(value);
     72 #endif
     73          *(uint32_t *)dst = value;
     74          src += 4;
     75          dst += 4;
     76       }
     77       dst_row += dst_stride;
     78       src_row += src_stride/sizeof(*src_row);
     79    }
     80 }
     81 
     82 void
     83 util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src,
     84                                        unsigned i, unsigned j)
     85 {
     86    uint32_t value = *(const uint32_t *)src;
     87 #ifdef PIPE_ARCH_BIG_ENDIAN
     88    value = util_bswap32(value);
     89 #endif
     90    rgb9e5_to_float3(value, dst);
     91    dst[3] = 1; /* a */
     92 }
     93 
     94 
     95 void
     96 util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
     97                                          const uint8_t *src_row, unsigned src_stride,
     98                                          unsigned width, unsigned height)
     99 {
    100    unsigned x, y;
    101    float p[3];
    102    for(y = 0; y < height; y += 1) {
    103       uint8_t *dst = dst_row;
    104       const uint8_t *src = src_row;
    105       for(x = 0; x < width; x += 1) {
    106          uint32_t value = *(const uint32_t *)src;
    107 #ifdef PIPE_ARCH_BIG_ENDIAN
    108          value = util_bswap32(value);
    109 #endif
    110          rgb9e5_to_float3(value, p);
    111          dst[0] = float_to_ubyte(p[0]); /* r */
    112          dst[1] = float_to_ubyte(p[1]); /* g */
    113          dst[2] = float_to_ubyte(p[2]); /* b */
    114          dst[3] = 255; /* a */
    115          src += 4;
    116          dst += 4;
    117       }
    118       src_row += src_stride;
    119       dst_row += dst_stride/sizeof(*dst_row);
    120    }
    121 }
    122 
    123 
    124 void
    125 util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    126                                        const uint8_t *src_row, unsigned src_stride,
    127                                        unsigned width, unsigned height)
    128 {
    129    unsigned x, y;
    130    float p[3];
    131    for(y = 0; y < height; y += 1) {
    132       const uint8_t *src = src_row;
    133       uint8_t *dst = dst_row;
    134       for(x = 0; x < width; x += 1) {
    135          uint32_t value;
    136          p[0] = ubyte_to_float(src[0]);
    137          p[1] = ubyte_to_float(src[1]);
    138          p[2] = ubyte_to_float(src[2]);
    139          value = float3_to_rgb9e5(p);
    140 #ifdef PIPE_ARCH_BIG_ENDIAN
    141          value = util_bswap32(value);
    142 #endif
    143          *(uint32_t *)dst = value;
    144          src += 4;
    145          dst += 4;
    146       }
    147       dst_row += dst_stride;
    148       src_row += src_stride/sizeof(*src_row);
    149    }
    150 }
    151 
    152 
    153 void
    154 util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    155                                         const uint8_t *src_row, unsigned src_stride,
    156                                         unsigned width, unsigned height)
    157 {
    158    unsigned x, y;
    159    for(y = 0; y < height; y += 1) {
    160       float *dst = dst_row;
    161       const uint8_t *src = src_row;
    162       for(x = 0; x < width; x += 1) {
    163          uint32_t value = *(const uint32_t *)src;
    164 #ifdef PIPE_ARCH_BIG_ENDIAN
    165          value = util_bswap32(value);
    166 #endif
    167          r11g11b10f_to_float3(value, dst);
    168          dst[3] = 1; /* a */
    169          src += 4;
    170          dst += 4;
    171       }
    172       src_row += src_stride;
    173       dst_row += dst_stride/sizeof(*dst_row);
    174    }
    175 }
    176 
    177 void
    178 util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    179                                       const float *src_row, unsigned src_stride,
    180                                       unsigned width, unsigned height)
    181 {
    182    unsigned x, y;
    183    for(y = 0; y < height; y += 1) {
    184       const float *src = src_row;
    185       uint8_t *dst = dst_row;
    186       for(x = 0; x < width; x += 1) {
    187          uint32_t value = float3_to_r11g11b10f(src);
    188 #ifdef PIPE_ARCH_BIG_ENDIAN
    189          value = util_bswap32(value);
    190 #endif
    191          *(uint32_t *)dst = value;
    192          src += 4;
    193          dst += 4;
    194       }
    195       dst_row += dst_stride;
    196       src_row += src_stride/sizeof(*src_row);
    197    }
    198 }
    199 
    200 void
    201 util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src,
    202                                        unsigned i, unsigned j)
    203 {
    204    uint32_t value = *(const uint32_t *)src;
    205 #ifdef PIPE_ARCH_BIG_ENDIAN
    206    value = util_bswap32(value);
    207 #endif
    208    r11g11b10f_to_float3(value, dst);
    209    dst[3] = 1; /* a */
    210 }
    211 
    212 
    213 void
    214 util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    215                                          const uint8_t *src_row, unsigned src_stride,
    216                                          unsigned width, unsigned height)
    217 {
    218    unsigned x, y;
    219    float p[3];
    220    for(y = 0; y < height; y += 1) {
    221       uint8_t *dst = dst_row;
    222       const uint8_t *src = src_row;
    223       for(x = 0; x < width; x += 1) {
    224          uint32_t value = *(const uint32_t *)src;
    225 #ifdef PIPE_ARCH_BIG_ENDIAN
    226          value = util_bswap32(value);
    227 #endif
    228          r11g11b10f_to_float3(value, p);
    229          dst[0] = float_to_ubyte(p[0]); /* r */
    230          dst[1] = float_to_ubyte(p[1]); /* g */
    231          dst[2] = float_to_ubyte(p[2]); /* b */
    232          dst[3] = 255; /* a */
    233          src += 4;
    234          dst += 4;
    235       }
    236       src_row += src_stride;
    237       dst_row += dst_stride/sizeof(*dst_row);
    238    }
    239 }
    240 
    241 
    242 void
    243 util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    244                                        const uint8_t *src_row, unsigned src_stride,
    245                                        unsigned width, unsigned height)
    246 {
    247    unsigned x, y;
    248    float p[3];
    249    for(y = 0; y < height; y += 1) {
    250       const uint8_t *src = src_row;
    251       uint8_t *dst = dst_row;
    252       for(x = 0; x < width; x += 1) {
    253          uint32_t value;
    254          p[0] = ubyte_to_float(src[0]);
    255          p[1] = ubyte_to_float(src[1]);
    256          p[2] = ubyte_to_float(src[2]);
    257          value = float3_to_r11g11b10f(p);
    258 #ifdef PIPE_ARCH_BIG_ENDIAN
    259          value = util_bswap32(value);
    260 #endif
    261          *(uint32_t *)dst = value;
    262          src += 4;
    263          dst += 4;
    264       }
    265       dst_row += dst_stride;
    266       src_row += src_stride/sizeof(*src_row);
    267    }
    268 }
    269 
    270 
    271 void
    272 util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    273                                   const uint8_t *src_row, unsigned src_stride,
    274                                   unsigned width, unsigned height)
    275 {
    276 
    277 }
    278 
    279 
    280 void
    281 util_format_r1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    282                                 const float *src_row, unsigned src_stride,
    283                                 unsigned width, unsigned height)
    284 {
    285 
    286 }
    287 
    288 
    289 void
    290 util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
    291                                  unsigned i, unsigned j)
    292 {
    293 
    294 }
    295 
    296 
    297 void
    298 util_format_r1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    299                                    const uint8_t *src_row, unsigned src_stride,
    300                                    unsigned width, unsigned height)
    301 {
    302 
    303 }
    304 
    305 
    306 void
    307 util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    308                                  const uint8_t *src_row, unsigned src_stride,
    309                                  unsigned width, unsigned height)
    310 {
    311 }
    312 
    313 
    314 /*
    315  * PIPE_FORMAT_R8G8Bx_SNORM
    316  *
    317  * A.k.a. D3DFMT_CxV8U8
    318  */
    319 
    320 static uint8_t
    321 r8g8bx_derive(int16_t r, int16_t g)
    322 {
    323    /* Derive blue from red and green components.
    324     * Apparently, we must always use integers to perform calculations,
    325     * otherwise the results won't match D3D's CxV8U8 definition.
    326     */
    327    return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f;
    328 }
    329 
    330 void
    331 util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    332                                       const uint8_t *src_row, unsigned src_stride,
    333                                       unsigned width, unsigned height)
    334 {
    335    unsigned x, y;
    336 
    337    for(y = 0; y < height; y += 1) {
    338       float *dst = dst_row;
    339       const uint16_t *src = (const uint16_t *)src_row;
    340       for(x = 0; x < width; x += 1) {
    341          uint16_t value = *src++;
    342          int16_t r, g;
    343 
    344 #ifdef PIPE_ARCH_BIG_ENDIAN
    345          value = util_bswap32(value);
    346 #endif
    347 
    348          r = ((int16_t)(value << 8)) >> 8;
    349          g = ((int16_t)(value << 0)) >> 8;
    350 
    351          dst[0] = (float)(r * (1.0f/0x7f)); /* r */
    352          dst[1] = (float)(g * (1.0f/0x7f)); /* g */
    353          dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */
    354          dst[3] = 1.0f; /* a */
    355          dst += 4;
    356       }
    357       src_row += src_stride;
    358       dst_row += dst_stride/sizeof(*dst_row);
    359    }
    360 }
    361 
    362 
    363 void
    364 util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    365                                        const uint8_t *src_row, unsigned src_stride,
    366                                        unsigned width, unsigned height)
    367 {
    368    unsigned x, y;
    369    for(y = 0; y < height; y += 1) {
    370       uint8_t *dst = dst_row;
    371       const uint16_t *src = (const uint16_t *)src_row;
    372       for(x = 0; x < width; x += 1) {
    373          uint16_t value = *src++;
    374          int16_t r, g;
    375 
    376 #ifdef PIPE_ARCH_BIG_ENDIAN
    377          value = util_bswap32(value);
    378 #endif
    379 
    380          r = ((int16_t)(value << 8)) >> 8;
    381          g = ((int16_t)(value << 0)) >> 8;
    382 
    383          dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */
    384          dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */
    385          dst[2] = r8g8bx_derive(r, g); /* b */
    386          dst[3] = 255; /* a */
    387          dst += 4;
    388       }
    389       src_row += src_stride;
    390       dst_row += dst_stride/sizeof(*dst_row);
    391    }
    392 }
    393 
    394 
    395 void
    396 util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    397                                     const float *src_row, unsigned src_stride,
    398                                     unsigned width, unsigned height)
    399 {
    400    unsigned x, y;
    401    for(y = 0; y < height; y += 1) {
    402       const float *src = src_row;
    403       uint16_t *dst = (uint16_t *)dst_row;
    404       for(x = 0; x < width; x += 1) {
    405          uint16_t value = 0;
    406 
    407          value |= (uint16_t)(((int8_t)(CLAMP(src[0], -1, 1) * 0x7f)) & 0xff) ;
    408          value |= (uint16_t)((((int8_t)(CLAMP(src[1], -1, 1) * 0x7f)) & 0xff) << 8) ;
    409 
    410 #ifdef PIPE_ARCH_BIG_ENDIAN
    411          value = util_bswap32(value);
    412 #endif
    413 
    414          *dst++ = value;
    415 
    416          src += 4;
    417       }
    418       dst_row += dst_stride;
    419       src_row += src_stride/sizeof(*src_row);
    420    }
    421 }
    422 
    423 
    424 void
    425 util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    426                                      const uint8_t *src_row, unsigned src_stride,
    427                                      unsigned width, unsigned height)
    428 {
    429    unsigned x, y;
    430 
    431    for(y = 0; y < height; y += 1) {
    432       const uint8_t *src = src_row;
    433       uint16_t *dst = (uint16_t *)dst_row;
    434       for(x = 0; x < width; x += 1) {
    435          uint16_t value = 0;
    436 
    437          value |= src[0] >> 1;
    438          value |= (src[1] >> 1) << 8;
    439 
    440 #ifdef PIPE_ARCH_BIG_ENDIAN
    441          value = util_bswap32(value);
    442 #endif
    443 
    444          *dst++ = value;
    445 
    446          src += 4;
    447       }
    448       dst_row += dst_stride;
    449       src_row += src_stride/sizeof(*src_row);
    450    }
    451 }
    452 
    453 
    454 void
    455 util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src,
    456                                      unsigned i, unsigned j)
    457 {
    458    uint16_t value = *(const uint16_t *)src;
    459    int16_t r, g;
    460 
    461 #ifdef PIPE_ARCH_BIG_ENDIAN
    462    value = util_bswap32(value);
    463 #endif
    464 
    465    r = ((int16_t)(value << 8)) >> 8;
    466    g = ((int16_t)(value << 0)) >> 8;
    467 
    468    dst[0] = r * (1.0f/0x7f); /* r */
    469    dst[1] = g * (1.0f/0x7f); /* g */
    470    dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */
    471    dst[3] = 1.0f; /* a */
    472 }
    473