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