xref: /aosp_15_r20/external/libgav1/src/dsp/distance_weighted_blend.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1*09537850SAkhilesh Sanikop // Copyright 2019 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop //      http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop 
15*09537850SAkhilesh Sanikop #include "src/dsp/distance_weighted_blend.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <cassert>
18*09537850SAkhilesh Sanikop #include <cstddef>
19*09537850SAkhilesh Sanikop #include <cstdint>
20*09537850SAkhilesh Sanikop #include <type_traits>
21*09537850SAkhilesh Sanikop 
22*09537850SAkhilesh Sanikop #include "src/dsp/dsp.h"
23*09537850SAkhilesh Sanikop #include "src/utils/common.h"
24*09537850SAkhilesh Sanikop 
25*09537850SAkhilesh Sanikop namespace libgav1 {
26*09537850SAkhilesh Sanikop namespace dsp {
27*09537850SAkhilesh Sanikop namespace {
28*09537850SAkhilesh Sanikop 
29*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
DistanceWeightedBlend_C(const void * LIBGAV1_RESTRICT prediction_0,const void * LIBGAV1_RESTRICT prediction_1,const uint8_t weight_0,const uint8_t weight_1,const int width,const int height,void * LIBGAV1_RESTRICT const dest,const ptrdiff_t dest_stride)30*09537850SAkhilesh Sanikop void DistanceWeightedBlend_C(const void* LIBGAV1_RESTRICT prediction_0,
31*09537850SAkhilesh Sanikop                              const void* LIBGAV1_RESTRICT prediction_1,
32*09537850SAkhilesh Sanikop                              const uint8_t weight_0, const uint8_t weight_1,
33*09537850SAkhilesh Sanikop                              const int width, const int height,
34*09537850SAkhilesh Sanikop                              void* LIBGAV1_RESTRICT const dest,
35*09537850SAkhilesh Sanikop                              const ptrdiff_t dest_stride) {
36*09537850SAkhilesh Sanikop   // 7.11.3.2 Rounding variables derivation process
37*09537850SAkhilesh Sanikop   //   2 * FILTER_BITS(7) - (InterRound0(3|5) + InterRound1(7))
38*09537850SAkhilesh Sanikop   constexpr int inter_post_round_bits = (bitdepth == 12) ? 2 : 4;
39*09537850SAkhilesh Sanikop   using PredType =
40*09537850SAkhilesh Sanikop       typename std::conditional<bitdepth == 8, int16_t, uint16_t>::type;
41*09537850SAkhilesh Sanikop   const auto* pred_0 = static_cast<const PredType*>(prediction_0);
42*09537850SAkhilesh Sanikop   const auto* pred_1 = static_cast<const PredType*>(prediction_1);
43*09537850SAkhilesh Sanikop   auto* dst = static_cast<Pixel*>(dest);
44*09537850SAkhilesh Sanikop   const ptrdiff_t dst_stride = dest_stride / sizeof(Pixel);
45*09537850SAkhilesh Sanikop 
46*09537850SAkhilesh Sanikop   int y = 0;
47*09537850SAkhilesh Sanikop   do {
48*09537850SAkhilesh Sanikop     int x = 0;
49*09537850SAkhilesh Sanikop     do {
50*09537850SAkhilesh Sanikop       // See warp.cc and convolve.cc for detailed prediction ranges.
51*09537850SAkhilesh Sanikop       // weight_0 + weight_1 = 16.
52*09537850SAkhilesh Sanikop       int res = pred_0[x] * weight_0 + pred_1[x] * weight_1;
53*09537850SAkhilesh Sanikop       res -= (bitdepth == 8) ? 0 : kCompoundOffset * 16;
54*09537850SAkhilesh Sanikop       dst[x] = static_cast<Pixel>(
55*09537850SAkhilesh Sanikop           Clip3(RightShiftWithRounding(res, inter_post_round_bits + 4), 0,
56*09537850SAkhilesh Sanikop                 (1 << bitdepth) - 1));
57*09537850SAkhilesh Sanikop     } while (++x < width);
58*09537850SAkhilesh Sanikop 
59*09537850SAkhilesh Sanikop     dst += dst_stride;
60*09537850SAkhilesh Sanikop     pred_0 += width;
61*09537850SAkhilesh Sanikop     pred_1 += width;
62*09537850SAkhilesh Sanikop   } while (++y < height);
63*09537850SAkhilesh Sanikop }
64*09537850SAkhilesh Sanikop 
Init8bpp()65*09537850SAkhilesh Sanikop void Init8bpp() {
66*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(8);
67*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
68*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
69*09537850SAkhilesh Sanikop   dsp->distance_weighted_blend = DistanceWeightedBlend_C<8, uint8_t>;
70*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
71*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
72*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp8bpp_DistanceWeightedBlend
73*09537850SAkhilesh Sanikop   dsp->distance_weighted_blend = DistanceWeightedBlend_C<8, uint8_t>;
74*09537850SAkhilesh Sanikop #endif
75*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
76*09537850SAkhilesh Sanikop }
77*09537850SAkhilesh Sanikop 
78*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
Init10bpp()79*09537850SAkhilesh Sanikop void Init10bpp() {
80*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(10);
81*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
82*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
83*09537850SAkhilesh Sanikop   dsp->distance_weighted_blend = DistanceWeightedBlend_C<10, uint16_t>;
84*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
85*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
86*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp10bpp_DistanceWeightedBlend
87*09537850SAkhilesh Sanikop   dsp->distance_weighted_blend = DistanceWeightedBlend_C<10, uint16_t>;
88*09537850SAkhilesh Sanikop #endif
89*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
90*09537850SAkhilesh Sanikop }
91*09537850SAkhilesh Sanikop #endif  // LIBGAV1_MAX_BITDEPTH >= 10
92*09537850SAkhilesh Sanikop 
93*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
Init12bpp()94*09537850SAkhilesh Sanikop void Init12bpp() {
95*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(12);
96*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
97*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
98*09537850SAkhilesh Sanikop   dsp->distance_weighted_blend = DistanceWeightedBlend_C<12, uint16_t>;
99*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
100*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
101*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp12bpp_DistanceWeightedBlend
102*09537850SAkhilesh Sanikop   dsp->distance_weighted_blend = DistanceWeightedBlend_C<12, uint16_t>;
103*09537850SAkhilesh Sanikop #endif
104*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
105*09537850SAkhilesh Sanikop }
106*09537850SAkhilesh Sanikop #endif  // LIBGAV1_MAX_BITDEPTH == 12
107*09537850SAkhilesh Sanikop 
108*09537850SAkhilesh Sanikop }  // namespace
109*09537850SAkhilesh Sanikop 
DistanceWeightedBlendInit_C()110*09537850SAkhilesh Sanikop void DistanceWeightedBlendInit_C() {
111*09537850SAkhilesh Sanikop   Init8bpp();
112*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
113*09537850SAkhilesh Sanikop   Init10bpp();
114*09537850SAkhilesh Sanikop #endif
115*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
116*09537850SAkhilesh Sanikop   Init12bpp();
117*09537850SAkhilesh Sanikop #endif
118*09537850SAkhilesh Sanikop }
119*09537850SAkhilesh Sanikop 
120*09537850SAkhilesh Sanikop }  // namespace dsp
121*09537850SAkhilesh Sanikop }  // namespace libgav1
122