// 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_