Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  ac_strategy.h   Sprache: C

 
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifndef LIB_JXL_AC_STRATEGY_H_
#define LIB_JXL_AC_STRATEGY_H_

#include <jxl/memory_manager.h>

#include <cstddef>
#include <cstdint>
#include <hwy/base.h>  // kMaxVectorSize

#include "lib/jxl/base/compiler_specific.h"
#include "lib/jxl/base/rect.h"
#include "lib/jxl/base/status.h"
#include "lib/jxl/coeff_order_fwd.h"
#include "lib/jxl/frame_dimensions.h"
#include "lib/jxl/image.h"
#include "lib/jxl/image_ops.h"

// Defines the different kinds of transforms, and heuristics to choose between
// them.
// `AcStrategy` represents what transform should be used, and which sub-block of
// that transform we are currently in. Note that DCT4x4 is applied on all four
// 4x4 sub-blocks of an 8x8 block.
// `AcStrategyImage` defines which strategy should be used for each 8x8 block
// of the image. The highest 4 bits represent the strategy to be used, the
// lowest 4 represent the index of the block inside that strategy.

namespace jxl {

// Raw strategy types.
enum class AcStrategyType : uint32_t {
  // Regular block size DCT
  DCT = 0,
  // Encode pixels without transforming
  IDENTITY = 1,
  // Use 2-by-2 DCT
  DCT2X2 = 2,
  // Use 4-by-4 DCT
  DCT4X4 = 3,
  // Use 16-by-16 DCT
  DCT16X16 = 4,
  // Use 32-by-32 DCT
  DCT32X32 = 5,
  // Use 16-by-8 DCT
  DCT16X8 = 6,
  // Use 8-by-16 DCT
  DCT8X16 = 7,
  // Use 32-by-8 DCT
  DCT32X8 = 8,
  // Use 8-by-32 DCT
  DCT8X32 = 9,
  // Use 32-by-16 DCT
  DCT32X16 = 10,
  // Use 16-by-32 DCT
  DCT16X32 = 11,
  // 4x8 and 8x4 DCT
  DCT4X8 = 12,
  DCT8X4 = 13,
  // Corner-DCT.
  AFV0 = 14,
  AFV1 = 15,
  AFV2 = 16,
  AFV3 = 17,
  // Larger DCTs
  DCT64X64 = 18,
  DCT64X32 = 19,
  DCT32X64 = 20,
  // No transforms smaller than 64x64 are allowed below.
  DCT128X128 = 21,
  DCT128X64 = 22,
  DCT64X128 = 23,
  DCT256X256 = 24,
  DCT256X128 = 25,
  DCT128X256 = 26
};

class AcStrategy {
 public:
  // Extremal values for the number of blocks/coefficients of a single strategy.
  static constexpr size_t kMaxCoeffBlocks = 32;
  static constexpr size_t kMaxBlockDim = kBlockDim * kMaxCoeffBlocks;
  // Maximum number of coefficients in a block. Guaranteed to be a multiple of
  // the vector size.
  static constexpr size_t kMaxCoeffArea = kMaxBlockDim * kMaxBlockDim;
  static_assert((kMaxCoeffArea * sizeof(float)) % hwy::kMaxVectorSize == 0,
                "Coefficient area is not a multiple of vector size");

  static constexpr uint8_t kNumValidStrategies =
      static_cast<uint8_t>(AcStrategyType::DCT128X256) + 1;

  static constexpr uint32_t TypeBit(const AcStrategyType type) {
    return 1u << static_cast<uint32_t>(type);
  }

  // Returns true if this block is the first 8x8 block (i.e. top-left) of a
  // possibly multi-block strategy.
  JXL_INLINE bool IsFirstBlock() const { return is_first_; }

  JXL_INLINE bool IsMultiblock() const {
    constexpr uint32_t bits =
        TypeBit(AcStrategyType::DCT16X16) | TypeBit(AcStrategyType::DCT32X32) |
        TypeBit(AcStrategyType::DCT16X8) | TypeBit(AcStrategyType::DCT8X16) |
        TypeBit(AcStrategyType::DCT32X8) | TypeBit(AcStrategyType::DCT8X32) |
        TypeBit(AcStrategyType::DCT16X32) | TypeBit(AcStrategyType::DCT32X16) |
        TypeBit(AcStrategyType::DCT32X64) | TypeBit(AcStrategyType::DCT64X32) |
        TypeBit(AcStrategyType::DCT64X64) | TypeBit(AcStrategyType::DCT64X128) |
        TypeBit(AcStrategyType::DCT128X64) |
        TypeBit(AcStrategyType::DCT128X128) |
        TypeBit(AcStrategyType::DCT128X256) |
        TypeBit(AcStrategyType::DCT256X128) |
        TypeBit(AcStrategyType::DCT256X256);
    return ((1u << static_cast<uint32_t>(Strategy())) & bits) != 0;
  }

  // Returns the raw strategy value. Should only be used for tokenization.
  JXL_INLINE uint8_t RawStrategy() const {
    return static_cast<uint8_t>(strategy_);
  }

  JXL_INLINE AcStrategyType Strategy() const { return strategy_; }

  // Inverse check
  static JXL_INLINE constexpr bool IsRawStrategyValid(int raw_strategy) {
    return raw_strategy < kNumValidStrategies && raw_strategy >= 0;
  }
  static JXL_INLINE AcStrategy FromRawStrategy(uint8_t raw_strategy) {
    return FromRawStrategy(static_cast<AcStrategyType>(raw_strategy));
  }
  static JXL_INLINE AcStrategy FromRawStrategy(AcStrategyType raw_strategy) {
    JXL_DASSERT(IsRawStrategyValid(static_cast<uint32_t>(raw_strategy)));
    return AcStrategy(raw_strategy, /*is_first=*/true);
  }

  // "Natural order" means the order of increasing of "anisotropic" frequency of
  // continuous version of DCT basis.
  // Round-trip, for any given strategy s:
  //  X = NaturalCoeffOrder(s)[NaturalCoeffOrderLutN(s)[X]]
  //  X = NaturalCoeffOrderLut(s)[NaturalCoeffOrderN(s)[X]]
  void ComputeNaturalCoeffOrder(coeff_order_t* order) const;
  void ComputeNaturalCoeffOrderLut(coeff_order_t* lut) const;

  // Number of 8x8 blocks that this strategy will cover. 0 for non-top-left
  // blocks inside a multi-block transform.
  JXL_INLINE size_t covered_blocks_x() const {
    static constexpr uint8_t kLut[] = {1, 1, 1, 1,  2, 4,  1,  2,  1,
                                       4, 2, 4, 1,  1, 1,  1,  1,  1,
                                       8, 4, 8, 16, 8, 16, 32, 16, 32};
    static_assert(sizeof(kLut) / sizeof(*kLut) == kNumValidStrategies,
                  "Update LUT");
    return kLut[static_cast<size_t>(strategy_)];
  }

  JXL_INLINE size_t covered_blocks_y() const {
    static constexpr uint8_t kLut[] = {1, 1, 1, 1,  2,  4, 2,  1,  4,
                                       1, 4, 2, 1,  1,  1, 1,  1,  1,
                                       8, 8, 4, 16, 16, 8, 32, 32, 16};
    static_assert(sizeof(kLut) / sizeof(*kLut) == kNumValidStrategies,
                  "Update LUT");
    return kLut[static_cast<size_t>(strategy_)];
  }

  JXL_INLINE size_t log2_covered_blocks() const {
    static constexpr uint8_t kLut[] = {0, 0, 0, 0, 2, 4, 1,  1, 2,
                                       2, 3, 3, 0, 0, 0, 0,  0, 0,
                                       6, 5, 5, 8, 7, 7, 10, 9, 9};
    static_assert(sizeof(kLut) / sizeof(*kLut) == kNumValidStrategies,
                  "Update LUT");
    return kLut[static_cast<size_t>(strategy_)];
  }

 private:
  friend class AcStrategyRow;
  JXL_INLINE AcStrategy(AcStrategyType strategy, bool is_first)
      : strategy_(strategy), is_first_(is_first) {
    JXL_DASSERT(IsMultiblock() || is_first == true);
  }

  AcStrategyType strategy_;
  bool is_first_;
};

// Class to use a certain row of the AC strategy.
class AcStrategyRow {
 public:
  explicit AcStrategyRow(const uint8_t* row) : row_(row) {}
  AcStrategy operator[](size_t x) const {
    AcStrategyType strategy = static_cast<AcStrategyType>(row_[x] >> 1);
    bool is_first = static_cast<bool>(row_[x] & 1);
    return AcStrategy(strategy, is_first);
  }

 private:
  const uint8_t* JXL_RESTRICT row_;
};

class AcStrategyImage {
 public:
  AcStrategyImage() = default;
  static StatusOr<AcStrategyImage> Create(JxlMemoryManager* memory_manager,
                                          size_t xsize, size_t ysize);

  AcStrategyImage(AcStrategyImage&&) = default;
  AcStrategyImage& operator=(AcStrategyImage&&) = default;

  void FillDCT8(const Rect& rect) {
    FillPlane<uint8_t>((static_cast<uint8_t>(AcStrategyType::DCT) << 1) | 1,
                       &layers_, rect);
  }
  void FillDCT8() { FillDCT8(Rect(layers_)); }

  void FillInvalid() { FillImage(INVALID, &layers_); }

  Status Set(size_t x, size_t y, AcStrategyType type) {
#if (JXL_IS_DEBUG_BUILD)
    AcStrategy acs = AcStrategy::FromRawStrategy(type);
    JXL_DASSERT(y + acs.covered_blocks_y() <= layers_.ysize());
    JXL_DASSERT(x + acs.covered_blocks_x() <= layers_.xsize());
#endif
    JXL_RETURN_IF_ERROR(SetNoBoundsCheck(x, y, type, /*check=*/false));
    return true;
  }

  Status SetNoBoundsCheck(size_t x, size_t y, AcStrategyType type,
                          bool check = true) {
    AcStrategy acs = AcStrategy::FromRawStrategy(type);
    for (size_t iy = 0; iy < acs.covered_blocks_y(); iy++) {
      for (size_t ix = 0; ix < acs.covered_blocks_x(); ix++) {
        size_t pos = (y + iy) * stride_ + x + ix;
        if (check && row_[pos] != INVALID) {
          return JXL_FAILURE("Invalid AC strategy: block overlap");
        }
        row_[pos] =
            (static_cast<uint8_t>(type) << 1) | ((iy | ix) == 0 ? 1 : 0);
      }
    }
    return true;
  }

  bool IsValid(size_t x, size_t y) { return row_[y * stride_ + x] != INVALID; }

  AcStrategyRow ConstRow(size_t y, size_t x_prefix = 0) const {
    return AcStrategyRow(layers_.ConstRow(y) + x_prefix);
  }

  AcStrategyRow ConstRow(const Rect& rect, size_t y) const {
    return ConstRow(rect.y0() + y, rect.x0());
  }

  size_t PixelsPerRow() const { return layers_.PixelsPerRow(); }

  size_t xsize() const { return layers_.xsize(); }
  size_t ysize() const { return layers_.ysize(); }

  // Count the number of blocks of a given type.
  size_t CountBlocks(AcStrategyType type) const;

  JxlMemoryManager* memory_manager() const { return layers_.memory_manager(); }

 private:
  ImageB layers_;
  uint8_t* JXL_RESTRICT row_;
  size_t stride_;

  // A value that does not represent a valid combined AC strategy
  // value. Used as a sentinel.
  static constexpr uint8_t INVALID = 0xFF;
};

}  // namespace jxl

#endif  // LIB_JXL_AC_STRATEGY_H_

Messung V0.5
C=97 H=97 G=96

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge