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_ENDPOINT_CODEC_H_
16 #define ASTC_CODEC_DECODER_ENDPOINT_CODEC_H_
17 
18 #include "src/decoder/physical_astc_block.h"
19 #include "src/decoder/types.h"
20 
21 #include <array>
22 #include <vector>
23 
24 namespace astc_codec {
25 
26 // We use a special distinction for encode modes used to pass to the
27 // EncodeColorsForMode function below. The reason is that some of the color
28 // modes have sub-modes (like blue-contract) that change whether or not it is
29 // useful to encode an endpoint pair using one mode versus another. To avoid
30 // this problem, we approach the problem of encoding by specifying some
31 // high-level encoding modes. These eventually choose one of the low level
32 // ColorEndpointModes from Section C.2.14 when used in EncodeColorsForMode.
33 enum class EndpointEncodingMode {
34   kDirectLuma,
35   kDirectLumaAlpha,
36   kBaseScaleRGB,
37   kBaseScaleRGBA,
38   kDirectRGB,
39   kDirectRGBA
40 };
41 
42 // Returns the number of values in the encoded endpoint pair after encoding
43 // to a specific high-level encoding mode.
NumValuesForEncodingMode(EndpointEncodingMode mode)44 constexpr int NumValuesForEncodingMode(EndpointEncodingMode mode) {
45   return
46       mode == EndpointEncodingMode::kDirectLuma ? 2 :
47       mode == EndpointEncodingMode::kDirectLumaAlpha ? 4 :
48       mode == EndpointEncodingMode::kBaseScaleRGB ? 4 :
49       mode == EndpointEncodingMode::kBaseScaleRGBA ? 6 :
50       mode == EndpointEncodingMode::kDirectRGB ? 6 : 8;
51 }
52 
53 // Fills |vals| with the quantized endpoint colors values defined in the ASTC
54 // specification. The values are quantized to the range [0, max_value]. These
55 // quantization limits can be obtained by querying the associated functions in
56 // integer_sequence_codec. The returned |astc_mode| will be the ASTC mode used
57 // to encode the resulting sequence.
58 //
59 // The |encoding_mode| is used to determine the way that we encode the values.
60 // Each encoding mode is used to determine which ASTC mode best corresponds
61 // to the pair of endpoints. It is a necessary hint to the encoding function
62 // in order to process the endpoints. Each encoding mode gurantees a certain
63 // number of values generated per endpoints.
64 //
65 // The return value will be true if the endpoints have been switched in order to
66 // reap the most benefit from the way the hardware decodes the given mode. In
67 // this case, the associated weights that interpolate this color must also be
68 // switched. In other words, for each w, it should change to 64 - w.
69 bool EncodeColorsForMode(
70     const RgbaColor& endpoint_low_rgba, const RgbaColor& endpoint_high_rgba,
71     int max_value, EndpointEncodingMode encoding_mode,
72     ColorEndpointMode* astc_mode, std::vector<int>* vals);
73 
74 // Decodes the color values quantized to the range [0, max_value] into RGBA
75 // endpoints for the given mode. This function is the inverse of
76 // EncodeColorsForMode -- see that function for details. This function should
77 // work on all LDR endpoint modes, but no HDR modes.
78 void DecodeColorsForMode(const std::vector<int>& vals,
79                          int max_value, ColorEndpointMode mode,
80                          RgbaColor* endpoint_low_rgba,
81                          RgbaColor* endpoint_high_rgba);
82 
83 // Returns true if the quantized |vals| in the range [0, max_value] use the
84 // 'blue_contract' modification during decoding for the given |mode|.
85 bool UsesBlueContract(int max_value, ColorEndpointMode mode,
86                       const std::vector<int>& vals);
87 
88 }  // namespace astc_codec
89 
90 #endif  // ASTC_CODEC_DECODER_ENDPOINT_CODEC_H_
91