From b56a50064caf2a590ba43699e0074690fcd431bf Mon Sep 17 00:00:00 2001 From: Jeff McGlynn Date: Wed, 20 Jun 2018 11:34:20 -0700 Subject: Initial version of astc-codec for open source release Contains an implementation of an ASTC decoder that is able to pass the dEQP ASTC LDR tests. astc-codec has no external dependencies for the main library, only for test code, and is licensed under the Apache license. Components: include/ - Public API that can decode ASTC LDR data into a RGBA UNORM8 buffer. src/base/ - Base library with common functionality not directly related to ASTC decoding. Contains a uint128 implementation, BitStream for reading/writing bits with a primitive (or uint128 type), Optional implementation (to not take a dependency on C++17), and more. src/decoder/ - Internal implementation of the ASTC decoder. src/base/test/, src/decoder/test/ - Unit tests (and a fuzzing test) for the astc decoder. src/decoder/testdata/ - Sample ASTC images and golden image results for testing. src/decoder/tools/ - A tool to inspect contents of an ASTC file. third_party/ - Third party libraries, only used for tests. Change-Id: Ia98e5a7dc847daa3d3a48c5e62d94b8fb1cb98bd --- src/decoder/logical_astc_block.h | 127 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/decoder/logical_astc_block.h (limited to 'src/decoder/logical_astc_block.h') diff --git a/src/decoder/logical_astc_block.h b/src/decoder/logical_astc_block.h new file mode 100644 index 0000000..2243eb4 --- /dev/null +++ b/src/decoder/logical_astc_block.h @@ -0,0 +1,127 @@ +// 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_LOGICAL_ASTC_BLOCK_H_ +#define ASTC_CODEC_DECODER_LOGICAL_ASTC_BLOCK_H_ + +#include "src/base/optional.h" +#include "src/decoder/footprint.h" +#include "src/decoder/intermediate_astc_block.h" +#include "src/decoder/partition.h" +#include "src/decoder/physical_astc_block.h" + +#include +#include +#include + +namespace astc_codec { + +// A logical ASTC block holds the endpoints, indices, and partition information +// of a compressed block. These values generally do not adhere to any +// quality-for-bitrate-imposed limits and are solely logical entities for +// determining the best representation of a given block. +class LogicalASTCBlock { + public: + LogicalASTCBlock(const LogicalASTCBlock&) = default; + LogicalASTCBlock(LogicalASTCBlock&&) = default; + + // Unpack an intermediate block into a logical one. + LogicalASTCBlock(const Footprint& footprint, + const IntermediateBlockData& block); + + // Unpack a void extent intermediate block into a logical one. + LogicalASTCBlock(const Footprint& footprint, const VoidExtentData& block); + + // Create a new, empty ASTC block + explicit LogicalASTCBlock(const Footprint& footprint); + + // Returns the footprint associated with this block. The footprint is defined + // via the partition, because the partition definition is dependent on the + // footprint. + const Footprint& GetFootprint() const { return partition_.footprint; } + + // Returns the unquantized and infilled weight in the range [0, 64] for the + // given texel location. Assumes that the block is a single-plane block, + // meaning that weights are used equally across all channels. + void SetWeightAt(int x, int y, int weight); + int WeightAt(int x, int y) const; + + // Returns the unquantized and infilled weight in the range [0, 64] for the + // given channel at the given texel location. If the block does not have a + // dual-plane channel then the reference-returning version will fail, as it + // cannot return a reference to a value that (potentially) doesn't exist. + void SetDualPlaneWeightAt(int channel, int x, int y, int weight); + int DualPlaneWeightAt(int channel, int x, int y) const; + + // Returns the color as it would be in the given pixel coordinates of the + // block. Fails if the coordinates are outside of the range of the block + // footprint + RgbaColor ColorAt(int x, int y) const; + + // Sets the current partition for the block. |p|'s footprint must match the + // return value of GetFootprint() or else this call will fail. + void SetPartition(const Partition& p); + + // Sets the endpoints for the given subset. + void SetEndpoints(const EndpointPair& eps, int subset); + void SetEndpoints(const Endpoint& ep1, const Endpoint& ep2, int subset) { + SetEndpoints(std::make_pair(ep1, ep2), subset); + } + + // Sets the dual plane channel for the block. Value must be within the range + // [0, 3]. If a negative value is passed, then the dual-plane data for the + // block is removed, and the block is treated as a single-plane block. + void SetDualPlaneChannel(int channel); + bool IsDualPlane() const { return dual_plane_.hasValue(); } + + private: + // A block may have up to four endpoint pairs. + std::vector endpoints_; + + // Weights are stored as values in the interval [0, 64]. + std::vector weights_; + + // The partition information for this block. This determines the + // appropriate subsets that each pixel should belong to. + Partition partition_; + + // Dual plane data holds both the channel and the weights that describe + // the dual plane data for the given block. If a block has a dual plane, then + // we need to know both the channel and the weights associated with it. + struct DualPlaneData { + int channel; + std::vector weights; + }; + + // The dual-plane data is optional from a logical representation of the block. + base::Optional dual_plane_; + + // Calculates the unquantized and interpolated weights from the encoded weight + // values and possibly dual-plane weights specified in the passed ASTC block. + void CalculateWeights(const Footprint& footprint, + const IntermediateBlockData& block); + + // Calculates the weights for a VoidExtentBlock. + void CalculateWeights(const Footprint& footprint, + const VoidExtentData& block); +}; + +// Unpacks the physical ASTC block into a logical block. Returns false if the +// physical block is an error encoded block. +base::Optional UnpackLogicalBlock( + const Footprint& footprint, const PhysicalASTCBlock& pb); + +} // namespace astc_codec + +#endif // ASTC_CODEC_DECODER_LOGICAL_ASTC_BLOCK_H_ -- cgit v1.2.3