xref: /aosp_15_r20/external/libgav1/src/dsp/intra_edge.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/intra_edge.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <cassert>
18*09537850SAkhilesh Sanikop #include <cstdint>
19*09537850SAkhilesh Sanikop #include <cstring>
20*09537850SAkhilesh Sanikop 
21*09537850SAkhilesh Sanikop #include "src/dsp/dsp.h"
22*09537850SAkhilesh Sanikop #include "src/utils/common.h"
23*09537850SAkhilesh Sanikop 
24*09537850SAkhilesh Sanikop namespace libgav1 {
25*09537850SAkhilesh Sanikop namespace dsp {
26*09537850SAkhilesh Sanikop namespace {
27*09537850SAkhilesh Sanikop 
28*09537850SAkhilesh Sanikop constexpr int kKernelTaps = 5;
29*09537850SAkhilesh Sanikop constexpr int kKernels[3][kKernelTaps] = {
30*09537850SAkhilesh Sanikop     {0, 4, 8, 4, 0}, {0, 5, 6, 5, 0}, {2, 4, 4, 4, 2}};
31*09537850SAkhilesh Sanikop constexpr int kMaxUpsampleSize = 16;
32*09537850SAkhilesh Sanikop 
33*09537850SAkhilesh Sanikop template <typename Pixel>
IntraEdgeFilter_C(void * buffer,int size,int strength)34*09537850SAkhilesh Sanikop void IntraEdgeFilter_C(void* buffer, int size, int strength) {
35*09537850SAkhilesh Sanikop   assert(strength > 0);
36*09537850SAkhilesh Sanikop   Pixel edge[129];
37*09537850SAkhilesh Sanikop   memcpy(edge, buffer, sizeof(edge[0]) * size);
38*09537850SAkhilesh Sanikop   auto* const dst_buffer = static_cast<Pixel*>(buffer);
39*09537850SAkhilesh Sanikop   const int kernel_index = strength - 1;
40*09537850SAkhilesh Sanikop   for (int i = 1; i < size; ++i) {
41*09537850SAkhilesh Sanikop     int sum = 0;
42*09537850SAkhilesh Sanikop     for (int j = 0; j < kKernelTaps; ++j) {
43*09537850SAkhilesh Sanikop       const int k = Clip3(i + j - 2, 0, size - 1);
44*09537850SAkhilesh Sanikop       sum += kKernels[kernel_index][j] * edge[k];
45*09537850SAkhilesh Sanikop     }
46*09537850SAkhilesh Sanikop     dst_buffer[i] = RightShiftWithRounding(sum, 4);
47*09537850SAkhilesh Sanikop   }
48*09537850SAkhilesh Sanikop }
49*09537850SAkhilesh Sanikop 
50*09537850SAkhilesh Sanikop template <int bitdepth, typename Pixel>
IntraEdgeUpsampler_C(void * buffer,int size)51*09537850SAkhilesh Sanikop void IntraEdgeUpsampler_C(void* buffer, int size) {
52*09537850SAkhilesh Sanikop   assert(size % 4 == 0 && size <= kMaxUpsampleSize);
53*09537850SAkhilesh Sanikop   auto* const pixel_buffer = static_cast<Pixel*>(buffer);
54*09537850SAkhilesh Sanikop   Pixel temp[kMaxUpsampleSize + 3];
55*09537850SAkhilesh Sanikop   temp[0] = temp[1] = pixel_buffer[-1];
56*09537850SAkhilesh Sanikop   memcpy(temp + 2, pixel_buffer, sizeof(temp[0]) * size);
57*09537850SAkhilesh Sanikop   temp[size + 2] = pixel_buffer[size - 1];
58*09537850SAkhilesh Sanikop 
59*09537850SAkhilesh Sanikop   pixel_buffer[-2] = temp[0];
60*09537850SAkhilesh Sanikop   for (int i = 0; i < size; ++i) {
61*09537850SAkhilesh Sanikop     const int sum =
62*09537850SAkhilesh Sanikop         -temp[i] + (9 * temp[i + 1]) + (9 * temp[i + 2]) - temp[i + 3];
63*09537850SAkhilesh Sanikop     pixel_buffer[2 * i - 1] =
64*09537850SAkhilesh Sanikop         Clip3(RightShiftWithRounding(sum, 4), 0, (1 << bitdepth) - 1);
65*09537850SAkhilesh Sanikop     pixel_buffer[2 * i] = temp[i + 2];
66*09537850SAkhilesh Sanikop   }
67*09537850SAkhilesh Sanikop }
68*09537850SAkhilesh Sanikop 
Init8bpp()69*09537850SAkhilesh Sanikop void Init8bpp() {
70*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(8);
71*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
72*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
73*09537850SAkhilesh Sanikop   dsp->intra_edge_filter = IntraEdgeFilter_C<uint8_t>;
74*09537850SAkhilesh Sanikop   dsp->intra_edge_upsampler = IntraEdgeUpsampler_C<8, uint8_t>;
75*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
76*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
77*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp8bpp_IntraEdgeFilter
78*09537850SAkhilesh Sanikop   dsp->intra_edge_filter = IntraEdgeFilter_C<uint8_t>;
79*09537850SAkhilesh Sanikop #endif
80*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp8bpp_IntraEdgeUpsampler
81*09537850SAkhilesh Sanikop   dsp->intra_edge_upsampler = IntraEdgeUpsampler_C<8, uint8_t>;
82*09537850SAkhilesh Sanikop #endif
83*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
84*09537850SAkhilesh Sanikop }
85*09537850SAkhilesh Sanikop 
86*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
Init10bpp()87*09537850SAkhilesh Sanikop void Init10bpp() {
88*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(10);
89*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
90*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
91*09537850SAkhilesh Sanikop   dsp->intra_edge_filter = IntraEdgeFilter_C<uint16_t>;
92*09537850SAkhilesh Sanikop   dsp->intra_edge_upsampler = IntraEdgeUpsampler_C<10, uint16_t>;
93*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
94*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
95*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp10bpp_IntraEdgeFilter
96*09537850SAkhilesh Sanikop   dsp->intra_edge_filter = IntraEdgeFilter_C<uint16_t>;
97*09537850SAkhilesh Sanikop #endif
98*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp10bpp_IntraEdgeUpsampler
99*09537850SAkhilesh Sanikop   dsp->intra_edge_upsampler = IntraEdgeUpsampler_C<10, uint16_t>;
100*09537850SAkhilesh Sanikop #endif
101*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
102*09537850SAkhilesh Sanikop }
103*09537850SAkhilesh Sanikop #endif  // LIBGAV1_MAX_BITDEPTH >= 10
104*09537850SAkhilesh Sanikop 
105*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
Init12bpp()106*09537850SAkhilesh Sanikop void Init12bpp() {
107*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(12);
108*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
109*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
110*09537850SAkhilesh Sanikop   dsp->intra_edge_filter = IntraEdgeFilter_C<uint16_t>;
111*09537850SAkhilesh Sanikop   dsp->intra_edge_upsampler = IntraEdgeUpsampler_C<12, uint16_t>;
112*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
113*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
114*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp12bpp_IntraEdgeFilter
115*09537850SAkhilesh Sanikop   dsp->intra_edge_filter = IntraEdgeFilter_C<uint16_t>;
116*09537850SAkhilesh Sanikop #endif
117*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp12bpp_IntraEdgeUpsampler
118*09537850SAkhilesh Sanikop   dsp->intra_edge_upsampler = IntraEdgeUpsampler_C<12, uint16_t>;
119*09537850SAkhilesh Sanikop #endif
120*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
121*09537850SAkhilesh Sanikop }
122*09537850SAkhilesh Sanikop #endif  // LIBGAV1_MAX_BITDEPTH == 12
123*09537850SAkhilesh Sanikop 
124*09537850SAkhilesh Sanikop }  // namespace
125*09537850SAkhilesh Sanikop 
IntraEdgeInit_C()126*09537850SAkhilesh Sanikop void IntraEdgeInit_C() {
127*09537850SAkhilesh Sanikop   Init8bpp();
128*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
129*09537850SAkhilesh Sanikop   Init10bpp();
130*09537850SAkhilesh Sanikop #endif
131*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
132*09537850SAkhilesh Sanikop   Init12bpp();
133*09537850SAkhilesh Sanikop #endif
134*09537850SAkhilesh Sanikop }
135*09537850SAkhilesh Sanikop 
136*09537850SAkhilesh Sanikop }  // namespace dsp
137*09537850SAkhilesh Sanikop }  // namespace libgav1
138