source: SHVCSoftware/branches/SHM-dev/source/App/TAppDownConvert/DownConvert.cpp @ 1598

Last change on this file since 1598 was 1587, checked in by interdigital, 8 years ago

JCTVC-Y0028 was adopted to support 10bit down conversion

File size: 26.9 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-2016, 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#include "DownConvert.h"
35
36#include <cmath>
37#include <cstring>
38
39
40#define  TMM_TABLE_SIZE          512
41
42
43//=================================================
44//
45//   G E N E R A L   M A I N   F U N C T I O N S
46//
47//=================================================
48
49DownConvert::DownConvert()
50: m_iImageStride            ( 0 )
51, m_paiImageBuffer          ( 0 )
52, m_paiTmp1dBuffer          ( 0 )
53{
54}
55 
56DownConvert::~DownConvert()
57{
58  xDestroy();
59}
60
61bool
62DownConvert::init( int iMaxWidth, int iMaxHeight, int iMaxMargin )
63{
64  xDestroy();
65
66  iMaxWidth                += 2 * iMaxMargin;
67  iMaxHeight               += 2 * iMaxMargin;
68  int iPicSize              =   iMaxWidth * iMaxHeight;
69  int iMaxDim               = ( iMaxWidth > iMaxHeight ? iMaxWidth : iMaxHeight );
70  m_iImageStride            = iMaxWidth;
71  m_paiImageBuffer          = new int [ iPicSize ];
72  m_paiTmp1dBuffer          = new int [ iMaxDim ];
73
74  ROFRS( m_paiImageBuffer,          true );
75  ROFRS( m_paiTmp1dBuffer,          true );
76
77  return false;
78}
79
80void
81DownConvert::destroy()
82{
83  delete this;
84}
85
86//===========================================================================
87//
88//   M A I N   F U N C T I O N S   F O R   D O W N C O N V E R T   T O O L
89//
90//===========================================================================
91
92
93void
94DownConvert::downsamplingSVC( short*    pucBufferY,   int   iStrideY,
95                              short*    pucBufferU,   int   iStrideU,
96                              short*    pucBufferV,   int   iStrideV,
97                              ResizeParameters* pcParameters, bool  bBotCoincided )
98{
99  int   iBaseW                  =   pcParameters->m_iFrameWidth;
100  int   iBaseH                  =   pcParameters->m_iFrameHeight;
101  int   iCurrW                  =   pcParameters->m_iRefLayerFrmWidth;
102  int   iCurrH                  =   pcParameters->m_iRefLayerFrmHeight;
103  bool  bTopAndBottomResampling = ( pcParameters->m_bRefLayerFrameMbsOnlyFlag == false  &&
104                                    pcParameters->m_bRefLayerFieldPicFlag     == false  &&
105                                    pcParameters->m_bFrameMbsOnlyFlag         == false  &&
106                                    pcParameters->m_bFieldPicFlag             == false    );
107  bool  bVerticalDownsampling   = ( pcParameters->m_bFrameMbsOnlyFlag         == true   &&
108                                    pcParameters->m_bRefLayerFieldPicFlag     == true     );
109  bool  bCurrBotField           = ( pcParameters->m_bFieldPicFlag             == true   &&
110                                    pcParameters->m_bBotFieldFlag             == true     );
111  bool  bBotFieldFlag           = ( pcParameters->m_bRefLayerFrameMbsOnlyFlag ?  false
112                                  : pcParameters->m_bFieldPicFlag             ?  pcParameters->m_bBotFieldFlag
113                                  : pcParameters->m_bRefLayerFieldPicFlag     ?  pcParameters->m_bRefLayerBotFieldFlag
114                                  : false );
115  int   iBaseField              = ( pcParameters->m_bRefLayerFrameMbsOnlyFlag ?  0 : 1 );
116  int   iCurrField              = ( pcParameters->m_bFieldPicFlag             ?  1 : 0 );
117  int   iBaseBot                = ( bBotFieldFlag ? 1 : 0 );
118  int   iCurrBot                = ( bCurrBotField ? 1 : 0 );
119
120  //==== check bot field coincided parameter for interlaced to progressive resampling =====
121  if( pcParameters->m_bRefLayerFrameMbsOnlyFlag && ! pcParameters->m_bFrameMbsOnlyFlag )
122  {
123    bBotFieldFlag = bBotCoincided;
124  }
125
126  //=======================
127  //=====   L U M A   =====
128  //=======================
129  assert( bTopAndBottomResampling == false );
130  if( !bTopAndBottomResampling )
131  {
132    short* pSrc = pucBufferY + iStrideY * iCurrBot;
133    short* pDes = pucBufferY + iStrideY * iBaseBot;
134    xCopyToImageBuffer  ( pSrc,         iCurrW, iCurrH >> iCurrField, iStrideY << iCurrField );
135    xCompDownsampling   ( pcParameters, false,  bBotFieldFlag,        bVerticalDownsampling  );
136    xCopyFromImageBuffer( pDes,         iBaseW, iBaseH >> iBaseField, iStrideY << iBaseField );
137  }
138
139  iBaseW >>= 1;
140  iBaseH >>= 1;
141  iCurrW >>= 1;
142  iCurrH >>= 1;
143
144  //===========================
145  //=====   C H R O M A   =====
146  //===========================
147  if( !bTopAndBottomResampling )
148  {
149    //===== U =====
150    short* pSrc = pucBufferU + iStrideU * iCurrBot;
151    short* pDes = pucBufferU + iStrideU * iBaseBot;
152    xCopyToImageBuffer  ( pSrc,         iCurrW, iCurrH >> iCurrField, iStrideU << iCurrField );
153    xCompDownsampling   ( pcParameters, true,   bBotFieldFlag,        bVerticalDownsampling  );
154    xCopyFromImageBuffer( pDes,         iBaseW, iBaseH >> iBaseField, iStrideU << iBaseField );
155
156    //===== V =====
157    pSrc = pucBufferV + iStrideV * iCurrBot;
158    pDes = pucBufferV + iStrideV * iBaseBot;
159    xCopyToImageBuffer  ( pSrc,         iCurrW, iCurrH >> iCurrField, iStrideV << iCurrField );
160    xCompDownsampling   ( pcParameters, true,   bBotFieldFlag,        bVerticalDownsampling  );
161    xCopyFromImageBuffer( pDes,         iBaseW, iBaseH >> iBaseField, iStrideV << iBaseField );
162  }
163}
164
165
166//======================================================
167//
168//   G E N E R A L   H E L P E R    F U N C T I O N S
169//
170//======================================================
171
172void
173DownConvert::xDestroy()
174{
175  delete [] m_paiImageBuffer;
176  delete [] m_paiTmp1dBuffer;
177  m_paiImageBuffer          = 0;
178  m_paiTmp1dBuffer          = 0;
179}
180
181int
182DownConvert::xClip( int iValue, int imin, int imax )
183{
184  ROTRS( iValue < imin, imin );
185  ROTRS( iValue > imax, imax );
186  return iValue;
187}
188
189
190//===============================================================================
191//
192//   H E L P E R   F U N C T I O N S   F O R   D O W N C O N V E R T   T O O L
193//
194//===============================================================================
195
196void
197DownConvert::xCopyToImageBuffer( short* pucSrc, int iWidth, int iHeight, int iStride )
198{
199  int* piDes = m_paiImageBuffer;
200  for( int j = 0; j < iHeight; j++ )
201  {
202    for( int i = 0; i < iWidth;  i++ )
203    {
204      piDes[i] = (int)pucSrc[i];
205    }
206    piDes   += m_iImageStride;
207    pucSrc  += iStride;
208  }
209}
210
211void
212DownConvert::xCopyFromImageBuffer( short* pucDes, int iWidth, int iHeight, int iStride )
213{
214  int* piSrc = m_paiImageBuffer;
215  for( int j = 0; j < iHeight; j++ )
216  {
217    for( int i = 0; i < iWidth;  i++ )
218    {
219      pucDes[i] = (short)piSrc[i];
220    }
221    pucDes  += iStride;
222    piSrc   += m_iImageStride;
223  }
224}
225
226void
227DownConvert::xCompDownsampling( ResizeParameters* pcParameters, bool bChroma, bool bBotFlag, bool bVerticalDownsampling )
228{
229  //===== set general parameters =====
230  int   iBotField   = ( bBotFlag ? 1 : 0 );
231  int   iFactor     = ( !bChroma ? 1 : 2 );
232  int   iRefPhaseX  = ( !bChroma ? 0 : pcParameters->m_iChromaPhaseX );
233  int   iRefPhaseY  = ( !bChroma ? 0 : pcParameters->m_iChromaPhaseY );
234  int   iPhaseX     = ( !bChroma ? 0 : pcParameters->m_iRefLayerChromaPhaseX );
235  int   iPhaseY     = ( !bChroma ? 0 : pcParameters->m_iRefLayerChromaPhaseY );
236  int   iRefW       = pcParameters->m_iFrameWidth         / iFactor;  // reference layer frame width
237  int   iRefH       = pcParameters->m_iFrameHeight        / iFactor;  // reference layer frame height
238  int   iOutW       = pcParameters->m_iScaledRefFrmWidth  / iFactor;  // scaled reference layer frame width
239  int   iOutH       = pcParameters->m_iScaledRefFrmHeight / iFactor;  // scaled reference layer frame height
240  int   iGlobalW    = pcParameters->m_iRefLayerFrmWidth   / iFactor;  // current frame width
241  int   iGlobalH    = pcParameters->m_iRefLayerFrmHeight  / iFactor;  // current frame height
242  int   iLeftOffset = pcParameters->m_iLeftFrmOffset      / iFactor;  // current left frame offset
243  int   iTopOffset  = pcParameters->m_iTopFrmOffset       / iFactor;  // current  top frame offset
244
245  //===== set input/output size =====
246  int   iBaseField  = ( pcParameters->m_bRefLayerFrameMbsOnlyFlag ? 0 : 1 );
247  int   iCurrField  = ( pcParameters->m_bRefLayerFrameMbsOnlyFlag && pcParameters->m_bFrameMbsOnlyFlag ? 0 : 1 );
248  int   iBaseW      = iRefW;
249  int   iBaseH      = iRefH       >> iBaseField;
250  int   iCurrW      = iGlobalW;
251  int   iCurrH      = iGlobalH    >> iCurrField;
252  int   iLOffset    = iLeftOffset;
253  int   iTOffset    = iTopOffset  >> iCurrField;
254  int   iROffset    = iCurrW - iLOffset -   iOutW;
255  int   iBOffset    = iCurrH - iTOffset - ( iOutH >> iCurrField );
256
257  //===== set position calculation parameters =====
258  int   iScaledW    = iOutW;
259  int   iScaledH    = ( ! pcParameters->m_bRefLayerFrameMbsOnlyFlag || pcParameters->m_bFrameMbsOnlyFlag ? iOutH : iOutH / 2 );
260  int   iShiftX     = ( pcParameters->m_iLevelIdc <= 30 ? 16 : 31 - CeilLog2( iScaledW ) );
261  int   iShiftY     = ( pcParameters->m_iLevelIdc <= 30 ? 16 : 31 - CeilLog2( iScaledH ) );
262  int   iScaleX     = ( ( (unsigned int)iScaledW << iShiftX ) + ( iRefW >> 1 ) ) / iRefW;
263  int   iScaleY     = ( ( (unsigned int)iScaledH << iShiftY ) + ( iRefH >> 1 ) ) / iRefH;
264
265  int   inputBitDepth = pcParameters->inputBitDepth;
266  int   outputBitDepth = pcParameters->outputBitDepth;
267
268  if( ! pcParameters->m_bFrameMbsOnlyFlag || ! pcParameters->m_bRefLayerFrameMbsOnlyFlag )
269  {
270    if( pcParameters->m_bRefLayerFrameMbsOnlyFlag )
271    {
272      iPhaseY       = iPhaseY + 4 * iBotField + ( 3 - iFactor );
273#if ZERO_PHASE
274      iRefPhaseY    = 2 * iRefPhaseY + 0;
275#else
276      iRefPhaseY    = 2 * iRefPhaseY + 2;
277#endif
278    }
279    else
280    {
281      iPhaseY       = iPhaseY    + 4 * iBotField;
282      iRefPhaseY    = iRefPhaseY + 4 * iBotField;
283    }
284  }
285#if ZERO_PHASE
286  int   iAddX       = ( ( ( iScaledW * ( 0 + iRefPhaseX ) ) << ( iShiftX - 2 ) ) + ( iRefW >> 1 ) ) / iRefW + ( 1 << ( iShiftX - 5 ) );
287  int   iAddY       = ( ( ( iScaledH * ( 0 + iRefPhaseY ) ) << ( iShiftY - 2 ) ) + ( iRefH >> 1 ) ) / iRefH + ( 1 << ( iShiftY - 5 ) );
288  int   iDeltaX     = 4 * ( 0 + iPhaseX ) - ( iLeftOffset << 4 );
289  int   iDeltaY     = 4 * ( 0 + iPhaseY ) - ( iTopOffset  << 4 );
290#else
291  int   iAddX       = ( ( ( iScaledW * ( 2 + iRefPhaseX ) ) << ( iShiftX - 2 ) ) + ( iRefW >> 1 ) ) / iRefW + ( 1 << ( iShiftX - 5 ) );
292  int   iAddY       = ( ( ( iScaledH * ( 2 + iRefPhaseY ) ) << ( iShiftY - 2 ) ) + ( iRefH >> 1 ) ) / iRefH + ( 1 << ( iShiftY - 5 ) );
293  int   iDeltaX     = 4 * ( 2 + iPhaseX ) - ( iLeftOffset << 4 );
294  int   iDeltaY     = 4 * ( 2 + iPhaseY ) - ( iTopOffset  << 4 );
295#endif
296  if( ! pcParameters->m_bFrameMbsOnlyFlag || ! pcParameters->m_bRefLayerFrameMbsOnlyFlag )
297  {
298#if ZERO_PHASE
299    iAddY           = ( ( ( iScaledH * ( 0 + iRefPhaseY ) ) << ( iShiftY - 3 ) ) + ( iRefH >> 1 ) ) / iRefH + ( 1 << ( iShiftY - 5 ) );
300    iDeltaY         = 2 * ( 0 + iPhaseY ) - ( iTopOffset  << 3 );
301#else
302    iAddY           = ( ( ( iScaledH * ( 2 + iRefPhaseY ) ) << ( iShiftY - 3 ) ) + ( iRefH >> 1 ) ) / iRefH + ( 1 << ( iShiftY - 5 ) );
303    iDeltaY         = 2 * ( 2 + iPhaseY ) - ( iTopOffset  << 3 );
304#endif
305  }
306
307  //===== vertical downsampling to generate a field signal from a progressive frame =====
308  if( bVerticalDownsampling )
309  {
310    xVertDownsampling( iCurrW, iCurrH, bBotFlag, inputBitDepth, outputBitDepth);
311  }
312
313  //===== basic downsampling of a frame or field =====
314  xBasicDownsampling( iBaseW,   iBaseH,   iCurrW,   iCurrH,
315                      iLOffset, iTOffset, iROffset, iBOffset,
316                      iShiftX,  iShiftY,  iScaleX,  iScaleY,
317                      iAddX,    iAddY,    iDeltaX,  iDeltaY,
318                      inputBitDepth, outputBitDepth);
319}
320
321void
322DownConvert::xVertDownsampling( int   iBaseW,
323                                int   iBaseH,
324                                bool  bBotFlag, int inputBitDepth, int outputBitDepth)
325{
326  int aiVertFilter[13]  = { 2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2 };
327  int iBotField         = ( bBotFlag ? 1 : 0 );
328  int iCurrW            = iBaseW;
329  int iCurrH            = iBaseH << 1;
330
331  int shift = 6 + (inputBitDepth - outputBitDepth);
332  int shift_round = (1 << (shift -1));
333
334  //===== vertical downsampling =====
335  for( int j = 0; j < iCurrW; j++ )
336  {
337    int* piSrc = &m_paiImageBuffer[j];
338    for( int i = 0; i < iBaseH; i++ )
339    {
340      m_paiTmp1dBuffer[i] = 0;
341      for( int k = 0; k < 13; k++ )
342      {
343        int m = xClip( 2 * i + iBotField + k - 6, 0, iCurrH - 1 );
344        m_paiTmp1dBuffer[i] += aiVertFilter[k] * piSrc[m*m_iImageStride];
345      }
346      m_paiTmp1dBuffer[i] = ( m_paiTmp1dBuffer[i] + shift_round ) >> shift;
347    }
348    //--- clip and copy back to image buffer ---
349      for( int n = 0; n < iBaseH; n++ )
350      {
351        piSrc[n*m_iImageStride] = xClip( m_paiTmp1dBuffer[n], 0, ((1<<outputBitDepth)-1) );
352      }
353  }
354}
355
356void
357DownConvert::xBasicDownsampling( int iBaseW,   int iBaseH,   int iCurrW,   int iCurrH,
358                                 int iLOffset, int iTOffset, int iROffset, int iBOffset,
359                                 int iShiftX,  int iShiftY,  int iScaleX,  int iScaleY,
360                                 int iAddX,    int iAddY,    int iDeltaX,  int iDeltaY, int inputBitDepth, int outputBitDepth )
361{
362  const int filter16[8][16][12] =
363  {
364    { // D = 1
365      {   0,   0,   0,   0,   0, 128,   0,   0,   0,   0,   0,   0 },
366      {   0,   0,   0,   2,  -6, 127,   7,  -2,   0,   0,   0,   0 },
367      {   0,   0,   0,   3, -12, 125,  16,  -5,   1,   0,   0,   0 },
368      {   0,   0,   0,   4, -16, 120,  26,  -7,   1,   0,   0,   0 },
369      {   0,   0,   0,   5, -18, 114,  36, -10,   1,   0,   0,   0 },
370      {   0,   0,   0,   5, -20, 107,  46, -12,   2,   0,   0,   0 },
371      {   0,   0,   0,   5, -21,  99,  57, -15,   3,   0,   0,   0 },
372      {   0,   0,   0,   5, -20,  89,  68, -18,   4,   0,   0,   0 },
373      {   0,   0,   0,   4, -19,  79,  79, -19,   4,   0,   0,   0 },
374      {   0,   0,   0,   4, -18,  68,  89, -20,   5,   0,   0,   0 },
375      {   0,   0,   0,   3, -15,  57,  99, -21,   5,   0,   0,   0 },
376      {   0,   0,   0,   2, -12,  46, 107, -20,   5,   0,   0,   0 },
377      {   0,   0,   0,   1, -10,  36, 114, -18,   5,   0,   0,   0 },
378      {   0,   0,   0,   1,  -7,  26, 120, -16,   4,   0,   0,   0 },
379      {   0,   0,   0,   1,  -5,  16, 125, -12,   3,   0,   0,   0 },
380      {   0,   0,   0,   0,  -2,   7, 127,  -6,   2,   0,   0,   0 }
381    },
382    { // D = 1.5
383      {   0,   2,   0, -14,  33,  86,  33, -14,   0,   2,   0,   0 },
384      {   0,   1,   1, -14,  29,  85,  38, -13,  -1,   2,   0,   0 },
385      {   0,   1,   2, -14,  24,  84,  43, -12,  -2,   2,   0,   0 },
386      {   0,   1,   2, -13,  19,  83,  48, -11,  -3,   2,   0,   0 },
387      {   0,   0,   3, -13,  15,  81,  53, -10,  -4,   3,   0,   0 },
388      {   0,   0,   3, -12,  11,  79,  57,  -8,  -5,   3,   0,   0 },
389      {   0,   0,   3, -11,   7,  76,  62,  -5,  -7,   3,   0,   0 },
390      {   0,   0,   3, -10,   3,  73,  65,  -2,  -7,   3,   0,   0 },
391      {   0,   0,   3,  -9,   0,  70,  70,   0,  -9,   3,   0,   0 },
392      {   0,   0,   3,  -7,  -2,  65,  73,   3, -10,   3,   0,   0 },
393      {   0,   0,   3,  -7,  -5,  62,  76,   7, -11,   3,   0,   0 },
394      {   0,   0,   3,  -5,  -8,  57,  79,  11, -12,   3,   0,   0 },
395      {   0,   0,   3,  -4, -10,  53,  81,  15, -13,   3,   0,   0 },
396      {   0,   0,   2,  -3, -11,  48,  83,  19, -13,   2,   1,   0 },
397      {   0,   0,   2,  -2, -12,  43,  84,  24, -14,   2,   1,   0 },
398      {   0,   0,   2,  -1, -13,  38,  85,  29, -14,   1,   1,   0 }
399    },
400    { // D = 2
401      {   0,   5,   -6,  -10,  37,  76,   37,  -10,  -6,    5,  0,   0}, //0
402      {   0,   5,   -4,  -11,  33,  76,   40,  -9,    -7,    5,  0,   0}, //1
403      //{   0,   5,   -3,  -12,  28,  75,   44,  -7,    -8,    5,  1,   0}, //2
404      {  -1,   5,   -3,  -12,  29,  75,   45,  -7,    -8,   5,  0,   0}, //2 new coefficients in m24499
405      {  -1,   4,   -2,  -13,  25,  75,   48,  -5,    -9,    5,  1,   0}, //3
406      {  -1,   4,   -1,  -13,  22,  73,   52,  -3,    -10,  4,  1,   0}, //4
407      {  -1,   4,   0,    -13,  18,  72,   55,  -1,    -11,  4,  2,  -1}, //5
408      {  -1,   4,   1,    -13,  14,  70,   59,  2,    -12,  3,  2,  -1}, //6
409      {  -1,   3,   1,    -13,  11,  68,   62,  5,    -12,  3,  2,  -1}, //7
410      {  -1,   3,   2,    -13,  8,  65,   65,  8,    -13,  2,  3,  -1}, //8
411      {  -1,   2,   3,    -12,  5,  62,   68,  11,    -13,  1,  3,  -1}, //9
412      {  -1,   2,   3,    -12,  2,  59,   70,  14,    -13,  1,  4,  -1}, //10
413      {  -1,   2,   4,    -11,  -1,  55,   72,  18,    -13,  0,  4,  -1}, //11
414      {   0,   1,   4,    -10,  -3,  52,   73,  22,    -13,  -1,  4,  -1}, //12
415      {   0,   1,   5,    -9,    -5,  48,   75,  25,    -13,  -2,  4,  -1}, //13
416      //{   0,   1,   5,    -8,    -7,  44,   75,  28,    -12,  -3,  5,   0}, //14
417      {    0,   0,   5,    -8,   -7,  45,   75,  29,    -12,  -3,  5,  -1}  , //14 new coefficients in m24499 
418      {   0,   0,   5,    -7,    -9,  40,   76,  33,    -11,  -4,  5,   0}, //15
419    },
420    { // D = 2.5
421      {   2,  -3,   -9,  6,   39,  58,   39,  6,   -9,  -3,    2,    0}, // 0
422      {   2,  -3,   -9,  4,   38,  58,   43,  7,   -9,  -4,    1,    0}, // 1
423      {   2,  -2,   -9,  2,   35,  58,   44,  9,   -8,  -4,    1,    0}, // 2
424      {   1,  -2,   -9,  1,   34,  58,   46,  11,   -8,  -5,    1,    0}, // 3
425      //{   1,  -1,   -8,  -1,   31,  57,   48,  13,   -8,  -5,    1,    0}, // 4
426      {   1,  -1,   -8,  -1,   31,  57,   47,  13,   -7,  -5,    1,    0},  // 4 new coefficients in m24499 
427      {   1,  -1,   -8,  -2,   29,  56,   49,  15,   -7,  -6,    1,    1}, // 5
428      {   1,  0,   -8,  -3,   26,  55,   51,  17,   -7,  -6,    1,    1}, // 6
429      {   1,  0,   -7,  -4,   24,  54,   52,  19,   -6,  -7,    1,    1}, // 7
430      {   1,  0,   -7,  -5,   22,  53,   53,  22,   -5,  -7,    0,    1}, // 8
431      {   1,  1,   -7,  -6,   19,  52,   54,  24,   -4,  -7,    0,    1}, // 9
432      {   1,  1,   -6,  -7,   17,  51,   55,  26,   -3,  -8,    0,    1}, // 10
433      {   1,  1,   -6,  -7,   15,  49,   56,  29,   -2,  -8,    -1,    1}, // 11
434      //{   0,  1,   -5,  -8,   13,  48,   57,  31,   -1,  -8,    -1,    1}, // 12 new coefficients in m24499
435      {   0,  1,   -5,  -7,   13,  47,  57,  31,  -1,    -8,   -1,    1}, // 12   
436      {   0,  1,   -5,  -8,   11,  46,   58,  34,   1,    -9,    -2,    1}, // 13
437      {   0,  1,   -4,  -8,   9,    44,   58,  35,   2,    -9,    -2,    2}, // 14
438      {   0,  1,   -4,  -9,   7,    43,   58,  38,   4,    -9,    -3,    2}, // 15
439    },
440    { // D = 3
441      {  -2,  -7,   0,  17,  35,  43,  35,  17,   0,  -7,  -5,   2 },
442      {  -2,  -7,  -1,  16,  34,  43,  36,  18,   1,  -7,  -5,   2 },
443      {  -1,  -7,  -1,  14,  33,  43,  36,  19,   1,  -6,  -5,   2 },
444      {  -1,  -7,  -2,  13,  32,  42,  37,  20,   3,  -6,  -5,   2 },
445      {   0,  -7,  -3,  12,  31,  42,  38,  21,   3,  -6,  -5,   2 },
446      {   0,  -7,  -3,  11,  30,  42,  39,  23,   4,  -6,  -6,   1 },
447      {   0,  -7,  -4,  10,  29,  42,  40,  24,   5,  -6,  -6,   1 },
448      {   1,  -7,  -4,   9,  27,  41,  40,  25,   6,  -5,  -6,   1 },
449      {   1,  -6,  -5,   7,  26,  41,  41,  26,   7,  -5,  -6,   1 },
450      {   1,  -6,  -5,   6,  25,  40,  41,  27,   9,  -4,  -7,   1 },
451      {   1,  -6,  -6,   5,  24,  40,  42,  29,  10,  -4,  -7,   0 },
452      {   1,  -6,  -6,   4,  23,  39,  42,  30,  11,  -3,  -7,   0 },
453      {   2,  -5,  -6,   3,  21,  38,  42,  31,  12,  -3,  -7,   0 },
454      {   2,  -5,  -6,   3,  20,  37,  42,  32,  13,  -2,  -7,  -1 },
455      {   2,  -5,  -6,   1,  19,  36,  43,  33,  14,  -1,  -7,  -1 },
456      {   2,  -5,  -7,   1,  18,  36,  43,  34,  16,  -1,  -7,  -2 }
457    },
458    { // D = 3.5
459      {  -6,  -3,   5,  19,  31,  36,  31,  19,   5,  -3,  -6,   0 },
460      {  -6,  -4,   4,  18,  31,  37,  32,  20,   6,  -3,  -6,  -1 },
461      {  -6,  -4,   4,  17,  30,  36,  33,  21,   7,  -3,  -6,  -1 },
462      {  -5,  -5,   3,  16,  30,  36,  33,  22,   8,  -2,  -6,  -2 },
463      {  -5,  -5,   2,  15,  29,  36,  34,  23,   9,  -2,  -6,  -2 },
464      {  -5,  -5,   2,  15,  28,  36,  34,  24,  10,  -2,  -6,  -3 },
465      {  -4,  -5,   1,  14,  27,  36,  35,  24,  10,  -1,  -6,  -3 },
466      {  -4,  -5,   0,  13,  26,  35,  35,  25,  11,   0,  -5,  -3 },
467      {  -4,  -6,   0,  12,  26,  36,  36,  26,  12,   0,  -6,  -4 },
468      {  -3,  -5,   0,  11,  25,  35,  35,  26,  13,   0,  -5,  -4 },
469      {  -3,  -6,  -1,  10,  24,  35,  36,  27,  14,   1,  -5,  -4 },
470      {  -3,  -6,  -2,  10,  24,  34,  36,  28,  15,   2,  -5,  -5 },
471      {  -2,  -6,  -2,   9,  23,  34,  36,  29,  15,   2,  -5,  -5 },
472      {  -2,  -6,  -2,   8,  22,  33,  36,  30,  16,   3,  -5,  -5 },
473      {  -1,  -6,  -3,   7,  21,  33,  36,  30,  17,   4,  -4,  -6 },
474      {  -1,  -6,  -3,   6,  20,  32,  37,  31,  18,   4,  -4,  -6 }
475    },
476    { // D = 4
477      {  -9,   0,   9,  20,  28,  32,  28,  20,   9,   0,  -9,   0 },
478      {  -9,   0,   8,  19,  28,  32,  29,  20,  10,   0,  -4,  -5 },
479      {  -9,  -1,   8,  18,  28,  32,  29,  21,  10,   1,  -4,  -5 },
480      {  -9,  -1,   7,  18,  27,  32,  30,  22,  11,   1,  -4,  -6 },
481      {  -8,  -2,   6,  17,  27,  32,  30,  22,  12,   2,  -4,  -6 },
482      {  -8,  -2,   6,  16,  26,  32,  31,  23,  12,   2,  -4,  -6 },
483      {  -8,  -2,   5,  16,  26,  31,  31,  23,  13,   3,  -3,  -7 },
484      {  -8,  -3,   5,  15,  25,  31,  31,  24,  14,   4,  -3,  -7 },
485      {  -7,  -3,   4,  14,  25,  31,  31,  25,  14,   4,  -3,  -7 },
486      {  -7,  -3,   4,  14,  24,  31,  31,  25,  15,   5,  -3,  -8 },
487      {  -7,  -3,   3,  13,  23,  31,  31,  26,  16,   5,  -2,  -8 },
488      {  -6,  -4,   2,  12,  23,  31,  32,  26,  16,   6,  -2,  -8 },
489      {  -6,  -4,   2,  12,  22,  30,  32,  27,  17,   6,  -2,  -8 },
490      {  -6,  -4,   1,  11,  22,  30,  32,  27,  18,   7,  -1,  -9 },
491      {  -5,  -4,   1,  10,  21,  29,  32,  28,  18,   8,  -1,  -9 },
492      {  -5,  -4,   0,  10,  20,  29,  32,  28,  19,   8,   0,  -9 }
493    },
494    { // D = 5.5
495      {  -8,   7,  13,  18,  22,  24,  22,  18,  13,   7,   2, -10 },
496      {  -8,   7,  13,  18,  22,  23,  22,  19,  13,   7,   2, -10 },
497      {  -8,   6,  12,  18,  22,  23,  22,  19,  14,   8,   2, -10 },
498      {  -9,   6,  12,  17,  22,  23,  23,  19,  14,   8,   3, -10 },
499      {  -9,   6,  12,  17,  21,  23,  23,  19,  14,   9,   3, -10 },
500      {  -9,   5,  11,  17,  21,  23,  23,  20,  15,   9,   3, -10 },
501      {  -9,   5,  11,  16,  21,  23,  23,  20,  15,   9,   4, -10 },
502      {  -9,   5,  10,  16,  21,  23,  23,  20,  15,  10,   4, -10 },
503      { -10,   5,  10,  16,  20,  23,  23,  20,  16,  10,   5, -10 },
504      { -10,   4,  10,  15,  20,  23,  23,  21,  16,  10,   5,  -9 },
505      { -10,   4,   9,  15,  20,  23,  23,  21,  16,  11,   5,  -9 },
506      { -10,   3,   9,  15,  20,  23,  23,  21,  17,  11,   5,  -9 },
507      { -10,   3,   9,  14,  19,  23,  23,  21,  17,  12,   6,  -9 },
508      { -10,   3,   8,  14,  19,  23,  23,  22,  17,  12,   6,  -9 },
509      { -10,   2,   8,  14,  19,  22,  23,  22,  18,  12,   6,  -8 },
510      { -10,   2,   7,  13,  19,  22,  23,  22,  18,  13,   7,  -8 }
511    }
512  };
513
514  //===== determine filter sets =====
515  int iCropW      = iCurrW - iLOffset - iROffset;
516  int iCropH      = iCurrH - iTOffset - iBOffset;
517  int iVerFilter  = 0;
518  int iHorFilter  = 0;
519  if      (  4 * iCropH > 15 * iBaseH )   iVerFilter  = 7;
520  else if (  7 * iCropH > 20 * iBaseH )   iVerFilter  = 6;
521  else if (  2 * iCropH >  5 * iBaseH )   iVerFilter  = 5;
522  else if (  1 * iCropH >  2 * iBaseH )   iVerFilter  = 4;
523  else if (  3 * iCropH >  5 * iBaseH )   iVerFilter  = 3;
524  else if (  4 * iCropH >  5 * iBaseH )   iVerFilter  = 2;
525  else if ( 19 * iCropH > 20 * iBaseH )   iVerFilter  = 1;
526  if      (  4 * iCropW > 15 * iBaseW )   iHorFilter  = 7;
527  else if (  7 * iCropW > 20 * iBaseW )   iHorFilter  = 6;
528  else if (  2 * iCropW >  5 * iBaseW )   iHorFilter  = 5;
529  else if (  1 * iCropW >  2 * iBaseW )   iHorFilter  = 4;
530  else if (  3 * iCropW >  5 * iBaseW )   iHorFilter  = 3;
531  else if (  4 * iCropW >  5 * iBaseW )   iHorFilter  = 2;
532  else if ( 19 * iCropW > 20 * iBaseW )   iHorFilter  = 1;
533
534  int iShiftXM4 = iShiftX - 4;
535  int iShiftYM4 = iShiftY - 4;
536
537  int shift = 14 + (inputBitDepth - outputBitDepth);
538  int shift_round = (1 << (shift -1));
539
540  //===== horizontal downsampling =====
541  {
542    for( int j = 0; j < iCurrH; j++ )
543    {
544      int* piSrc = &m_paiImageBuffer[j*m_iImageStride];
545      for( int i = 0; i < iBaseW; i++ )
546      {
547        int iRefPos16 = (int)( (unsigned int)( i * iScaleX + iAddX ) >> iShiftXM4 ) - iDeltaX;
548        int iPhase    = iRefPos16  & 15;
549        int iRefPos   = iRefPos16 >>  4;
550
551        m_paiTmp1dBuffer[i] = 0;
552        for( int k = 0; k < 12; k++ )
553        {
554          int m = xClip( iRefPos + k - 5, 0, iCurrW - 1 );
555          m_paiTmp1dBuffer[i] += filter16[iHorFilter][iPhase][k] * piSrc[m];
556        }
557      }
558      //--- copy row back to image buffer ---
559      memcpy( piSrc, m_paiTmp1dBuffer, iBaseW*sizeof(int) );
560    }
561  }
562
563  //===== vertical downsampling =====
564  {
565    for( int i = 0; i < iBaseW; i++ )
566    {
567      int* piSrc = &m_paiImageBuffer[i];
568      for( int j = 0; j < iBaseH; j++ )
569      {
570        int iRefPos16 = (int)( (unsigned int)( j * iScaleY + iAddY ) >> iShiftYM4 ) - iDeltaY;
571        int iPhase    = iRefPos16  & 15;
572        int iRefPos   = iRefPos16 >>  4;
573
574        m_paiTmp1dBuffer[j] = 0;
575        for( int k = 0; k < 12; k++ )
576        {
577          int m = xClip( iRefPos + k - 5, 0, iCurrH - 1 );
578          m_paiTmp1dBuffer[j] += filter16[iVerFilter][iPhase][k] * piSrc[m*m_iImageStride];
579        }
580        m_paiTmp1dBuffer[j] = ( m_paiTmp1dBuffer[j] + shift_round ) >> shift;
581      }
582      //--- clip and copy back to image buffer ---
583        for( int n = 0; n < iBaseH; n++ )
584        {
585          piSrc[n*m_iImageStride] = xClip( m_paiTmp1dBuffer[n], 0, ((1<<outputBitDepth)-1));
586        }
587    }
588  }
589}
590
591
592
593
Note: See TracBrowser for help on using the repository browser.