• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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