tor-browser

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

palette.h (5511B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #ifndef LIB_JXL_MODULAR_TRANSFORM_PALETTE_H_
      7 #define LIB_JXL_MODULAR_TRANSFORM_PALETTE_H_
      8 
      9 #include <algorithm>
     10 #include <array>
     11 #include <cstddef>
     12 #include <cstdint>
     13 
     14 #include "lib/jxl/base/compiler_specific.h"
     15 #include "lib/jxl/base/data_parallel.h"
     16 #include "lib/jxl/base/status.h"
     17 #include "lib/jxl/modular/encoding/context_predict.h"
     18 #include "lib/jxl/modular/modular_image.h"
     19 #include "lib/jxl/modular/options.h"
     20 
     21 namespace jxl {
     22 
     23 namespace palette_internal {
     24 
     25 static constexpr int kMaxPaletteLookupTableSize = 1 << 16;
     26 
     27 static constexpr int kRgbChannels = 3;
     28 
     29 // 5x5x5 color cube for the larger cube.
     30 static constexpr int kLargeCube = 5;
     31 
     32 // Smaller interleaved color cube to fill the holes of the larger cube.
     33 static constexpr int kSmallCube = 4;
     34 static constexpr int kSmallCubeBits = 2;
     35 // kSmallCube ** 3
     36 static constexpr int kLargeCubeOffset = kSmallCube * kSmallCube * kSmallCube;
     37 static constexpr int kImplicitPaletteSize =
     38    kLargeCubeOffset + kLargeCube * kLargeCube * kLargeCube;
     39 
     40 template <int denom>
     41 static inline pixel_type Scale(uint64_t value, uint64_t bit_depth) {
     42  // return (value * ((static_cast<pixel_type_w>(1) << bit_depth) - 1)) / denom;
     43  // We only call this function with kSmallCube or kLargeCube - 1 as denom,
     44  // allowing us to avoid a division here.
     45  static_assert(denom == 4);
     46  return (value * ((static_cast<uint64_t>(1) << bit_depth) - 1)) >> 2;
     47 }
     48 
     49 // The purpose of this function is solely to extend the interpretation of
     50 // palette indices to implicit values. If index < nb_deltas, indicating that the
     51 // result is a delta palette entry, it is the responsibility of the caller to
     52 // treat it as such.
     53 static JXL_MAYBE_UNUSED pixel_type
     54 GetPaletteValue(const pixel_type *const palette, int index, const size_t c,
     55                const int palette_size, const int onerow, const int bit_depth) {
     56  if (index < 0) {
     57    static constexpr std::array<std::array<pixel_type, 3>, 72> kDeltaPalette = {
     58        {
     59            {{0, 0, 0}},       {{4, 4, 4}},       {{11, 0, 0}},
     60            {{0, 0, -13}},     {{0, -12, 0}},     {{-10, -10, -10}},
     61            {{-18, -18, -18}}, {{-27, -27, -27}}, {{-18, -18, 0}},
     62            {{0, 0, -32}},     {{-32, 0, 0}},     {{-37, -37, -37}},
     63            {{0, -32, -32}},   {{24, 24, 45}},    {{50, 50, 50}},
     64            {{-45, -24, -24}}, {{-24, -45, -45}}, {{0, -24, -24}},
     65            {{-34, -34, 0}},   {{-24, 0, -24}},   {{-45, -45, -24}},
     66            {{64, 64, 64}},    {{-32, 0, -32}},   {{0, -32, 0}},
     67            {{-32, 0, 32}},    {{-24, -45, -24}}, {{45, 24, 45}},
     68            {{24, -24, -45}},  {{-45, -24, 24}},  {{80, 80, 80}},
     69            {{64, 0, 0}},      {{0, 0, -64}},     {{0, -64, -64}},
     70            {{-24, -24, 45}},  {{96, 96, 96}},    {{64, 64, 0}},
     71            {{45, -24, -24}},  {{34, -34, 0}},    {{112, 112, 112}},
     72            {{24, -45, -45}},  {{45, 45, -24}},   {{0, -32, 32}},
     73            {{24, -24, 45}},   {{0, 96, 96}},     {{45, -24, 24}},
     74            {{24, -45, -24}},  {{-24, -45, 24}},  {{0, -64, 0}},
     75            {{96, 0, 0}},      {{128, 128, 128}}, {{64, 0, 64}},
     76            {{144, 144, 144}}, {{96, 96, 0}},     {{-36, -36, 36}},
     77            {{45, -24, -45}},  {{45, -45, -24}},  {{0, 0, -96}},
     78            {{0, 128, 128}},   {{0, 96, 0}},      {{45, 24, -45}},
     79            {{-128, 0, 0}},    {{24, -45, 24}},   {{-45, 24, -45}},
     80            {{64, 0, -64}},    {{64, -64, -64}},  {{96, 0, 96}},
     81            {{45, -45, 24}},   {{24, 45, -45}},   {{64, 64, -64}},
     82            {{128, 128, 0}},   {{0, 0, -128}},    {{-24, 45, -45}},
     83        }};
     84    if (c >= kRgbChannels) {
     85      return 0;
     86    }
     87    // Do not open the brackets, otherwise INT32_MIN negation could overflow.
     88    index = -(index + 1);
     89    index %= 1 + 2 * (kDeltaPalette.size() - 1);
     90    static constexpr int kMultiplier[] = {-1, 1};
     91    pixel_type result =
     92        kDeltaPalette[((index + 1) >> 1)][c] * kMultiplier[index & 1];
     93    if (bit_depth > 8) {
     94      result *= static_cast<pixel_type>(1) << (bit_depth - 8);
     95    }
     96    return result;
     97  } else if (palette_size <= index && index < palette_size + kLargeCubeOffset) {
     98    if (c >= kRgbChannels) return 0;
     99    index -= palette_size;
    100    index >>= c * kSmallCubeBits;
    101    return Scale<kSmallCube>(index % kSmallCube, bit_depth) +
    102           (1 << (std::max(0, bit_depth - 3)));
    103  } else if (palette_size + kLargeCubeOffset <= index) {
    104    if (c >= kRgbChannels) return 0;
    105    index -= palette_size + kLargeCubeOffset;
    106    // TODO(eustas): should we take care of ambiguity created by
    107    //               index >= kLargeCube ** 3 ?
    108    switch (c) {
    109      case 0:
    110      default:
    111        break;
    112      case 1:
    113        index /= kLargeCube;
    114        break;
    115      case 2:
    116        index /= kLargeCube * kLargeCube;
    117        break;
    118    }
    119    return Scale<kLargeCube - 1>(index % kLargeCube, bit_depth);
    120  }
    121  return palette[c * onerow + static_cast<size_t>(index)];
    122 }
    123 
    124 }  // namespace palette_internal
    125 
    126 Status InvPalette(Image &input, uint32_t begin_c, uint32_t nb_colors,
    127                  uint32_t nb_deltas, Predictor predictor,
    128                  const weighted::Header &wp_header, ThreadPool *pool);
    129 
    130 Status MetaPalette(Image &input, uint32_t begin_c, uint32_t end_c,
    131                   uint32_t nb_colors, uint32_t nb_deltas, bool lossy);
    132 
    133 }  // namespace jxl
    134 
    135 #endif  // LIB_JXL_MODULAR_TRANSFORM_PALETTE_H_