tor-browser

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

generatemip.inc (11443B)


      1 //
      2 // Copyright 2015 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 // generatemip.inc: Defines the GenerateMip function, templated on the format
      8 // type of the image for which mip levels are being generated.
      9 
     10 #include "common/mathutil.h"
     11 
     12 #include "image_util/imageformats.h"
     13 
     14 namespace angle
     15 {
     16 
     17 namespace priv
     18 {
     19 
     20 template <typename T>
     21 static inline T *GetPixel(uint8_t *data, size_t x, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
     22 {
     23    return reinterpret_cast<T*>(data + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
     24 }
     25 
     26 template <typename T>
     27 static inline const T *GetPixel(const uint8_t *data, size_t x, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
     28 {
     29    return reinterpret_cast<const T*>(data + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
     30 }
     31 
     32 template <typename T>
     33 static void GenerateMip_Y(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
     34                          const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
     35                          size_t destWidth, size_t destHeight, size_t destDepth,
     36                          uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
     37 {
     38    ASSERT(sourceWidth == 1);
     39    ASSERT(sourceHeight > 1);
     40    ASSERT(sourceDepth == 1);
     41 
     42    for (size_t y = 0; y < destHeight; y++)
     43    {
     44        const T *src0 = GetPixel<T>(sourceData, 0, y * 2, 0, sourceRowPitch, sourceDepthPitch);
     45        const T *src1 = GetPixel<T>(sourceData, 0, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
     46        T *dst = GetPixel<T>(destData, 0, y, 0, destRowPitch, destDepthPitch);
     47 
     48        T::average(dst, src0, src1);
     49    }
     50 }
     51 
     52 template <typename T>
     53 static void GenerateMip_X(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
     54                          const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
     55                          size_t destWidth, size_t destHeight, size_t destDepth,
     56                          uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
     57 {
     58    ASSERT(sourceWidth > 1);
     59    ASSERT(sourceHeight == 1);
     60    ASSERT(sourceDepth == 1);
     61 
     62    for (size_t x = 0; x < destWidth; x++)
     63    {
     64        const T *src0 = GetPixel<T>(sourceData, x * 2, 0, 0, sourceRowPitch, sourceDepthPitch);
     65        const T *src1 = GetPixel<T>(sourceData, x * 2 + 1, 0, 0, sourceRowPitch, sourceDepthPitch);
     66        T *dst = GetPixel<T>(destData, x, 0, 0, destRowPitch, destDepthPitch);
     67 
     68        T::average(dst, src0, src1);
     69    }
     70 }
     71 
     72 template <typename T>
     73 static void GenerateMip_Z(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
     74                          const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
     75                          size_t destWidth, size_t destHeight, size_t destDepth,
     76                          uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
     77 {
     78    ASSERT(sourceWidth == 1);
     79    ASSERT(sourceHeight == 1);
     80    ASSERT(sourceDepth > 1);
     81 
     82    for (size_t z = 0; z < destDepth; z++)
     83    {
     84        const T *src0 = GetPixel<T>(sourceData, 0, 0, z * 2, sourceRowPitch, sourceDepthPitch);
     85        const T *src1 = GetPixel<T>(sourceData, 0, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
     86        T *dst = GetPixel<T>(destData, 0, 0, z, destRowPitch, destDepthPitch);
     87 
     88        T::average(dst, src0, src1);
     89    }
     90 }
     91 
     92 template <typename T>
     93 static void GenerateMip_XY(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
     94                           const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
     95                           size_t destWidth, size_t destHeight, size_t destDepth,
     96                           uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
     97 {
     98    ASSERT(sourceWidth > 1);
     99    ASSERT(sourceHeight > 1);
    100    ASSERT(sourceDepth == 1);
    101 
    102    for (size_t y = 0; y < destHeight; y++)
    103    {
    104        for (size_t x = 0; x < destWidth; x++)
    105        {
    106            const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, 0, sourceRowPitch, sourceDepthPitch);
    107            const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
    108            const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, 0, sourceRowPitch, sourceDepthPitch);
    109            const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
    110            T *dst = GetPixel<T>(destData, x, y, 0, destRowPitch, destDepthPitch);
    111 
    112            T tmp0, tmp1;
    113 
    114            T::average(&tmp0, src0, src1);
    115            T::average(&tmp1, src2, src3);
    116            T::average(dst, &tmp0, &tmp1);
    117        }
    118    }
    119 }
    120 
    121 template <typename T>
    122 static void GenerateMip_YZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
    123                           const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
    124                           size_t destWidth, size_t destHeight, size_t destDepth,
    125                           uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
    126 {
    127    ASSERT(sourceWidth == 1);
    128    ASSERT(sourceHeight > 1);
    129    ASSERT(sourceDepth > 1);
    130 
    131    for (size_t z = 0; z < destDepth; z++)
    132    {
    133        for (size_t y = 0; y < destHeight; y++)
    134        {
    135            const T *src0 = GetPixel<T>(sourceData, 0, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
    136            const T *src1 = GetPixel<T>(sourceData, 0, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    137            const T *src2 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
    138            const T *src3 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    139            T *dst = GetPixel<T>(destData, 0, y, z, destRowPitch, destDepthPitch);
    140 
    141            T tmp0, tmp1;
    142 
    143            T::average(&tmp0, src0, src1);
    144            T::average(&tmp1, src2, src3);
    145            T::average(dst, &tmp0, &tmp1);
    146        }
    147    }
    148 }
    149 
    150 template <typename T>
    151 static void GenerateMip_XZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
    152                           const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
    153                           size_t destWidth, size_t destHeight, size_t destDepth,
    154                           uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
    155 {
    156    ASSERT(sourceWidth > 1);
    157    ASSERT(sourceHeight == 1);
    158    ASSERT(sourceDepth > 1);
    159 
    160    for (size_t z = 0; z < destDepth; z++)
    161    {
    162        for (size_t x = 0; x < destWidth; x++)
    163        {
    164            const T *src0 = GetPixel<T>(sourceData, x * 2, 0, z * 2, sourceRowPitch, sourceDepthPitch);
    165            const T *src1 = GetPixel<T>(sourceData, x * 2, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    166            const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2, sourceRowPitch, sourceDepthPitch);
    167            const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    168            T *dst = GetPixel<T>(destData, x, 0, z, destRowPitch, destDepthPitch);
    169 
    170            T tmp0, tmp1;
    171 
    172            T::average(&tmp0, src0, src1);
    173            T::average(&tmp1, src2, src3);
    174            T::average(dst, &tmp0, &tmp1);
    175        }
    176    }
    177 }
    178 
    179 template <typename T>
    180 static void GenerateMip_XYZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
    181                            const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
    182                            size_t destWidth, size_t destHeight, size_t destDepth,
    183                            uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
    184 {
    185    ASSERT(sourceWidth > 1);
    186    ASSERT(sourceHeight > 1);
    187    ASSERT(sourceDepth > 1);
    188 
    189    for (size_t z = 0; z < destDepth; z++)
    190    {
    191        for (size_t y = 0; y < destHeight; y++)
    192        {
    193            for (size_t x = 0; x < destWidth; x++)
    194            {
    195                const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
    196                const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    197                const T *src2 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
    198                const T *src3 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    199                const T *src4 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
    200                const T *src5 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    201                const T *src6 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
    202                const T *src7 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
    203                T *dst = GetPixel<T>(destData, x, y, z, destRowPitch, destDepthPitch);
    204 
    205                T tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
    206 
    207                T::average(&tmp0, src0, src1);
    208                T::average(&tmp1, src2, src3);
    209                T::average(&tmp2, src4, src5);
    210                T::average(&tmp3, src6, src7);
    211 
    212                T::average(&tmp4, &tmp0, &tmp1);
    213                T::average(&tmp5, &tmp2, &tmp3);
    214 
    215                T::average(dst, &tmp4, &tmp5);
    216            }
    217        }
    218    }
    219 }
    220 
    221 
    222 typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
    223                                      const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
    224                                      size_t destWidth, size_t destHeight, size_t destDepth,
    225                                      uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
    226 
    227 template <typename T>
    228 static MipGenerationFunction GetMipGenerationFunction(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth)
    229 {
    230    uint8_t index = ((sourceWidth > 1)  ? 1 : 0) |
    231                    ((sourceHeight > 1) ? 2 : 0) |
    232                    ((sourceDepth > 1)  ? 4 : 0);
    233 
    234    switch (index)
    235    {
    236      case 0: return nullptr;
    237      case 1: return GenerateMip_X<T>;   // W x 1 x 1
    238      case 2: return GenerateMip_Y<T>;   // 1 x H x 1
    239      case 3: return GenerateMip_XY<T>;  // W x H x 1
    240      case 4: return GenerateMip_Z<T>;   // 1 x 1 x D
    241      case 5: return GenerateMip_XZ<T>;  // W x 1 x D
    242      case 6: return GenerateMip_YZ<T>;  // 1 x H x D
    243      case 7: return GenerateMip_XYZ<T>; // W x H x D
    244    }
    245 
    246    UNREACHABLE();
    247    return nullptr;
    248 }
    249 
    250 }  // namespace priv
    251 
    252 template <typename T>
    253 inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
    254                        const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
    255                        uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
    256 {
    257    size_t mipWidth = std::max<size_t>(1, sourceWidth >> 1);
    258    size_t mipHeight = std::max<size_t>(1, sourceHeight >> 1);
    259    size_t mipDepth = std::max<size_t>(1, sourceDepth >> 1);
    260 
    261    priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth);
    262    ASSERT(generationFunction != nullptr);
    263 
    264    generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch,
    265                       mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch);
    266 }
    267 
    268 }  // namespace angle