blob: 1b04bddad4102d9ff5f9e6a0949d60970637cbde [file] [log] [blame]
// 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
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
// The logic in this file is based on the ASTC specification, which can be
// found here:
#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 {
// 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;
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