aboutsummaryrefslogtreecommitdiff
path: root/src/decoder/physical_astc_block.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder/physical_astc_block.h')
-rw-r--r--src/decoder/physical_astc_block.h128
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_