tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

loadimage_paletted.cpp (4506B)


      1 //
      2 // Copyright 2022 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_paletted.cpp: Decodes GL_PALETTE_* textures.
      8 
      9 #include "image_util/loadimage.h"
     10 
     11 #include <type_traits>
     12 #include "common/mathutil.h"
     13 
     14 #include "image_util/imageformats.h"
     15 
     16 namespace angle
     17 {
     18 
     19 namespace
     20 {
     21 
     22 template <typename T>
     23 R8G8B8A8 ReadColor(const T *src)
     24 {
     25    gl::ColorF tmp;
     26    T::readColor(&tmp, src);
     27    R8G8B8A8 rgba;
     28    R8G8B8A8::writeColor(&rgba, &tmp);
     29    return rgba;
     30 }
     31 
     32 size_t DecodeIndexIntoPalette(const uint8_t *row, size_t i, uint32_t indexBits)
     33 {
     34    switch (indexBits)
     35    {
     36        case 4:
     37        {
     38            // From OES_compressed_paletted_texture, section Additions to
     39            // Chapter 3 of the OpenGL 1.3 Specification (Rasterization):
     40            //
     41            // Texel Data Formats for compressed paletted textures
     42            //
     43            // PALETTE4_xxx:
     44            //
     45            //      7 6 5 4 3 2 1 0
     46            //      ---------------
     47            //     |  1st  |  2nd  |
     48            //     | texel | texel |
     49            //      ---------------
     50 
     51            bool even = i % 2 == 0;
     52            return (row[i / 2] >> (even ? 4 : 0)) & 0x0f;
     53        }
     54 
     55        case 8:
     56            return row[i];
     57 
     58        default:
     59            UNREACHABLE();
     60            return 0;
     61    }
     62 }
     63 
     64 R8G8B8A8 DecodeColor(const uint8_t *src,
     65                     uint32_t redBlueBits,
     66                     uint32_t greenBits,
     67                     uint32_t alphaBits)
     68 {
     69    switch (redBlueBits)
     70    {
     71        case 8:
     72            ASSERT(greenBits == 8);
     73            switch (alphaBits)
     74            {
     75                case 0:
     76                    return ReadColor<>(reinterpret_cast<const R8G8B8 *>(src));
     77                case 8:
     78                    return ReadColor<>(reinterpret_cast<const R8G8B8A8 *>(src));
     79                default:
     80                    UNREACHABLE();
     81                    break;
     82            }
     83            break;
     84 
     85        case 5:
     86            switch (greenBits)
     87            {
     88                case 6:
     89                    ASSERT(alphaBits == 0);
     90                    return ReadColor<>(reinterpret_cast<const R5G6B5 *>(src));
     91                case 5:
     92                    ASSERT(alphaBits == 1);
     93                    return ReadColor<>(reinterpret_cast<const R5G5B5A1 *>(src));
     94                default:
     95                    UNREACHABLE();
     96                    break;
     97            }
     98            break;
     99 
    100        case 4:
    101            ASSERT(greenBits == 4 && alphaBits == 4);
    102            return ReadColor<>(reinterpret_cast<const R4G4B4A4 *>(src));
    103 
    104        default:
    105            UNREACHABLE();
    106            break;
    107    }
    108 
    109    UNREACHABLE();
    110    return R8G8B8A8{0, 0, 0, 255};
    111 }
    112 
    113 }  // namespace
    114 
    115 // See LoadPalettedToRGBA8.
    116 void LoadPalettedToRGBA8Impl(size_t width,
    117                             size_t height,
    118                             size_t depth,
    119                             uint32_t indexBits,
    120                             uint32_t redBlueBits,
    121                             uint32_t greenBits,
    122                             uint32_t alphaBits,
    123                             const uint8_t *input,
    124                             size_t inputRowPitch,
    125                             size_t inputDepthPitch,
    126                             uint8_t *output,
    127                             size_t outputRowPitch,
    128                             size_t outputDepthPitch)
    129 {
    130    size_t colorBytes   = (redBlueBits + greenBits + redBlueBits + alphaBits) / 8;
    131    size_t paletteSize  = 1 << indexBits;
    132    size_t paletteBytes = paletteSize * colorBytes;
    133 
    134    const uint8_t *palette = input;
    135 
    136    const uint8_t *texels = input + paletteBytes;  // + TODO(http://anglebug.com/7688): mip levels
    137 
    138    for (size_t z = 0; z < depth; z++)
    139    {
    140        for (size_t y = 0; y < height; y++)
    141        {
    142            const uint8_t *srcRow =
    143                priv::OffsetDataPointer<uint8_t>(texels, y, z, inputRowPitch, inputDepthPitch);
    144            R8G8B8A8 *dstRow =
    145                priv::OffsetDataPointer<R8G8B8A8>(output, y, z, outputRowPitch, outputDepthPitch);
    146 
    147            for (size_t x = 0; x < width; x++)
    148            {
    149                size_t indexIntoPalette = DecodeIndexIntoPalette(srcRow, x, indexBits);
    150 
    151                dstRow[x] = DecodeColor(palette + indexIntoPalette * colorBytes, redBlueBits,
    152                                        greenBits, alphaBits);
    153            }
    154        }
    155    }
    156 }
    157 
    158 }  // namespace angle