1 // Copyright 2018 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_ 16 #define ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_ 17 18 // The logic in this file is based on the ASTC specification, which can be 19 // found here: 20 // https://www.opengl.org/registry/specs/KHR/texture_compression_astc_hdr.txt 21 22 #include "src/base/optional.h" 23 #include "src/base/uint128.h" 24 #include "src/decoder/types.h" 25 26 #include <string> 27 28 namespace astc_codec { 29 30 // A PhysicalASTCBlock contains all 128 bits and the logic for decoding the 31 // various internals of an ASTC block. 32 class PhysicalASTCBlock { 33 public: 34 // The physical size in bytes of an ASTC block 35 static const size_t kSizeInBytes = 16; 36 37 // Initializes an ASTC block based on the encoded string. 38 explicit PhysicalASTCBlock(const std::string& encoded_block); 39 explicit PhysicalASTCBlock(const base::UInt128 astc_block); 40 41 // Returns the 128 bits of this ASTC block. GetBlockBits()42 base::UInt128 GetBlockBits() const { return astc_bits_; } 43 44 // Weights are stored in a grid that may not have the same dimensions 45 // as the block dimensions. This allows us to see what the physical 46 // dimensions are of the grid. 47 base::Optional<std::array<int, 2>> WeightGridDims() const; 48 49 // The weight range is the maximum value a weight can take in the 50 // weight grid. 51 base::Optional<int> WeightRange() const; 52 53 // Returns true if the block encoding specifies a void-extent block. This 54 // kind of block stores a single color to be used for every pixel in the 55 // block. 56 bool IsVoidExtent() const; 57 58 // Returns the values (min_s, max_s, min_t, max_t) as defined in the void 59 // extent block as the range of texture coordinates for which this block is 60 // defined. (See Section C.2.23) 61 base::Optional<std::array<int, 4>> VoidExtentCoords() const; 62 63 // Returns true if the block contains two separate weight grids. One used 64 // for the channel returned by DualPlaneChannel() and one used by the other 65 // channels. 66 bool IsDualPlane() const; 67 68 // Returns the channel used as the "dual plane". The return value is only 69 // meaningful if IsDualPlane() returns true... 70 base::Optional<int> DualPlaneChannel() const; 71 72 // Returns a reason that the encoding doesn't adhere to the specification. 73 // If the encoding is legal, then this returns a nullptr. This allows us to 74 // still use code of the form: 75 // 76 // if (IsIllegalEncoding()) { 77 // ... error ... 78 // } 79 // ... no error ... 80 // 81 // However, it also helps with debugging since we can find problems with 82 // encodings a lot faster. 83 base::Optional<std::string> IsIllegalEncoding() const; 84 85 // Returns the number of weight bits present in this block. 86 base::Optional<int> NumWeightBits() const; 87 88 // Returns the starting position within the range [0, 127] of the 89 // weight data within the block. 90 base::Optional<int> WeightStartBit() const; 91 92 // Returns the number of endpoint pairs used in this block. 93 base::Optional<int> NumPartitions() const; 94 95 // Returns the seed used to determine the partition for a given 96 // (x, y) coordinate within the block. Determined using the 97 // block size and the function as described in the specification. 98 base::Optional<int> PartitionID() const; 99 100 // Returns the color endpoint mode for the given partition index. 101 base::Optional<ColorEndpointMode> GetEndpointMode(int partition) const; 102 103 // Returns the starting position within the range [0, 127] of the 104 // color data within the block. 105 base::Optional<int> ColorStartBit() const; 106 107 // Returns the number of integers used to represent the color endpoints. 108 base::Optional<int> NumColorValues() const; 109 110 // Returns the number of bits used to represent the color endpoints. 111 base::Optional<int> NumColorBits() const; 112 113 // Returns the maximum value that each of the encoded integers used to 114 // represent the color endpoints can take. 115 base::Optional<int> ColorValuesRange() const; 116 117 private: 118 const base::UInt128 astc_bits_; 119 120 // The logic to return the number of color bits and the color values range 121 // is very similar, so it's probably best to abstract it away into its own 122 // function. 123 void GetColorValuesInfo(int* color_bits, int* color_range) const; 124 }; 125 126 } // namespace astc_codec 127 128 #endif // ASTC_CODEC_DECODER_PHYSICAL_ASTC_BLOCK_H_ 129