source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComInterpolationFilter.cpp @ 1313

Last change on this file since 1313 was 1313, checked in by tech, 9 years ago

Merged 14.1-update-dev1@1312.

File size: 15.0 KB
Line 
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
34/**
35 * \file
36 * \brief Implementation of TComInterpolationFilter class
37 */
38
39// ====================================================================================================================
40// Includes
41// ====================================================================================================================
42
43#include "TComRom.h"
44#include "TComInterpolationFilter.h"
45#include <assert.h>
46
47#include "TComChromaFormat.h"
48
49
50//! \ingroup TLibCommon
51//! \{
52
53// ====================================================================================================================
54// Tables
55// ====================================================================================================================
56
57const TFilterCoeff TComInterpolationFilter::m_lumaFilter[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_LUMA] =
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
65const TFilterCoeff TComInterpolationFilter::m_chromaFilter[CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_CHROMA] =
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#if NH_3D_ARP
78const Short TComInterpolationFilter::m_lumaFilterARP[4][NTAPS_LUMA_ARP] =
79{
80  {64,  0},
81  {48, 16},
82  {32, 32},
83  {16, 48}
84};
85const Short TComInterpolationFilter::m_chromaFilterARP[8][NTAPS_CHROMA_ARP] =
86{
87  {64,  0},
88  {56,  8},
89  {48, 16},
90  {40, 24},
91  {32, 32},
92  {24, 40},
93  {16, 48},
94  {8,  56}
95};
96#endif
97
98// ====================================================================================================================
99// Private member functions
100// ====================================================================================================================
101
102/**
103 * \brief Apply unit FIR filter to a block of samples
104 *
105 * \param bitDepth   bitDepth of samples
106 * \param src        Pointer to source samples
107 * \param srcStride  Stride of source samples
108 * \param dst        Pointer to destination samples
109 * \param dstStride  Stride of destination samples
110 * \param width      Width of block
111 * \param height     Height of block
112 * \param isFirst    Flag indicating whether it is the first filtering operation
113 * \param isLast     Flag indicating whether it is the last filtering operation
114 */
115Void TComInterpolationFilter::filterCopy(Int bitDepth, const Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isFirst, Bool isLast)
116{
117  Int row, col;
118
119  if ( isFirst == isLast )
120  {
121    for (row = 0; row < height; row++)
122    {
123      for (col = 0; col < width; col++)
124      {
125        dst[col] = src[col];
126      }
127
128      src += srcStride;
129      dst += dstStride;
130    }
131  }
132  else if ( isFirst )
133  {
134    const Int shift = std::max<Int>(2, (IF_INTERNAL_PREC - bitDepth));
135
136    for (row = 0; row < height; row++)
137    {
138      for (col = 0; col < width; col++)
139      {
140        Pel val = leftShift_round(src[col], shift);
141        dst[col] = val - (Pel)IF_INTERNAL_OFFS;
142      }
143
144      src += srcStride;
145      dst += dstStride;
146    }
147  }
148  else
149  {
150    const Int shift = std::max<Int>(2, (IF_INTERNAL_PREC - bitDepth));
151
152    Pel maxVal = (1 << bitDepth) - 1;
153    Pel minVal = 0;
154    for (row = 0; row < height; row++)
155    {
156      for (col = 0; col < width; col++)
157      {
158        Pel val = src[ col ];
159        val = rightShift_round((val + IF_INTERNAL_OFFS), shift);
160        if (val < minVal)
161        {
162          val = minVal;
163        }
164        if (val > maxVal)
165        {
166          val = maxVal;
167        }
168        dst[col] = val;
169      }
170
171      src += srcStride;
172      dst += dstStride;
173    }
174  }
175}
176
177/**
178 * \brief Apply FIR filter to a block of samples
179 *
180 * \tparam N          Number of taps
181 * \tparam isVertical Flag indicating filtering along vertical direction
182 * \tparam isFirst    Flag indicating whether it is the first filtering operation
183 * \tparam isLast     Flag indicating whether it is the last filtering operation
184 * \param  bitDepth   Bit depth of samples
185 * \param  src        Pointer to source samples
186 * \param  srcStride  Stride of source samples
187 * \param  dst        Pointer to destination samples
188 * \param  dstStride  Stride of destination samples
189 * \param  width      Width of block
190 * \param  height     Height of block
191 * \param  coeff      Pointer to filter taps
192 */
193template<Int N, Bool isVertical, Bool isFirst, Bool isLast>
194Void TComInterpolationFilter::filter(Int bitDepth, Pel const *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, TFilterCoeff const *coeff)
195{
196  Int row, col;
197
198  Pel c[8];
199  c[0] = coeff[0];
200  c[1] = coeff[1];
201  if ( N >= 4 )
202  {
203    c[2] = coeff[2];
204    c[3] = coeff[3];
205  }
206  if ( N >= 6 )
207  {
208    c[4] = coeff[4];
209    c[5] = coeff[5];
210  }
211  if ( N == 8 )
212  {
213    c[6] = coeff[6];
214    c[7] = coeff[7];
215  }
216
217  Int cStride = ( isVertical ) ? srcStride : 1;
218  src -= ( N/2 - 1 ) * cStride;
219
220  Int offset;
221  Pel maxVal;
222  Int headRoom = std::max<Int>(2, (IF_INTERNAL_PREC - bitDepth));
223  Int shift    = IF_FILTER_PREC;
224  // with the current settings (IF_INTERNAL_PREC = 14 and IF_FILTER_PREC = 6), though headroom can be
225  // negative for bit depths greater than 14, shift will remain non-negative for bit depths of 8->20
226  assert(shift >= 0);
227
228  if ( isLast )
229  {
230    shift += (isFirst) ? 0 : headRoom;
231    offset = 1 << (shift - 1);
232    offset += (isFirst) ? 0 : IF_INTERNAL_OFFS << IF_FILTER_PREC;
233    maxVal = (1 << bitDepth) - 1;
234  }
235  else
236  {
237    shift -= (isFirst) ? headRoom : 0;
238    offset = (isFirst) ? -IF_INTERNAL_OFFS << shift : 0;
239    maxVal = 0;
240  }
241
242  for (row = 0; row < height; row++)
243  {
244    for (col = 0; col < width; col++)
245    {
246      Int sum;
247
248      sum  = src[ col + 0 * cStride] * c[0];
249      sum += src[ col + 1 * cStride] * c[1];
250      if ( N >= 4 )
251      {
252        sum += src[ col + 2 * cStride] * c[2];
253        sum += src[ col + 3 * cStride] * c[3];
254      }
255      if ( N >= 6 )
256      {
257        sum += src[ col + 4 * cStride] * c[4];
258        sum += src[ col + 5 * cStride] * c[5];
259      }
260      if ( N == 8 )
261      {
262        sum += src[ col + 6 * cStride] * c[6];
263        sum += src[ col + 7 * cStride] * c[7];
264      }
265
266      Pel val = ( sum + offset ) >> shift;
267      if ( isLast )
268      {
269        val = ( val < 0 ) ? 0 : val;
270        val = ( val > maxVal ) ? maxVal : val;
271      }
272      dst[col] = val;
273    }
274
275    src += srcStride;
276    dst += dstStride;
277  }
278}
279
280/**
281 * \brief Filter a block of samples (horizontal)
282 *
283 * \tparam N          Number of taps
284 * \param  bitDepth   Bit depth of samples
285 * \param  src        Pointer to source samples
286 * \param  srcStride  Stride of source samples
287 * \param  dst        Pointer to destination samples
288 * \param  dstStride  Stride of destination samples
289 * \param  width      Width of block
290 * \param  height     Height of block
291 * \param  isLast     Flag indicating whether it is the last filtering operation
292 * \param  coeff      Pointer to filter taps
293 */
294template<Int N>
295Void TComInterpolationFilter::filterHor(Int bitDepth, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isLast, TFilterCoeff const *coeff)
296{
297  if ( isLast )
298  {
299    filter<N, false, true, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
300  }
301  else
302  {
303    filter<N, false, true, false>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
304  }
305}
306
307/**
308 * \brief Filter a block of samples (vertical)
309 *
310 * \tparam N          Number of taps
311 * \param  bitDepth   Bit depth
312 * \param  src        Pointer to source samples
313 * \param  srcStride  Stride of source samples
314 * \param  dst        Pointer to destination samples
315 * \param  dstStride  Stride of destination samples
316 * \param  width      Width of block
317 * \param  height     Height of block
318 * \param  isFirst    Flag indicating whether it is the first filtering operation
319 * \param  isLast     Flag indicating whether it is the last filtering operation
320 * \param  coeff      Pointer to filter taps
321 */
322template<Int N>
323Void TComInterpolationFilter::filterVer(Int bitDepth, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Bool isFirst, Bool isLast, TFilterCoeff const *coeff)
324{
325  if ( isFirst && isLast )
326  {
327    filter<N, true, true, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
328  }
329  else if ( isFirst && !isLast )
330  {
331    filter<N, true, true, false>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
332  }
333  else if ( !isFirst && isLast )
334  {
335    filter<N, true, false, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
336  }
337  else
338  {
339    filter<N, true, false, false>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);
340  }
341}
342
343// ====================================================================================================================
344// Public member functions
345// ====================================================================================================================
346
347/**
348 * \brief Filter a block of Luma/Chroma samples (horizontal)
349 *
350 * \param  compID     Chroma component ID
351 * \param  src        Pointer to source samples
352 * \param  srcStride  Stride of source samples
353 * \param  dst        Pointer to destination samples
354 * \param  dstStride  Stride of destination samples
355 * \param  width      Width of block
356 * \param  height     Height of block
357 * \param  frac       Fractional sample offset
358 * \param  isLast     Flag indicating whether it is the last filtering operation
359 * \param  fmt        Chroma format
360 * \param  bitDepth   Bit depth
361 */
362Void TComInterpolationFilter::filterHor(const ComponentID compID, Pel *src, Int srcStride, Pel *dst, Int dstStride, Int width, Int height, Int frac, Bool isLast, const ChromaFormat fmt, const Int bitDepth
363#if NH_3D_ARP
364    , Bool filterType
365#endif
366)
367{
368  if ( frac == 0 )
369  {
370    filterCopy(bitDepth, src, srcStride, dst, dstStride, width, height, true, isLast );
371  }
372  else if (isLuma(compID))
373  {
374    assert(frac >= 0 && frac < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
375#if NH_3D_ARP
376    if(filterType)
377    {
378      filterHor<NTAPS_LUMA_ARP>(bitDepth, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilterARP[frac]);
379    }
380    else
381    {
382#endif
383    filterHor<NTAPS_LUMA>(bitDepth, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilter[frac]);
384#if NH_3D_ARP
385    }
386#endif
387
388  }
389  else
390  {
391    const UInt csx = getComponentScaleX(compID, fmt);
392    assert(frac >=0 && csx<2 && (frac<<(1-csx)) < CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
393#if NH_3D_ARP
394    if(filterType)
395    {
396      filterHor<NTAPS_CHROMA_ARP>(bitDepth, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilterARP[frac]);
397    }
398    else
399    {
400#endif
401    filterHor<NTAPS_CHROMA>(bitDepth, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilter[frac<<(1-csx)]);
402#if NH_3D_ARP
403    }
404#endif
405  }
406}
407
408
409/**
410 * \brief Filter a block of Luma/Chroma samples (vertical)
411 *
412 * \param  compID     Colour component ID
413 * \param  src        Pointer to source samples
414 * \param  srcStride  Stride of source samples
415 * \param  dst        Pointer to destination samples
416 * \param  dstStride  Stride of destination samples
417 * \param  width      Width of block
418 * \param  height     Height of block
419 * \param  frac       Fractional sample offset
420 * \param  isFirst    Flag indicating whether it is the first filtering operation
421 * \param  isLast     Flag indicating whether it is the last filtering operation
422 * \param  fmt        Chroma format
423 * \param  bitDepth   Bit depth
424 */
425Void 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, const Int bitDepth
426#if NH_3D_ARP
427    , Bool filterType
428#endif
429)
430{
431  if ( frac == 0 )
432  {
433    filterCopy(bitDepth, src, srcStride, dst, dstStride, width, height, isFirst, isLast );
434  }
435  else if (isLuma(compID))
436  {
437    assert(frac >= 0 && frac < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
438#if NH_3D_ARP
439    if(filterType)
440    {
441      filterVer<NTAPS_LUMA_ARP>(bitDepth, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilterARP[frac]);   
442    }
443    else
444    {
445#endif
446    filterVer<NTAPS_LUMA>(bitDepth, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilter[frac]);
447#if NH_3D_ARP
448    }
449#endif
450
451  }
452  else
453  {
454    const UInt csy = getComponentScaleY(compID, fmt);
455    assert(frac >=0 && csy<2 && (frac<<(1-csy)) < CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS);
456#if NH_3D_ARP
457    if(filterType)
458    {
459      filterVer<NTAPS_CHROMA_ARP>(bitDepth, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilterARP[frac]);   
460    }
461    else
462    {
463#endif
464    filterVer<NTAPS_CHROMA>(bitDepth, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilter[frac<<(1-csy)]);
465#if NH_3D_ARP
466    }
467#endif
468    }
469    }
470//! \}
Note: See TracBrowser for help on using the repository browser.