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_LOGICAL_ASTC_BLOCK_H_ 16 #define ASTC_CODEC_DECODER_LOGICAL_ASTC_BLOCK_H_ 17 18 #include "src/base/optional.h" 19 #include "src/decoder/footprint.h" 20 #include "src/decoder/intermediate_astc_block.h" 21 #include "src/decoder/partition.h" 22 #include "src/decoder/physical_astc_block.h" 23 24 #include <array> 25 #include <utility> 26 #include <vector> 27 28 namespace astc_codec { 29 30 // A logical ASTC block holds the endpoints, indices, and partition information 31 // of a compressed block. These values generally do not adhere to any 32 // quality-for-bitrate-imposed limits and are solely logical entities for 33 // determining the best representation of a given block. 34 class LogicalASTCBlock { 35 public: 36 LogicalASTCBlock(const LogicalASTCBlock&) = default; 37 LogicalASTCBlock(LogicalASTCBlock&&) = default; 38 39 // Unpack an intermediate block into a logical one. 40 LogicalASTCBlock(const Footprint& footprint, 41 const IntermediateBlockData& block); 42 43 // Unpack a void extent intermediate block into a logical one. 44 LogicalASTCBlock(const Footprint& footprint, const VoidExtentData& block); 45 46 // Create a new, empty ASTC block 47 explicit LogicalASTCBlock(const Footprint& footprint); 48 49 // Returns the footprint associated with this block. The footprint is defined 50 // via the partition, because the partition definition is dependent on the 51 // footprint. GetFootprint()52 const Footprint& GetFootprint() const { return partition_.footprint; } 53 54 // Returns the unquantized and infilled weight in the range [0, 64] for the 55 // given texel location. Assumes that the block is a single-plane block, 56 // meaning that weights are used equally across all channels. 57 void SetWeightAt(int x, int y, int weight); 58 int WeightAt(int x, int y) const; 59 60 // Returns the unquantized and infilled weight in the range [0, 64] for the 61 // given channel at the given texel location. If the block does not have a 62 // dual-plane channel then the reference-returning version will fail, as it 63 // cannot return a reference to a value that (potentially) doesn't exist. 64 void SetDualPlaneWeightAt(int channel, int x, int y, int weight); 65 int DualPlaneWeightAt(int channel, int x, int y) const; 66 67 // Returns the color as it would be in the given pixel coordinates of the 68 // block. Fails if the coordinates are outside of the range of the block 69 // footprint 70 RgbaColor ColorAt(int x, int y) const; 71 72 // Sets the current partition for the block. |p|'s footprint must match the 73 // return value of GetFootprint() or else this call will fail. 74 void SetPartition(const Partition& p); 75 76 // Sets the endpoints for the given subset. 77 void SetEndpoints(const EndpointPair& eps, int subset); SetEndpoints(const Endpoint & ep1,const Endpoint & ep2,int subset)78 void SetEndpoints(const Endpoint& ep1, const Endpoint& ep2, int subset) { 79 SetEndpoints(std::make_pair(ep1, ep2), subset); 80 } 81 82 // Sets the dual plane channel for the block. Value must be within the range 83 // [0, 3]. If a negative value is passed, then the dual-plane data for the 84 // block is removed, and the block is treated as a single-plane block. 85 void SetDualPlaneChannel(int channel); IsDualPlane()86 bool IsDualPlane() const { return dual_plane_.hasValue(); } 87 88 private: 89 // A block may have up to four endpoint pairs. 90 std::vector<EndpointPair> endpoints_; 91 92 // Weights are stored as values in the interval [0, 64]. 93 std::vector<int> weights_; 94 95 // The partition information for this block. This determines the 96 // appropriate subsets that each pixel should belong to. 97 Partition partition_; 98 99 // Dual plane data holds both the channel and the weights that describe 100 // the dual plane data for the given block. If a block has a dual plane, then 101 // we need to know both the channel and the weights associated with it. 102 struct DualPlaneData { 103 int channel; 104 std::vector<int> weights; 105 }; 106 107 // The dual-plane data is optional from a logical representation of the block. 108 base::Optional<DualPlaneData> dual_plane_; 109 110 // Calculates the unquantized and interpolated weights from the encoded weight 111 // values and possibly dual-plane weights specified in the passed ASTC block. 112 void CalculateWeights(const Footprint& footprint, 113 const IntermediateBlockData& block); 114 115 // Calculates the weights for a VoidExtentBlock. 116 void CalculateWeights(const Footprint& footprint, 117 const VoidExtentData& block); 118 }; 119 120 // Unpacks the physical ASTC block into a logical block. Returns false if the 121 // physical block is an error encoded block. 122 base::Optional<LogicalASTCBlock> UnpackLogicalBlock( 123 const Footprint& footprint, const PhysicalASTCBlock& pb); 124 125 } // namespace astc_codec 126 127 #endif // ASTC_CODEC_DECODER_LOGICAL_ASTC_BLOCK_H_ 128