libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

transform.h (5231B)


      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_TRANSFORM_H_
      7 #define LIB_JXL_MODULAR_TRANSFORM_TRANSFORM_H_
      8 
      9 #include <cstdint>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "lib/jxl/base/data_parallel.h"
     14 #include "lib/jxl/fields.h"
     15 #include "lib/jxl/modular/encoding/context_predict.h"
     16 #include "lib/jxl/modular/options.h"
     17 
     18 namespace jxl {
     19 
     20 enum class TransformId : uint32_t {
     21   // G, R-G, B-G and variants (including YCoCg).
     22   kRCT = 0,
     23 
     24   // Color palette. Parameters are: [begin_c] [end_c] [nb_colors]
     25   kPalette = 1,
     26 
     27   // Squeezing (Haar-style)
     28   kSqueeze = 2,
     29 
     30   // Invalid for now.
     31   kInvalid = 3,
     32 };
     33 
     34 struct SqueezeParams : public Fields {
     35   JXL_FIELDS_NAME(SqueezeParams)
     36   bool horizontal;
     37   bool in_place;
     38   uint32_t begin_c;
     39   uint32_t num_c;
     40   SqueezeParams();
     41   Status VisitFields(Visitor *JXL_RESTRICT visitor) override {
     42     JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &horizontal));
     43     JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &in_place));
     44     JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Bits(3), BitsOffset(6, 8),
     45                                            BitsOffset(10, 72),
     46                                            BitsOffset(13, 1096), 0, &begin_c));
     47     JXL_QUIET_RETURN_IF_ERROR(
     48         visitor->U32(Val(1), Val(2), Val(3), BitsOffset(4, 4), 2, &num_c));
     49     return true;
     50   }
     51 };
     52 
     53 class Transform : public Fields {
     54  public:
     55   TransformId id;
     56   // for Palette and RCT.
     57   uint32_t begin_c;
     58   // for RCT. 42 possible values starting from 0.
     59   uint32_t rct_type;
     60   // Only for Palette and NearLossless.
     61   uint32_t num_c;
     62   // Only for Palette.
     63   uint32_t nb_colors;
     64   uint32_t nb_deltas;
     65   // for Squeeze. Default squeeze if empty.
     66   std::vector<SqueezeParams> squeezes;
     67   // for NearLossless, not serialized.
     68   int max_delta_error;
     69   // Serialized for Palette.
     70   Predictor predictor;
     71   // for Palette, not serialized.
     72   bool ordered_palette = true;
     73   bool lossy_palette = false;
     74 
     75   explicit Transform(TransformId id);
     76   // default constructor for bundles.
     77   Transform() : Transform(TransformId::kInvalid) {}
     78 
     79   Status VisitFields(Visitor *JXL_RESTRICT visitor) override {
     80     JXL_QUIET_RETURN_IF_ERROR(
     81         visitor->U32(Val(static_cast<uint32_t>(TransformId::kRCT)),
     82                      Val(static_cast<uint32_t>(TransformId::kPalette)),
     83                      Val(static_cast<uint32_t>(TransformId::kSqueeze)),
     84                      Val(static_cast<uint32_t>(TransformId::kInvalid)),
     85                      static_cast<uint32_t>(TransformId::kRCT),
     86                      reinterpret_cast<uint32_t *>(&id)));
     87     if (id == TransformId::kInvalid) {
     88       return JXL_FAILURE("Invalid transform ID");
     89     }
     90     if (visitor->Conditional(id == TransformId::kRCT ||
     91                              id == TransformId::kPalette)) {
     92       JXL_QUIET_RETURN_IF_ERROR(
     93           visitor->U32(Bits(3), BitsOffset(6, 8), BitsOffset(10, 72),
     94                        BitsOffset(13, 1096), 0, &begin_c));
     95     }
     96     if (visitor->Conditional(id == TransformId::kRCT)) {
     97       // 0-41, default YCoCg.
     98       JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Val(6), Bits(2), BitsOffset(4, 2),
     99                                              BitsOffset(6, 10), 6, &rct_type));
    100       if (rct_type >= 42) {
    101         return JXL_FAILURE("Invalid transform RCT type");
    102       }
    103     }
    104     if (visitor->Conditional(id == TransformId::kPalette)) {
    105       JXL_QUIET_RETURN_IF_ERROR(
    106           visitor->U32(Val(1), Val(3), Val(4), BitsOffset(13, 1), 3, &num_c));
    107       JXL_QUIET_RETURN_IF_ERROR(visitor->U32(
    108           BitsOffset(8, 0), BitsOffset(10, 256), BitsOffset(12, 1280),
    109           BitsOffset(16, 5376), 256, &nb_colors));
    110       JXL_QUIET_RETURN_IF_ERROR(
    111           visitor->U32(Val(0), BitsOffset(8, 1), BitsOffset(10, 257),
    112                        BitsOffset(16, 1281), 0, &nb_deltas));
    113       JXL_QUIET_RETURN_IF_ERROR(
    114           visitor->Bits(4, static_cast<uint32_t>(Predictor::Zero),
    115                         reinterpret_cast<uint32_t *>(&predictor)));
    116       if (predictor >= Predictor::Best) {
    117         return JXL_FAILURE("Invalid predictor");
    118       }
    119     }
    120 
    121     if (visitor->Conditional(id == TransformId::kSqueeze)) {
    122       uint32_t num_squeezes = static_cast<uint32_t>(squeezes.size());
    123       JXL_QUIET_RETURN_IF_ERROR(
    124           visitor->U32(Val(0), BitsOffset(4, 1), BitsOffset(6, 9),
    125                        BitsOffset(8, 41), 0, &num_squeezes));
    126       if (visitor->IsReading()) squeezes.resize(num_squeezes);
    127       for (size_t i = 0; i < num_squeezes; i++) {
    128         JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&squeezes[i]));
    129       }
    130     }
    131     return true;
    132   }
    133 
    134   JXL_FIELDS_NAME(Transform)
    135 
    136   Status Inverse(Image &input, const weighted::Header &wp_header,
    137                  ThreadPool *pool = nullptr);
    138   Status MetaApply(Image &input);
    139 };
    140 
    141 Status CheckEqualChannels(const Image &image, uint32_t c1, uint32_t c2);
    142 
    143 static inline pixel_type PixelAdd(pixel_type a, pixel_type b) {
    144   return static_cast<pixel_type>(static_cast<uint32_t>(a) +
    145                                  static_cast<uint32_t>(b));
    146 }
    147 
    148 }  // namespace jxl
    149 
    150 #endif  // LIB_JXL_MODULAR_TRANSFORM_TRANSFORM_H_