diff options
Diffstat (limited to 'src/decoder/physical_astc_block.h')
-rw-r--r-- | src/decoder/physical_astc_block.h | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/decoder/physical_astc_block.h b/src/decoder/physical_astc_block.h new file mode 100644 index 0000000..1b04bdd --- /dev/null +++ b/src/decoder/physical_astc_block.h @@ -0,0 +1,128 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_ +#define ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_ + +// The logic in this file is based on the ASTC specification, which can be +// found here: +// https://www.opengl.org/registry/specs/KHR/texture_compression_astc_hdr.txt + +#include "src/base/optional.h" +#include "src/base/uint128.h" +#include "src/decoder/types.h" + +#include <string> + +namespace astc_codec { + +// A PhysicalASTCBlock contains all 128 bits and the logic for decoding the +// various internals of an ASTC block. +class PhysicalASTCBlock { + public: + // The physical size in bytes of an ASTC block + static const size_t kSizeInBytes = 16; + + // Initializes an ASTC block based on the encoded string. + explicit PhysicalASTCBlock(const std::string& encoded_block); + explicit PhysicalASTCBlock(const base::UInt128 astc_block); + + // Returns the 128 bits of this ASTC block. + base::UInt128 GetBlockBits() const { return astc_bits_; } + + // Weights are stored in a grid that may not have the same dimensions + // as the block dimensions. This allows us to see what the physical + // dimensions are of the grid. + base::Optional<std::array<int, 2>> WeightGridDims() const; + + // The weight range is the maximum value a weight can take in the + // weight grid. + base::Optional<int> WeightRange() const; + + // Returns true if the block encoding specifies a void-extent block. This + // kind of block stores a single color to be used for every pixel in the + // block. + bool IsVoidExtent() const; + + // Returns the values (min_s, max_s, min_t, max_t) as defined in the void + // extent block as the range of texture coordinates for which this block is + // defined. (See Section C.2.23) + base::Optional<std::array<int, 4>> VoidExtentCoords() const; + + // Returns true if the block contains two separate weight grids. One used + // for the channel returned by DualPlaneChannel() and one used by the other + // channels. + bool IsDualPlane() const; + + // Returns the channel used as the "dual plane". The return value is only + // meaningful if IsDualPlane() returns true... + base::Optional<int> DualPlaneChannel() const; + + // Returns a reason that the encoding doesn't adhere to the specification. + // If the encoding is legal, then this returns a nullptr. This allows us to + // still use code of the form: + // + // if (IsIllegalEncoding()) { + // ... error ... + // } + // ... no error ... + // + // However, it also helps with debugging since we can find problems with + // encodings a lot faster. + base::Optional<std::string> IsIllegalEncoding() const; + + // Returns the number of weight bits present in this block. + base::Optional<int> NumWeightBits() const; + + // Returns the starting position within the range [0, 127] of the + // weight data within the block. + base::Optional<int> WeightStartBit() const; + + // Returns the number of endpoint pairs used in this block. + base::Optional<int> NumPartitions() const; + + // Returns the seed used to determine the partition for a given + // (x, y) coordinate within the block. Determined using the + // block size and the function as described in the specification. + base::Optional<int> PartitionID() const; + + // Returns the color endpoint mode for the given partition index. + base::Optional<ColorEndpointMode> GetEndpointMode(int partition) const; + + // Returns the starting position within the range [0, 127] of the + // color data within the block. + base::Optional<int> ColorStartBit() const; + + // Returns the number of integers used to represent the color endpoints. + base::Optional<int> NumColorValues() const; + + // Returns the number of bits used to represent the color endpoints. + base::Optional<int> NumColorBits() const; + + // Returns the maximum value that each of the encoded integers used to + // represent the color endpoints can take. + base::Optional<int> ColorValuesRange() const; + + private: + const base::UInt128 astc_bits_; + + // The logic to return the number of color bits and the color values range + // is very similar, so it's probably best to abstract it away into its own + // function. + void GetColorValuesInfo(int* color_bits, int* color_range) const; +}; + +} // namespace astc_codec + +#endif // ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_ |