Home | History | Annotate | Download | only in renderer
      1 //
      2 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // loadimage.cpp: Defines image loading functions.
      8 
      9 #include "libGLESv2/renderer/loadimage.h"
     10 
     11 namespace rx
     12 {
     13 
     14 void LoadA8ToRGBA8(size_t width, size_t height, size_t depth,
     15                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     16                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     17 {
     18     for (size_t z = 0; z < depth; z++)
     19     {
     20         for (size_t y = 0; y < height; y++)
     21         {
     22             const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
     23             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
     24             for (size_t x = 0; x < width; x++)
     25             {
     26                 dest[x] = static_cast<uint32_t>(source[x]) << 24;
     27             }
     28         }
     29     }
     30 }
     31 
     32 void LoadA8ToBGRA8(size_t width, size_t height, size_t depth,
     33                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     34                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     35 {
     36     // Same as loading to RGBA
     37     LoadA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
     38 }
     39 
     40 void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth,
     41                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     42                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     43 {
     44     for (size_t z = 0; z < depth; z++)
     45     {
     46         for (size_t y = 0; y < height; y++)
     47         {
     48             const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
     49             float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
     50             for (size_t x = 0; x < width; x++)
     51             {
     52                 dest[4 * x + 0] = 0.0f;
     53                 dest[4 * x + 1] = 0.0f;
     54                 dest[4 * x + 2] = 0.0f;
     55                 dest[4 * x + 3] = source[x];
     56             }
     57         }
     58     }
     59 }
     60 
     61 void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth,
     62                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     63                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     64 {
     65     for (size_t z = 0; z < depth; z++)
     66     {
     67         for (size_t y = 0; y < height; y++)
     68         {
     69             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
     70             uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
     71             for (size_t x = 0; x < width; x++)
     72             {
     73                 dest[4 * x + 0] = 0;
     74                 dest[4 * x + 1] = 0;
     75                 dest[4 * x + 2] = 0;
     76                 dest[4 * x + 3] = source[x];
     77             }
     78         }
     79     }
     80 }
     81 
     82 void LoadL8ToRGBA8(size_t width, size_t height, size_t depth,
     83                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
     84                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
     85 {
     86     for (size_t z = 0; z < depth; z++)
     87     {
     88         for (size_t y = 0; y < height; y++)
     89         {
     90             const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
     91             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
     92             for (size_t x = 0; x < width; x++)
     93             {
     94                 dest[4 * x + 0] = source[x];
     95                 dest[4 * x + 1] = source[x];
     96                 dest[4 * x + 2] = source[x];
     97                 dest[4 * x + 3] = 0xFF;
     98             }
     99         }
    100     }
    101 }
    102 
    103 void LoadL8ToBGRA8(size_t width, size_t height, size_t depth,
    104                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    105                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    106 {
    107     // Same as loading to RGBA
    108     LoadL8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
    109 }
    110 
    111 void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth,
    112                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    113                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    114 {
    115     for (size_t z = 0; z < depth; z++)
    116     {
    117         for (size_t y = 0; y < height; y++)
    118         {
    119             const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
    120             float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
    121             for (size_t x = 0; x < width; x++)
    122             {
    123                 dest[4 * x + 0] = source[x];
    124                 dest[4 * x + 1] = source[x];
    125                 dest[4 * x + 2] = source[x];
    126                 dest[4 * x + 3] = 1.0f;
    127             }
    128         }
    129     }
    130 }
    131 
    132 void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth,
    133                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    134                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    135 {
    136     for (size_t z = 0; z < depth; z++)
    137     {
    138         for (size_t y = 0; y < height; y++)
    139         {
    140             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    141             uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
    142             for (size_t x = 0; x < width; x++)
    143             {
    144                 dest[4 * x + 0] = source[x];
    145                 dest[4 * x + 1] = source[x];
    146                 dest[4 * x + 2] = source[x];
    147                 dest[4 * x + 3] = gl::Float16One;
    148             }
    149         }
    150     }
    151 }
    152 
    153 void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth,
    154                     const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    155                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    156 {
    157     for (size_t z = 0; z < depth; z++)
    158     {
    159         for (size_t y = 0; y < height; y++)
    160         {
    161             const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
    162             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    163             for (size_t x = 0; x < width; x++)
    164             {
    165                 dest[4 * x + 0] = source[2 * x + 0];
    166                 dest[4 * x + 1] = source[2 * x + 0];
    167                 dest[4 * x + 2] = source[2 * x + 0];
    168                 dest[4 * x + 3] = source[2 * x + 1];
    169             }
    170         }
    171     }
    172 }
    173 
    174 void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth,
    175                     const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    176                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    177 {
    178     // Same as loading to RGBA
    179     LoadLA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
    180 }
    181 
    182 void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth,
    183                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    184                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    185 {
    186     for (size_t z = 0; z < depth; z++)
    187     {
    188         for (size_t y = 0; y < height; y++)
    189         {
    190             const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
    191             float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
    192             for (size_t x = 0; x < width; x++)
    193             {
    194                 dest[4 * x + 0] = source[2 * x + 0];
    195                 dest[4 * x + 1] = source[2 * x + 0];
    196                 dest[4 * x + 2] = source[2 * x + 0];
    197                 dest[4 * x + 3] = source[2 * x + 1];
    198             }
    199         }
    200     }
    201 }
    202 
    203 void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth,
    204                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    205                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    206 {
    207     for (size_t z = 0; z < depth; z++)
    208     {
    209         for (size_t y = 0; y < height; y++)
    210         {
    211             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    212             uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
    213             for (size_t x = 0; x < width; x++)
    214             {
    215                 dest[4 * x + 0] = source[2 * x + 0];
    216                 dest[4 * x + 1] = source[2 * x + 0];
    217                 dest[4 * x + 2] = source[2 * x + 0];
    218                 dest[4 * x + 3] = source[2 * x + 1];
    219             }
    220         }
    221     }
    222 }
    223 
    224 void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth,
    225                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    226                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    227 {
    228     for (size_t z = 0; z < depth; z++)
    229     {
    230         for (size_t y = 0; y < height; y++)
    231         {
    232             const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
    233             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    234             for (size_t x = 0; x < width; x++)
    235             {
    236                 dest[4 * x + 0] = source[x * 3 + 2];
    237                 dest[4 * x + 1] = source[x * 3 + 1];
    238                 dest[4 * x + 2] = source[x * 3 + 0];
    239                 dest[4 * x + 3] = 0xFF;
    240             }
    241         }
    242     }
    243 }
    244 
    245 void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth,
    246                     const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    247                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    248 {
    249     for (size_t z = 0; z < depth; z++)
    250     {
    251         for (size_t y = 0; y < height; y++)
    252         {
    253             const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
    254             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    255             for (size_t x = 0; x < width; x++)
    256             {
    257                 dest[4 * x + 0] = 0x00;
    258                 dest[4 * x + 1] = source[x * 2 + 1];
    259                 dest[4 * x + 2] = source[x * 2 + 0];
    260                 dest[4 * x + 3] = 0xFF;
    261             }
    262         }
    263     }
    264 }
    265 
    266 void LoadR8ToBGRX8(size_t width, size_t height, size_t depth,
    267                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    268                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    269 {
    270     for (size_t z = 0; z < depth; z++)
    271     {
    272         for (size_t y = 0; y < height; y++)
    273         {
    274             const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
    275             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    276             for (size_t x = 0; x < width; x++)
    277             {
    278                 dest[4 * x + 0] = 0x00;
    279                 dest[4 * x + 1] = 0x00;
    280                 dest[4 * x + 2] = source[x];
    281                 dest[4 * x + 3] = 0xFF;
    282             }
    283         }
    284     }
    285 }
    286 
    287 void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth,
    288                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    289                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    290 {
    291     for (size_t z = 0; z < depth; z++)
    292     {
    293         for (size_t y = 0; y < height; y++)
    294         {
    295             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    296             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    297             for (size_t x = 0; x < width; x++)
    298             {
    299                 uint16_t rgb = source[x];
    300                 dest[4 * x + 0] = ((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2);
    301                 dest[4 * x + 1] = ((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9);
    302                 dest[4 * x + 2] = ((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13);
    303                 dest[4 * x + 3] = 0xFF;
    304             }
    305         }
    306     }
    307 }
    308 
    309 void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth,
    310                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    311                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    312 {
    313     for (size_t z = 0; z < depth; z++)
    314     {
    315         for (size_t y = 0; y < height; y++)
    316         {
    317             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    318             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    319             for (size_t x = 0; x < width; x++)
    320             {
    321                 uint16_t rgb = source[x];
    322                 dest[4 * x + 0] = ((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13);
    323                 dest[4 * x + 1] = ((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9);
    324                 dest[4 * x + 2] = ((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2);
    325                 dest[4 * x + 3] = 0xFF;
    326             }
    327         }
    328     }
    329 }
    330 
    331 void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth,
    332                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    333                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    334 {
    335     for (size_t z = 0; z < depth; z++)
    336     {
    337         for (size_t y = 0; y < height; y++)
    338         {
    339             const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
    340             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
    341             for (size_t x = 0; x < width; x++)
    342             {
    343                 uint32_t rgba = source[x];
    344                 dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
    345             }
    346         }
    347     }
    348 }
    349 
    350 void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth,
    351                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    352                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    353 {
    354     for (size_t z = 0; z < depth; z++)
    355     {
    356         for (size_t y = 0; y < height; y++)
    357         {
    358             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    359             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    360             for (size_t x = 0; x < width; x++)
    361             {
    362                 uint16_t rgba = source[x];
    363                 dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
    364                 dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
    365                 dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
    366                 dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
    367             }
    368         }
    369     }
    370 }
    371 
    372 void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth,
    373                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    374                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    375 {
    376     for (size_t z = 0; z < depth; z++)
    377     {
    378         for (size_t y = 0; y < height; y++)
    379         {
    380             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    381             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    382             for (size_t x = 0; x < width; x++)
    383             {
    384                 uint16_t rgba = source[x];
    385                 dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
    386                 dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
    387                 dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
    388                 dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
    389             }
    390         }
    391     }
    392 }
    393 
    394 void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth,
    395                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    396                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    397 {
    398     for (size_t z = 0; z < depth; z++)
    399     {
    400         for (size_t y = 0; y < height; y++)
    401         {
    402             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    403             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    404             for (size_t x = 0; x < width; x++)
    405             {
    406                 uint16_t bgra = source[x];
    407                 dest[4 * x + 0] = ((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12);
    408                 dest[4 * x + 1] = ((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8);
    409                 dest[4 * x + 2] = ((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4);
    410                 dest[4 * x + 3] = ((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0);
    411             }
    412         }
    413     }
    414 }
    415 
    416 void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth,
    417                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    418                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    419 {
    420     for (size_t z = 0; z < depth; z++)
    421     {
    422         for (size_t y = 0; y < height; y++)
    423         {
    424             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    425             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    426             for (size_t x = 0; x < width; x++)
    427             {
    428                 uint16_t rgba = source[x];
    429                 dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
    430                 dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
    431                 dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
    432                 dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
    433             }
    434         }
    435     }
    436 }
    437 
    438 void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth,
    439                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    440                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    441 {
    442     for (size_t z = 0; z < depth; z++)
    443     {
    444         for (size_t y = 0; y < height; y++)
    445         {
    446             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    447             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    448             for (size_t x = 0; x < width; x++)
    449             {
    450                 uint16_t rgba = source[x];
    451                 dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
    452                 dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
    453                 dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
    454                 dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
    455             }
    456         }
    457     }
    458 }
    459 
    460 
    461 void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth,
    462                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    463                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    464 {
    465     for (size_t z = 0; z < depth; z++)
    466     {
    467         for (size_t y = 0; y < height; y++)
    468         {
    469             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    470             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    471             for (size_t x = 0; x < width; x++)
    472             {
    473                 uint16_t bgra = source[x];
    474                 dest[4 * x + 0] = ((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13);
    475                 dest[4 * x + 1] = ((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8);
    476                 dest[4 * x + 2] = ((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3);
    477                 dest[4 * x + 3] = (bgra & 0x0001) ? 0xFF : 0;
    478             }
    479         }
    480     }
    481 }
    482 
    483 void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth,
    484                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    485                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    486 {
    487     for (size_t z = 0; z < depth; z++)
    488     {
    489         for (size_t y = 0; y < height; y++)
    490         {
    491             const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
    492             uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
    493             for (size_t x = 0; x < width; x++)
    494             {
    495                 uint32_t rgba = source[x];
    496                 dest[4 * x + 0] = (rgba & 0x000003FF) >>  2;
    497                 dest[4 * x + 1] = (rgba & 0x000FFC00) >> 12;
    498                 dest[4 * x + 2] = (rgba & 0x3FF00000) >> 22;
    499                 dest[4 * x + 3] = ((rgba & 0xC0000000) >> 30) * 0x55;
    500             }
    501         }
    502     }
    503 }
    504 
    505 void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth,
    506                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    507                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    508 {
    509     for (size_t z = 0; z < depth; z++)
    510     {
    511         for (size_t y = 0; y < height; y++)
    512         {
    513             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    514             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
    515             for (size_t x = 0; x < width; x++)
    516             {
    517                 dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]),
    518                                                       gl::float16ToFloat32(source[x * 3 + 1]),
    519                                                       gl::float16ToFloat32(source[x * 3 + 2]));
    520             }
    521         }
    522     }
    523 }
    524 
    525 void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth,
    526                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    527                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    528 {
    529     for (size_t z = 0; z < depth; z++)
    530     {
    531         for (size_t y = 0; y < height; y++)
    532         {
    533             const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
    534             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
    535             for (size_t x = 0; x < width; x++)
    536             {
    537                 dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], source[x * 3 + 2]);
    538             }
    539         }
    540     }
    541 }
    542 
    543 void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth,
    544                           const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    545                           uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    546 {
    547     for (size_t z = 0; z < depth; z++)
    548     {
    549         for (size_t y = 0; y < height; y++)
    550         {
    551             const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
    552             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
    553             for (size_t x = 0; x < width; x++)
    554             {
    555                 dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) <<  0) |
    556                           (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) |
    557                           (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22);
    558             }
    559         }
    560     }
    561 }
    562 
    563 void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth,
    564                           const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    565                           uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    566 {
    567     for (size_t z = 0; z < depth; z++)
    568     {
    569         for (size_t y = 0; y < height; y++)
    570         {
    571             const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
    572             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
    573             for (size_t x = 0; x < width; x++)
    574             {
    575                 dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) <<  0) |
    576                           (gl::float32ToFloat11(source[x * 3 + 1]) << 11) |
    577                           (gl::float32ToFloat10(source[x * 3 + 2]) << 22);
    578             }
    579         }
    580     }
    581 }
    582 
    583 void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth,
    584                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    585                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    586 {
    587     for (size_t z = 0; z < depth; z++)
    588     {
    589         for (size_t y = 0; y < height; y++)
    590         {
    591             const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
    592             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
    593             for (size_t x = 0; x < width; x++)
    594             {
    595                 uint32_t d = source[x] >> 8;
    596                 uint8_t  s = source[x] & 0xFF;
    597                 dest[x] = d | (s << 24);
    598             }
    599         }
    600     }
    601 }
    602 
    603 void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth,
    604                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    605                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    606 {
    607     for (size_t z = 0; z < depth; z++)
    608     {
    609         for (size_t y = 0; y < height; y++)
    610         {
    611             const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
    612             uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
    613             for (size_t x = 0; x < width; x++)
    614             {
    615                 dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
    616                 dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
    617                 dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]);
    618                 dest[x * 4 + 3] = gl::Float16One;
    619             }
    620         }
    621     }
    622 }
    623 
    624 void LoadR32ToR16(size_t width, size_t height, size_t depth,
    625                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    626                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    627 {
    628     for (size_t z = 0; z < depth; z++)
    629     {
    630         for (size_t y = 0; y < height; y++)
    631         {
    632             const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
    633             uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
    634             for (size_t x = 0; x < width; x++)
    635             {
    636                 dest[x] = source[x] >> 16;
    637             }
    638         }
    639     }
    640 }
    641 
    642 void LoadR32ToR24G8(size_t width, size_t height, size_t depth,
    643                     const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
    644                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
    645 {
    646     for (size_t z = 0; z < depth; z++)
    647     {
    648         for (size_t y = 0; y < height; y++)
    649         {
    650             const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
    651             uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
    652 
    653             for (size_t x = 0; x < width; x++)
    654             {
    655                 dest[x] = source[x] >> 8;
    656             }
    657         }
    658     }
    659 }
    660 
    661 }
    662