HEVC Test Model (HM)  HM-16.3
TComInterpolationFilter.cpp
Go to the documentation of this file.
1 /* The copyright in this software is being made available under the BSD
2  * License, included below. This software may be subject to other third party
3  * and contributor rights, including patent rights, and no such rights are
4  * granted under this license.
5  *
6  * Copyright (c) 2010-2015, ITU/ISO/IEC
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18  * be used to endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
39 // ====================================================================================================================
40 // Includes
41 // ====================================================================================================================
42 
43 #include "TComRom.h"
45 #include <assert.h>
46 
47 #include "TComChromaFormat.h"
48 
49 
52 
53 // ====================================================================================================================
54 // Tables
55 // ====================================================================================================================
56 
58 {
59  { 0, 0, 0, 64, 0, 0, 0, 0 },
60  { -1, 4, -10, 58, 17, -5, 1, 0 },
61  { -1, 4, -11, 40, 40, -11, 4, -1 },
62  { 0, 1, -5, 17, 58, -10, 4, -1 }
63 };
64 
66 {
67  { 0, 64, 0, 0 },
68  { -2, 58, 10, -2 },
69  { -4, 54, 16, -2 },
70  { -6, 46, 28, -4 },
71  { -4, 36, 36, -4 },
72  { -4, 28, 46, -6 },
73  { -2, 16, 54, -4 },
74  { -2, 10, 58, -2 }
75 };
76 
77 // ====================================================================================================================
78 // Private member functions
79 // ====================================================================================================================
80 
94 Void TComInterpolationFilter::filterCopy(Int bitDepth, const Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isFirst, Bool isLast)
95 {
96  Int row, col;
97 
98  if ( isFirst == isLast )
99  {
100  for (row = 0; row < height; row++)
101  {
102  for (col = 0; col < width; col++)
103  {
104  dst[col] = src[col];
105  }
106 
107  src += srcStride;
108  dst += dstStride;
109  }
110  }
111  else if ( isFirst )
112  {
113  const Int shift = std::max<Int>(2, (IF_INTERNAL_PREC - bitDepth));
114 
115  for (row = 0; row < height; row++)
116  {
117  for (col = 0; col < width; col++)
118  {
119  Pel val = leftShift_round(src[col], shift);
120  dst[col] = val - (Pel)IF_INTERNAL_OFFS;
121  }
122 
123  src += srcStride;
124  dst += dstStride;
125  }
126  }
127  else
128  {
129  const Int shift = std::max<Int>(2, (IF_INTERNAL_PREC - bitDepth));
130 
131  Pel maxVal = (1 << bitDepth) - 1;
132  Pel minVal = 0;
133  for (row = 0; row < height; row++)
134  {
135  for (col = 0; col < width; col++)
136  {
137  Pel val = src[ col ];
138  val = rightShift_round((val + IF_INTERNAL_OFFS), shift);
139  if (val < minVal)
140  {
141  val = minVal;
142  }
143  if (val > maxVal)
144  {
145  val = maxVal;
146  }
147  dst[col] = val;
148  }
149 
150  src += srcStride;
151  dst += dstStride;
152  }
153  }
154 }
155 
172 template<Int N, Bool isVertical, Bool isFirst, Bool isLast>
173 Void TComInterpolationFilter::filter(Int bitDepth, Pel const *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, TFilterCoeff const *coeff)
174 {
175  Int row, col;
176 
177  Pel c[8];
178  c[0] = coeff[0];
179  c[1] = coeff[1];
180  if ( N >= 4 )
181  {
182  c[2] = coeff[2];
183  c[3] = coeff[3];
184  }
185  if ( N >= 6 )
186  {
187  c[4] = coeff[4];
188  c[5] = coeff[5];
189  }
190  if ( N == 8 )
191  {
192  c[6] = coeff[6];
193  c[7] = coeff[7];
194  }
195 
196  Int cStride = ( isVertical ) ? srcStride : 1;
197  src -= ( N/2 - 1 ) * cStride;
198 
199  Int offset;
200  Pel maxVal;
201  Int headRoom = std::max<Int>(2, (IF_INTERNAL_PREC - bitDepth));
202  Int shift = IF_FILTER_PREC;
203  // with the current settings (IF_INTERNAL_PREC = 14 and IF_FILTER_PREC = 6), though headroom can be
204  // negative for bit depths greater than 14, shift will remain non-negative for bit depths of 8->20
205  assert(shift >= 0);
206 
207  if ( isLast )
208  {
209  shift += (isFirst) ? 0 : headRoom;
210  offset = 1 << (shift - 1);
211  offset += (isFirst) ? 0 : IF_INTERNAL_OFFS << IF_FILTER_PREC;
212  maxVal = (1 << bitDepth) - 1;
213  }
214  else
215  {
216  shift -= (isFirst) ? headRoom : 0;
217  offset = (isFirst) ? -IF_INTERNAL_OFFS << shift : 0;
218  maxVal = 0;
219  }
220 
221  for (row = 0; row < height; row++)
222  {
223  for (col = 0; col < width; col++)
224  {
225  Int sum;
226 
227  sum = src[ col + 0 * cStride] * c[0];
228  sum += src[ col + 1 * cStride] * c[1];
229  if ( N >= 4 )
230  {
231  sum += src[ col + 2 * cStride] * c[2];
232  sum += src[ col + 3 * cStride] * c[3];
233  }
234  if ( N >= 6 )
235  {
236  sum += src[ col + 4 * cStride] * c[4];
237  sum += src[ col + 5 * cStride] * c[5];
238  }
239  if ( N == 8 )
240  {
241  sum += src[ col + 6 * cStride] * c[6];
242  sum += src[ col + 7 * cStride] * c[7];
243  }
244 
245  Pel val = ( sum + offset ) >> shift;
246  if ( isLast )
247  {
248  val = ( val < 0 ) ? 0 : val;
249  val = ( val > maxVal ) ? maxVal : val;
250  }
251  dst[col] = val;
252  }
253 
254  src += srcStride;
255  dst += dstStride;
256  }
257 }
258 
273 template<Int N>
274 Void TComInterpolationFilter::filterHor(Int bitDepth, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isLast, TFilterCoeff const *coeff)
275 {
276  if ( isLast )
277  {
278  filter<N, false, true, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
279  }
280  else
281  {
282  filter<N, false, true, false>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
283  }
284 }
285 
301 template<Int N>
302 Void TComInterpolationFilter::filterVer(Int bitDepth, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isFirst, Bool isLast, TFilterCoeff const *coeff)
303 {
304  if ( isFirst && isLast )
305  {
306  filter<N, true, true, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
307  }
308  else if ( isFirst && !isLast )
309  {
310  filter<N, true, true, false>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
311  }
312  else if ( !isFirst && isLast )
313  {
314  filter<N, true, false, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
315  }
316  else
317  {
318  filter<N, true, false, false>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
319  }
320 }
321 
322 // ====================================================================================================================
323 // Public member functions
324 // ====================================================================================================================
325 
340 Void TComInterpolationFilter::filterHor(const ComponentID compID, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Int frac, Bool isLast, const ChromaFormat fmt )
341 {
342  if ( frac == 0 )
343  {
344  filterCopy(g_bitDepth[toChannelType(compID)], src, srcStride, dst, dstStride, width, height, true, isLast );
345  }
346  else if (isLuma(compID))
347  {
348  assert(frac >= 0 && frac < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
349  filterHor<NTAPS_LUMA>(g_bitDepth[toChannelType(compID)], src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilter[frac]);
350  }
351  else
352  {
353  const UInt csx = getComponentScaleX(compID, fmt);
354  assert(frac >=0 && csx<2 && (frac<<(1-csx)) < CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
355  filterHor<NTAPS_CHROMA>(g_bitDepth[toChannelType(compID)], src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilter[frac<<(1-csx)]);
356  }
357 }
358 
359 
375 Void TComInterpolationFilter::filterVer(const ComponentID compID, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Int frac, Bool isFirst, Bool isLast, const ChromaFormat fmt )
376 {
377  if ( frac == 0 )
378  {
379  filterCopy(g_bitDepth[toChannelType(compID)], src, srcStride, dst, dstStride, width, height, isFirst, isLast );
380  }
381  else if (isLuma(compID))
382  {
383  assert(frac >= 0 && frac < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
384  filterVer<NTAPS_LUMA>(g_bitDepth[toChannelType(compID)], src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilter[frac]);
385  }
386  else
387  {
388  const UInt csy = getComponentScaleY(compID, fmt);
389  assert(frac >=0 && csy<2 && (frac<<(1-csy)) < CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
390  filterVer<NTAPS_CHROMA>(g_bitDepth[toChannelType(compID)], src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilter[frac<<(1-csy)]);
391  }
392 }
393 
#define IF_FILTER_PREC
Log2 of sum of filter taps.
static Void filterCopy(Int bitDepth, const Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isFirst, Bool isLast)
Apply unit FIR filter to a block of samples.
#define CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS
Definition: TypeDef.h:213
Short TFilterCoeff
filter coefficient
Definition: TypeDef.h:695
void Void
Definition: TypeDef.h:285
ValueType leftShift_round(const ValueType value, const Int shift)
Definition: CommonDef.h:168
global variables & functions (header)
Declaration of TComInterpolationFilter class.
static UInt getComponentScaleY(const ComponentID id, const ChromaFormat fmt)
unsigned int UInt
Definition: TypeDef.h:297
static UInt getComponentScaleX(const ComponentID id, const ChromaFormat fmt)
#define IF_INTERNAL_OFFS
Offset used internally.
Short Pel
pixel type
Definition: TypeDef.h:692
#define LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS
Definition: TypeDef.h:212
#define IF_INTERNAL_PREC
Number of bits for internal precision.
static const TFilterCoeff m_chromaFilter[8][4]
Chroma filter taps.
bool Bool
Definition: TypeDef.h:286
static ChannelType toChannelType(const ComponentID id)
ValueType rightShift_round(const ValueType value, const Int shift)
Definition: CommonDef.h:169
ChromaFormat
chroma formats (according to semantics of chroma_format_idc)
Definition: TypeDef.h:352
Int g_bitDepth[MAX_NUM_CHANNEL_TYPE]
Definition: TComRom.cpp:548
static Void filterVer(Int bitDepth, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isFirst, Bool isLast, TFilterCoeff const *coeff)
Filter a block of samples (vertical)
static Void filter(Int bitDepth, Pel const *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, TFilterCoeff const *coeff)
Apply FIR filter to a block of samples.
int Int
Definition: TypeDef.h:296
ComponentID
Definition: TypeDef.h:368
#define NTAPS_LUMA
Number of taps for luma.
static Bool isLuma(const ComponentID id)
#define NTAPS_CHROMA
Number of taps for chroma.
static Void filterHor(Int bitDepth, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isLast, TFilterCoeff const *coeff)
Filter a block of samples (horizontal)
static const TFilterCoeff m_lumaFilter[4][8]
Luma filter taps.