source: 3DVCSoftware/branches/HTM-15.2-dev/source/Lib/TLibRenderer/TRenFilter.cpp @ 1373

Last change on this file since 1373 was 1373, checked in by tech, 8 years ago

Macro fixes.

  • Property svn:eol-style set to native
File size: 52.5 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 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#include "TRenImage.h"
36#include "TRenFilter.h"
37#include "TRenInterpFilter.h"
38#if NH_3D_VSO
39
40///// COMMON /////
41template<UInt bitDepth>
42Void TRenFilter<bitDepth>::setSubPelShiftLUT( Int iLutPrec, Int** piSubPelShiftLUT, Int iShift )
43{
44  //ToDo: use same rounding for left and right
45  AOT( iLutPrec < 0 || iLutPrec > 2 );
46  Int iStep = 1 << iLutPrec;
47  for (Int iDelta = 0; iDelta < (iStep << 1)+1; iDelta++ )
48  {
49    for (Int iCurDelta = 0; iCurDelta < (iStep << 1)+1; iCurDelta++ )
50    {
51      if (iCurDelta <= iDelta)
52      {
53        piSubPelShiftLUT[iDelta][iCurDelta] =  (iDelta != 0) ?( ( iStep * iCurDelta + ( iDelta >> 1) )/ iDelta) + iShift * iStep :  iShift * iStep;
54      }
55      else
56      {
57        piSubPelShiftLUT[iDelta][iCurDelta] = 0xdeaddead;
58      }
59    }
60  }
61}
62template<UInt bitDepth>
63Void TRenFilter<bitDepth>::setupZLUT( Bool bBlendUseDistWeight, Int iBlendZThresPerc, Int iRelDistToLeft, Int** ppiBaseShiftLUTLeft, Int** ppiBaseShiftLUTRight, Int& riBlendZThres, Int& riBlendDistWeight, Int* piInvZLUTLeft, Int* piInvZLUTRight )
64{
65  AOT( iRelDistToLeft == -1 );
66  riBlendDistWeight = bBlendUseDistWeight ? iRelDistToLeft :  1 << (REN_VDWEIGHT_PREC - 1);
67
68  for (UInt uiDepthValue = 0; uiDepthValue <= 256; uiDepthValue++)
69  {
70    //GT: retrieve depth approx from shift
71    piInvZLUTLeft [uiDepthValue] = abs( ppiBaseShiftLUTLeft [0][uiDepthValue] );
72    piInvZLUTRight[uiDepthValue] = abs( ppiBaseShiftLUTRight[0][uiDepthValue] );
73  }
74  // Set Threshold
75  riBlendZThres  = ( std::max( abs(piInvZLUTLeft[0]- piInvZLUTLeft[255]), abs(piInvZLUTRight[0]- piInvZLUTRight[255]) ) * iBlendZThresPerc + 50)  / 100;
76}
77
78template<UInt bitDepth>
79Void TRenFilter<bitDepth>::filledToUsedPelMap( PelImage* pcFilledImage, PelImage* pcUsedPelsImage, Int iUsedPelMapMarExt )
80{
81  // Convert to binary map
82  Int iWidth  = pcFilledImage      ->getPlane(0)->getWidth ();
83  Int iHeight = pcFilledImage      ->getPlane(0)->getHeight();
84
85  AOT( iWidth  != pcUsedPelsImage  ->getPlane(0)->getWidth () );
86  AOT( iHeight != pcUsedPelsImage  ->getPlane(0)->getHeight() );
87  AOF( pcUsedPelsImage->is420() );
88
89  Int iSrcStride  = pcFilledImage  ->getPlane(0)->getStride();
90  Int iDstStrideY = pcUsedPelsImage->getPlane(0)->getStride();
91  Int iDstStrideU = pcUsedPelsImage->getPlane(1)->getStride();
92  Int iDstStrideV = pcUsedPelsImage->getPlane(2)->getStride();
93
94  Pel* pcSrcData  = pcFilledImage  ->getPlane(0)->getPlaneData();
95  Pel* pcDstDataY = pcUsedPelsImage->getPlane(0)->getPlaneData();
96  Pel* pcDstDataU = pcUsedPelsImage->getPlane(1)->getPlaneData();
97  Pel* pcDstDataV = pcUsedPelsImage->getPlane(2)->getPlaneData(); // Only used as buffer
98
99  for (Int iPosY = 0; iPosY < iHeight; iPosY++ )
100  {
101    for (Int iPosX = 0; iPosX < iWidth; iPosX++ )
102    {
103      pcDstDataY[iPosX] = ( pcSrcData[iPosX] != REN_IS_FILLED ) ? REN_USED_PEL : REN_UNUSED_PEL;
104
105      if ((iPosX & 1) && (iPosY & 1))
106      {
107        pcDstDataU[iPosX >> 1] = (   ( pcSrcData[iPosX                 ] != REN_IS_FILLED )
108          || ( pcSrcData[iPosX - 1             ] != REN_IS_FILLED )
109          || ( pcSrcData[iPosX     - iSrcStride] != REN_IS_FILLED )
110          || ( pcSrcData[iPosX - 1 - iSrcStride] != REN_IS_FILLED )
111          ) ? REN_USED_PEL : REN_UNUSED_PEL;
112      }
113    }
114
115    if ( iPosY & 1 )
116    {
117      pcDstDataU += iDstStrideU;
118    }
119
120    pcDstDataY += iDstStrideY;
121    pcSrcData  += iSrcStride;
122  }
123
124  //// Dilatation for Interpolation Filters ////
125  //GT: should better be defined somewhere else ...
126  const Int iLumaIntFiltHalfSize   = 4;
127  const Int iChromaIntFiltHalfSize = 2;
128
129  Int iDilateSizeLuma   = iLumaIntFiltHalfSize   +   iUsedPelMapMarExt      ;
130  Int iDilateSizeChroma = iChromaIntFiltHalfSize + ( iUsedPelMapMarExt >> 1);
131
132  pcDstDataY = pcUsedPelsImage->getPlane(0)->getPlaneData();
133  pcDstDataU = pcUsedPelsImage->getPlane(1)->getPlaneData();
134  pcDstDataV = pcUsedPelsImage->getPlane(2)->getPlaneData();
135
136  // Dilate Luma horizontally
137  xDilate( pcDstDataY, iDstStrideY, iWidth, iHeight, pcDstDataY, iDstStrideY, iDilateSizeLuma, false, true  );
138  xDilate( pcDstDataY, iDstStrideY, iWidth, iHeight, pcDstDataY, iDstStrideY, iDilateSizeLuma, false, false );
139
140  // Dilate Chorma vertically and horizontally (for UV-up)
141  xDilate( pcDstDataU, iDstStrideU, iWidth>>1, iHeight>>1, pcDstDataU, iDstStrideU, iDilateSizeChroma, false, true  );
142  xDilate( pcDstDataU, iDstStrideU, iWidth>>1, iHeight>>1, pcDstDataU, iDstStrideU, iDilateSizeChroma, false, false );
143
144  xDilate( pcDstDataU, iDstStrideU, iWidth>>1, iHeight>>1, pcDstDataU, iDstStrideU, iChromaIntFiltHalfSize, true, true  );
145  xDilate( pcDstDataU, iDstStrideU, iWidth>>1, iHeight>>1, pcDstDataU, iDstStrideU, iChromaIntFiltHalfSize, true, false );
146
147  for (Int iPosY = 0; iPosY < (iHeight >> 1); iPosY++ )
148  {
149    for (Int iPosX = 0; iPosX < (iWidth >> 1); iPosX++ )
150    {
151      pcDstDataV[iPosX] = pcDstDataU[iPosX];
152    }
153
154    pcDstDataU += iDstStrideU;
155    pcDstDataV += iDstStrideV;
156  }
157}
158
159/////////// Copy /////////////
160template<UInt bitDepth>
161Void TRenFilter<bitDepth>::copy(const Pel* pcInputPlaneData, Int iInputStride, Int iWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
162{
163  xDistributeArray(pcInputPlaneData, iInputStride, 1, 1, iWidth, iHeight ,pcOutputPlaneData, iOutputStride, 1 , 1 );
164
165}
166
167/////////// Horizontal Mirror ///////////
168template<UInt bitDepth> template <typename T> 
169Void TRenFilter<bitDepth>::mirrorHor( TRenImage<T> *pcImage )
170{
171  for (UInt uCurPlane = 0 ; uCurPlane < pcImage->getNumberOfPlanes(); uCurPlane++ )
172  {
173    mirrorHor( pcImage->getPlane(uCurPlane) );
174  }
175}
176
177template<UInt bitDepth> template <typename T> 
178Void TRenFilter<bitDepth>::mirrorHor( TRenImagePlane<T> *pcImagePlane )
179{
180  T* pcPlaneData = pcImagePlane->getPlaneDataOrg();
181  T cTemp;
182  UInt uiStride = pcImagePlane->getStride();
183  UInt uiHeight = pcImagePlane->getHeightOrg();
184  UInt uiWidth  = pcImagePlane->getWidthOrg();
185
186  for (UInt uiPosY = 0; uiPosY < uiHeight; uiPosY++)
187  {
188    for (UInt uiPosX = 0; uiPosX < ( (uiWidth+1) >> 1); uiPosX++ )
189    {
190      cTemp = pcPlaneData[uiPosX];
191      pcPlaneData[uiPosX] = pcPlaneData[uiWidth - uiPosX-1];
192      pcPlaneData[uiWidth-uiPosX-1] = cTemp;
193    }
194    pcPlaneData += uiStride;
195  }
196}
197
198/////////// Comparison ///////////
199template<UInt bitDepth>
200Int64 TRenFilter<bitDepth>::SSE   (PelImagePlane* pcInputPlane1, PelImagePlane* pcInputPlane2, Bool bLuma )
201{
202  UInt uiWidth     = pcInputPlane1->getWidth();
203  UInt uiHeight    = pcInputPlane1->getHeight();
204
205  UInt uiStride1   = pcInputPlane1->getStride();
206  UInt uiStride2   = pcInputPlane2->getStride();
207
208  Pel* pucImData1  = pcInputPlane1->getPlaneData();
209  Pel* pucImData2  = pcInputPlane2->getPlaneData();
210
211  return SSE( pucImData1, (Int) uiStride1, (Int) uiWidth, (Int) uiHeight, pucImData2, (Int) uiStride2, bLuma );
212}
213
214template<UInt bitDepth>
215Int64 TRenFilter<bitDepth>::SSE( Pel* piSrc1, Int iSrcStride1, Int iWidth, Int iHeight,  Pel* piSrc2, Int iSrcStride2, Bool bLuma )
216{
217  Int64 iSSE = 0;
218
219
220  Int iShift = ( bitDepth  - 8 ) << 1 ;
221  for(Int iPosY = 0; iPosY < iHeight; iPosY++)
222  {
223    for(Int iPosX = 0; iPosX < iWidth; iPosX++)
224    {
225      Int iDiff = ( piSrc1[iPosX] - piSrc2[iPosX] );
226      iSSE += (( iDiff * iDiff ) >> iShift);
227    }
228    piSrc1 += iSrcStride1;
229    piSrc2 += iSrcStride2;
230  }
231  return iSSE;
232}
233
234template<UInt bitDepth> template <typename T> 
235Bool TRenFilter<bitDepth>::compare( TRenImage<T> *pInputImage1, TRenImage<T> *pInputImage2 )
236{
237  Bool bIsEqual = true;
238  for (UInt uiCurPlane = 0 ; uiCurPlane < pInputImage1->getNumberOfPlanes(); uiCurPlane++ )
239  {
240    bIsEqual = bIsEqual && compare(pInputImage1->getPlane(uiCurPlane), pInputImage2->getPlane(uiCurPlane));
241  }
242  return bIsEqual;
243}
244
245template<UInt bitDepth> template <typename T> 
246Bool TRenFilter<bitDepth>::compare   (TRenImagePlane<T>* pcInputPlane1  , TRenImagePlane<T>* pcInputPlane2   )
247{
248  UInt uiWidth  = pcInputPlane1->getWidth();
249  UInt uiHeight = pcInputPlane1->getHeight();
250
251  UInt uiStride1 = pcInputPlane1->getStride();
252  UInt uiStride2 = pcInputPlane2->getStride();
253
254  T* pucImData1  = pcInputPlane1->getPlaneData();
255  T* pucImData2  = pcInputPlane2->getPlaneData();
256
257  Bool bEqual = true;
258  for(UInt uiPosY = 0; uiPosY < uiHeight; uiPosY++)
259  {
260
261    for(UInt uiPosX = 0; uiPosX < uiWidth; uiPosX++)
262    {
263      bEqual = bEqual && ( pucImData1[uiPosX] == pucImData2[uiPosX]);
264    }
265    pucImData1 += uiStride1;
266    pucImData2 += uiStride2;
267  }
268  return bEqual;
269}
270
271/////////// Sampling ///////////
272template<UInt bitDepth>
273inline Void TRenFilter<bitDepth>::sampleUp2Tap13(PelImage* pcInputImage, PelImage* pcOutputImage)
274{ // UpSampling from JSVM Software (DownConvertStatic) ???
275
276  UInt uiNumPlanes = pcInputImage->getNumberOfPlanes();
277
278  for (UInt uiCurPlane = 0; uiCurPlane < uiNumPlanes; uiCurPlane++)
279  {
280    PelImagePlane* pcInputPlane  = pcInputImage ->getPlane(uiCurPlane);
281    PelImagePlane* pcOutputPlane = pcOutputImage->getPlane(uiCurPlane);
282
283    Int iWidth  = pcInputPlane->getWidth();
284    Int iHeight = pcInputPlane->getHeight();
285
286    Int iInputStride  = pcInputPlane->getStride();
287    Int iOutputStride = pcOutputPlane->getStride();
288
289    assert( iWidth  == 2 * pcOutputPlane->getWidth ());
290    assert( iHeight == 2 * pcOutputPlane->getHeight());
291
292    Int iOffset;
293
294    Pel *pcInputPlaneData   = pcInputPlane->getPlaneData();
295    Int *piDataVerUp        = new Int[iWidth * iHeight * 2];
296    Pel *pcOutputPlaneData  = pcOutputPlane->getPlaneData();
297
298    // Up sampling filter.
299    Int aiFilterCoeff[16] = { 0, 0, 1, 0, -5, 0, 20, 32, 20, 0, -5,  0, 1, 0, 0, 32 };
300
301    // Normalization factors for filtered values.
302    Int iDivH = 1, iDivV = 1, iAddH = 0, iAddV = 0;
303
304    // Factors after horizontal and vertical filtering.
305    iDivH = (aiFilterCoeff[15]*aiFilterCoeff[15]); iAddH = iDivH / 2;
306
307    Int* piDst = new Int[2*iWidth];
308    //1) VERTICAL UPSAMPLING.
309
310    // Process all cols.
311    for(Int i=0; i<iWidth; i++ )
312    {
313      // Set source (col) poInter.
314      Pel* pcSrc = &pcInputPlaneData[i];
315
316      // Process all rows.
317      for( Int j=0; j<iHeight; j++ )
318      {
319        // Adjust indices of border samples.
320        Int i00 = ((j <   3) ? 0   : j-3) * iInputStride;
321        Int i01 = ((j <   2) ? 0   : j-2) * iInputStride;
322        Int i02 = ((j <   1) ? 0   : j-1) * iInputStride;
323        Int i03 = ((j < iHeight  ) ? j   : j-1) * iInputStride;
324        Int i04 = ((j < iHeight-1) ? j+1 : j-1) * iInputStride;
325        Int i05 = ((j < iHeight-2) ? j+2 : j-1) * iInputStride;
326        Int i06 = ((j < iHeight-3) ? j+3 : j-1) * iInputStride;
327        Int i07 = ((j < iHeight-4) ? j+4 : j-1) * iInputStride;
328
329        // Calculate filtered (even) sample.
330        piDst[2*j+0] = aiFilterCoeff[13] * pcSrc[i00]
331        + aiFilterCoeff[11] * pcSrc[i01]
332        + aiFilterCoeff[ 9] * pcSrc[i02]
333        + aiFilterCoeff[ 7] * pcSrc[i03]
334        + aiFilterCoeff[ 5] * pcSrc[i04]
335        + aiFilterCoeff[ 3] * pcSrc[i05]
336        + aiFilterCoeff[ 1] * pcSrc[i06];
337
338        // Calculate filtered (odd) sample.
339        piDst[2*j+1] = aiFilterCoeff[14] * pcSrc[i00]
340        + aiFilterCoeff[12] * pcSrc[i01]
341        + aiFilterCoeff[10] * pcSrc[i02]
342        + aiFilterCoeff[ 8] * pcSrc[i03]
343        + aiFilterCoeff[ 6] * pcSrc[i04]
344        + aiFilterCoeff[ 4] * pcSrc[i05]
345        + aiFilterCoeff[ 2] * pcSrc[i06]
346        + aiFilterCoeff[ 0] * pcSrc[i07];
347      }
348
349      // Process all filtered samples.
350      for(Int j=0; j<(2*iHeight); j++ )
351      {
352        // Scale and copy to image buffer.
353        piDataVerUp[iWidth*j+i] = (piDst[j] + iAddV) / iDivV;
354      }
355    }
356
357    // Update h
358    iHeight *= 2;
359
360    // 2) HORIZONTAL UPSAMPLING.
361
362    // Process all rows.
363    for( Int j=0; j<iHeight; j++ )
364    {
365      // Set source (row) poInter.
366      Int* piSrc = &piDataVerUp[iWidth*j];
367
368      // Process all cols.
369      for( Int i=0; i<iWidth; i++ )
370      {
371        // Adjust indices of border samples.
372        Int i00 = (i <   3) ? 0   : i-3;
373        Int i01 = (i <   2) ? 0   : i-2;
374        Int i02 = (i <   1) ? 0   : i-1;
375        Int i03 = (i < iWidth  ) ? i   : iWidth-1;
376        Int i04 = (i < iWidth-1) ? i+1 : iWidth-1;
377        Int i05 = (i < iWidth-2) ? i+2 : iWidth-1;
378        Int i06 = (i < iWidth-3) ? i+3 : iWidth-1;
379        Int i07 = (i < iWidth-4) ? i+4 : iWidth-1;
380
381        // Calculate filtered (even) sample.
382        piDst[2*i+0] =   aiFilterCoeff[13] * piSrc[i00]
383        + aiFilterCoeff[11] * piSrc[i01]
384        + aiFilterCoeff[ 9] * piSrc[i02]
385        + aiFilterCoeff[ 7] * piSrc[i03]
386        + aiFilterCoeff[ 5] * piSrc[i04]
387        + aiFilterCoeff[ 3] * piSrc[i05]
388        + aiFilterCoeff[ 1] * piSrc[i06];
389
390        // Calculate filtered (odd) sample.
391        piDst[2*i+1] = aiFilterCoeff[14] * piSrc[i00]
392        + aiFilterCoeff[12] * piSrc[i01]
393        + aiFilterCoeff[10] * piSrc[i02]
394        + aiFilterCoeff[ 8] * piSrc[i03]
395        + aiFilterCoeff[ 6] * piSrc[i04]
396        + aiFilterCoeff[ 4] * piSrc[i05]
397        + aiFilterCoeff[ 2] * piSrc[i06]
398        + aiFilterCoeff[ 0] * piSrc[i07];
399      }
400
401      iOffset = 2* iOutputStride * j;
402      // Process all filtered samples.
403      for(Int i=0; i<iWidth*2; i++ )
404      {
405        // Scale and copy to image buffer.
406        pcOutputPlaneData[iOffset+i] = ClipBD((Pel) ((piDst[i] + iAddH) / iDivH), bitDepth);
407      }
408    }
409
410    delete [] piDataVerUp;
411    delete [] piDst;
412
413  }
414}
415
416template<UInt bitDepth>
417Void TRenFilter<bitDepth>::sampleDown2Tap13(PelImage* pcInputImage, PelImage* pcOutputImage)
418{ // DownSampling from JSVM Software (DownConvertStatic) ??
419
420  UInt uiNumPlanes = pcInputImage->getNumberOfPlanes();
421
422  for (UInt uiCurPlane = 0; uiCurPlane < uiNumPlanes; uiCurPlane++)
423  {
424    sampleDown2Tap13( pcInputImage ->getPlane(uiCurPlane),  pcOutputImage->getPlane(uiCurPlane) );
425  }
426};
427
428template<UInt bitDepth>
429Void TRenFilter<bitDepth>::sampleDown2Tap13( Pel* pcInputPlaneData, Int iInputStride, Int iWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
430{ // DownSampling from JSVM Software (DownConvertStatic) ??
431
432  Int iOffset, iPosX, iPosY, k;
433  Int* piDataHorDown = new Int[(Int)(iWidth * iHeight / 2)];
434
435  // Downsampling filter.
436  Int aiFilterCoeff[16] = { 0, 2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2, 0, 64 };
437
438  // Normalization factors for filtered values.
439  Int iDivH = 1, iDivV = 1, iAddH = 0, iAddV = 0;
440
441  iDivV = (aiFilterCoeff[15]*aiFilterCoeff[15]); iAddV = iDivV / 2;
442
443  // Allocate and init single row of filtered samples.
444  Int* piDst = new Int[iWidth];
445
446  // 1) HORIZONTAL DOWNSAMPLING.
447
448  // Process all rows.
449  for( iPosY=0; iPosY<iHeight; iPosY++ )
450  {
451    // Set source (row) poInter.
452    Pel* pcSrc = &pcInputPlaneData[iInputStride*iPosY];
453
454    // Process all cols.
455    for( iPosX=0, k=0; iPosX<(iWidth/2); iPosX++, k+=2 )
456    {
457      // Adjust indices of border samples.
458      Int i00 = (k <       7) ? 0   : k    -7;
459      Int i01 = (k <       6) ? 0   : k    -6;
460      Int i02 = (k <       5) ? 0   : k    -5;
461      Int i03 = (k <       4) ? 0   : k    -4;
462      Int i04 = (k <       3) ? 0   : k    -3;
463      Int i05 = (k <       2) ? 0   : k    -2;
464      Int i06 = (k <       1) ? 0   : k    -1;
465      Int i07 = (k < iWidth  ) ? k   : iWidth-1;
466      Int i08 = (k < iWidth-1) ? k+1 : iWidth-1;
467      Int i09 = (k < iWidth-2) ? k+2 : iWidth-1;
468      Int i10 = (k < iWidth-3) ? k+3 : iWidth-1;
469      Int i11 = (k < iWidth-4) ? k+4 : iWidth-1;
470      Int i12 = (k < iWidth-5) ? k+5 : iWidth-1;
471      Int i13 = (k < iWidth-6) ? k+6 : iWidth-1;
472      Int i14 = (k < iWidth-7) ? k+7 : iWidth-1;
473
474      // Calculate filtered sample.
475      piDst[iPosX] =     aiFilterCoeff[ 0] * pcSrc[i00]
476      + aiFilterCoeff[ 1] * pcSrc[i01]
477      + aiFilterCoeff[ 2] * pcSrc[i02]
478      + aiFilterCoeff[ 3] * pcSrc[i03]
479      + aiFilterCoeff[ 4] * pcSrc[i04]
480      + aiFilterCoeff[ 5] * pcSrc[i05]
481      + aiFilterCoeff[ 6] * pcSrc[i06]
482      + aiFilterCoeff[ 7] * pcSrc[i07]
483      + aiFilterCoeff[ 8] * pcSrc[i08]
484      + aiFilterCoeff[ 9] * pcSrc[i09]
485      + aiFilterCoeff[10] * pcSrc[i10]
486      + aiFilterCoeff[11] * pcSrc[i11]
487      + aiFilterCoeff[12] * pcSrc[i12]
488      + aiFilterCoeff[13] * pcSrc[i13]
489      + aiFilterCoeff[14] * pcSrc[i14];
490    }
491
492    iOffset = iPosY * iWidth/2;
493    // Process all filtered samples.
494    for( iPosX=0; iPosX<(iWidth/2); iPosX++ )
495    {
496      // Scale and copy back to image buffer.
497      piDataHorDown[iOffset+iPosX] = (piDst[iPosX] + iAddH) / iDivH;
498    }
499  }
500
501  // Update w.
502  iWidth >>= 1;
503
504  // 2) VERTICAL DOWNSAMPLING.
505
506  // Process all cols.
507  for(  iPosX=0; iPosX<iWidth; iPosX++ )
508  {
509    // Set source (col) poInter.
510    Int* piSrc = &piDataHorDown[iPosX];
511
512    // Process all rows.
513    for(  iPosY=0, k=0; iPosY<(iHeight/2); iPosY++, k+=2 )
514    {
515      // Adjust indices of border samples.
516      Int i00 = ((k <       7) ? 0   : k    -7) * iWidth;
517      Int i01 = ((k <       6) ? 0   : k    -6) * iWidth;
518      Int i02 = ((k <       5) ? 0   : k    -5) * iWidth;
519      Int i03 = ((k <       4) ? 0   : k    -4) * iWidth;
520      Int i04 = ((k <       3) ? 0   : k    -3) * iWidth;
521      Int i05 = ((k <       2) ? 0   : k    -2) * iWidth;
522      Int i06 = ((k <       1) ? 0   : k    -1) * iWidth;
523      Int i07 = ((k < iHeight  ) ? k   : iHeight-1) * iWidth;
524      Int i08 = ((k < iHeight-1) ? k+1 : iHeight-1) * iWidth;
525      Int i09 = ((k < iHeight-2) ? k+2 : iHeight-1) * iWidth;
526      Int i10 = ((k < iHeight-3) ? k+3 : iHeight-1) * iWidth;
527      Int i11 = ((k < iHeight-4) ? k+4 : iHeight-1) * iWidth;
528      Int i12 = ((k < iHeight-5) ? k+5 : iHeight-1) * iWidth;
529      Int i13 = ((k < iHeight-6) ? k+6 : iHeight-1) * iWidth;
530      Int i14 = ((k < iHeight-7) ? k+7 : iHeight-1) * iWidth;
531
532      // Calculate filtered sample.
533      piDst[iPosY] =     aiFilterCoeff[ 0] * piSrc[i00]
534      + aiFilterCoeff[ 1] * piSrc[i01]
535      + aiFilterCoeff[ 2] * piSrc[i02]
536      + aiFilterCoeff[ 3] * piSrc[i03]
537      + aiFilterCoeff[ 4] * piSrc[i04]
538      + aiFilterCoeff[ 5] * piSrc[i05]
539      + aiFilterCoeff[ 6] * piSrc[i06]
540      + aiFilterCoeff[ 7] * piSrc[i07]
541      + aiFilterCoeff[ 8] * piSrc[i08]
542      + aiFilterCoeff[ 9] * piSrc[i09]
543      + aiFilterCoeff[10] * piSrc[i10]
544      + aiFilterCoeff[11] * piSrc[i11]
545      + aiFilterCoeff[12] * piSrc[i12]
546      + aiFilterCoeff[13] * piSrc[i13]
547      + aiFilterCoeff[14] * piSrc[i14];
548    }
549
550    // Process all filtered samples.
551    for( iPosY=0; iPosY<(iHeight/2); iPosY++ )
552    {
553      // Scale and copy back to image buffer.
554      pcOutputPlaneData[iOutputStride*iPosY+iPosX] = ClipBD( ( Pel) ( (piDst[iPosY] + iAddV) / iDivV), bitDepth );
555    }
556  }
557
558  delete [] piDataHorDown;
559  delete [] piDst;
560}
561
562template<UInt bitDepth>
563Void TRenFilter<bitDepth>::sampleDown2Tap13(PelImagePlane* pcInputPlane, PelImagePlane* pcOutputPlane)
564{ // DownSampling from JSVM Software (DownConvertStatic) ??
565  Int iWidth       = pcInputPlane->getWidth();
566  Int iHeight      = pcInputPlane->getHeight();
567
568  assert( pcOutputPlane->getWidth () == (iWidth  >> 1 ));
569  assert( pcOutputPlane->getHeight() == (iHeight >> 1 ));
570
571  Int iInputStride  = pcInputPlane->getStride();
572  Int iOutputStride = pcOutputPlane->getStride();
573
574  Pel* pcInputPlaneData = pcInputPlane ->getPlaneData();
575  Pel* pcOutputPlaneData = pcOutputPlane->getPlaneData();
576
577  sampleDown2Tap13( pcInputPlaneData, iInputStride, iWidth, iHeight, pcOutputPlaneData, iOutputStride );
578};
579
580template<UInt bitDepth>
581Void TRenFilter<bitDepth>::sampleVerDown2Tap13( PelImagePlane* pcInputPlane, PelImagePlane* pcOutputPlane, Int uiPad)
582{   
583  // DownSampling from JSVM Software (DownConvertStatic) ??
584  Int iWidth       = pcInputPlane->getWidth();
585  Int iHeight      = pcInputPlane->getHeight();
586
587  assert( pcOutputPlane->getWidth () ==  iWidth       );
588  assert( pcOutputPlane->getHeight() == (iHeight >> 1));
589  assert (pcInputPlane ->getPad()    >=            12 );
590  assert (pcOutputPlane->getPad()    >=         uiPad );
591
592  Int iInputStride  = pcInputPlane->getStride();
593  Int iOutputStride = pcOutputPlane->getStride();
594
595  Pel* pcInputPlaneData  = pcInputPlane ->getPlaneData();
596  Pel* pcOutputPlaneData = pcOutputPlane->getPlaneData();
597
598  Int iStr0  = 0;
599  Int iStr1  = iInputStride;
600  Int iStr2  = iStr1  + iInputStride;
601  Int iStr3  = iStr2  + iInputStride;
602  Int iStr4  = iStr3  + iInputStride;
603  Int iStr5  = iStr4  + iInputStride;
604  Int iStr6  = iStr5  + iInputStride;
605  Int iStr7  = iStr6  + iInputStride;
606  Int iStr8  = iStr7  + iInputStride;
607  Int iStr9  = iStr8  + iInputStride;
608  Int iStr10 = iStr9  + iInputStride;
609  Int iStr11 = iStr10 + iInputStride;
610  Int iStr12 = iStr11 + iInputStride;;
611
612
613  // Downsampling filter { 0, 2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2, 0, 64 };
614  for ( Int iYPos = 0; iYPos < (iHeight >> 1); iYPos++)
615  {
616    Pel* pcTmpIn = pcInputPlaneData - 12 * iInputStride - uiPad;
617    for ( Int iXPos = -uiPad; iXPos < iWidth + uiPad; iXPos++)
618    {
619      Int iTmp0, iTmp1, iTmp2, iTmp3, iTmp4, iTmp5;
620      iTmp0 = pcTmpIn[iStr0] + pcTmpIn[iStr12];
621      iTmp1 = pcTmpIn[iStr2] + pcTmpIn[iStr10];
622      iTmp2 = pcTmpIn[iStr3] + pcTmpIn[iStr9 ];
623      iTmp3 = pcTmpIn[iStr4] + pcTmpIn[iStr8 ];
624      iTmp4 = pcTmpIn[iStr5] + pcTmpIn[iStr7 ];
625      iTmp5 = pcTmpIn[iStr6];
626
627      Int iSum = iTmp4 + iTmp3 - iTmp2 + ((iTmp0 + iTmp4 + iTmp5 - iTmp2) << 1) + ( ( iTmp3 - iTmp1)  << 2) + (  iTmp5 << 3 ) + (( iTmp4 + iTmp5 ) << 4);
628      pcOutputPlaneData[ iXPos ] = (Pel) ClipBD((iSum + 32) >> 6, bitDepth);
629      pcTmpIn++;
630    }
631    pcOutputPlaneData += iOutputStride;
632    pcInputPlaneData  += (iInputStride << 1);
633  }
634};
635
636template<UInt bitDepth>
637Void TRenFilter<bitDepth>::sampleHorDown2Tap13( PelImagePlane* pcInputPlane, PelImagePlane* pcOutputPlane, Int uiPad )
638{ 
639    // DownSampling from JSVM Software (DownConvertStatic) ??
640  Int iWidth       = pcInputPlane->getWidth();
641  Int iHeight      = pcInputPlane->getHeight();
642
643  assert( pcOutputPlane->getWidth () == (iWidth  >> 1));
644  assert( pcOutputPlane->getHeight() ==  iHeight      );
645  assert (pcInputPlane ->getPad()    >=            12 );
646  assert (pcOutputPlane->getPad()    >=         uiPad );
647
648  Int iInputStride  = pcInputPlane ->getStride();
649  Int iOutputStride = pcOutputPlane->getStride();
650
651  Pel* pcInputPlaneData  = pcInputPlane ->getPlaneData()- uiPad * iInputStride ;
652  Pel* pcOutputPlaneData = pcOutputPlane->getPlaneData()- uiPad * iOutputStride;
653
654  // Downsampling filter { 0, 2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2, 0, 64 };
655  for ( Int iYPos = 0; iYPos < iHeight + 2*uiPad; iYPos++)
656  {
657    Pel* pcTmpIn = pcInputPlaneData - 12;
658    for ( Int iXPos = 0; iXPos < ( iWidth >> 1); iXPos++)
659    {
660      Int iTmp0, iTmp1, iTmp2, iTmp3, iTmp4, iTmp5;
661      iTmp0 = pcTmpIn[0]+ pcTmpIn[12];
662      iTmp1 = pcTmpIn[2]+ pcTmpIn[10];
663      iTmp2 = pcTmpIn[3]+ pcTmpIn[9 ];
664      iTmp3 = pcTmpIn[4]+ pcTmpIn[8 ];
665      iTmp4 = pcTmpIn[5]+ pcTmpIn[7 ];
666      iTmp5 = pcTmpIn[6];
667
668      Int iSum = iTmp4 + iTmp3 - iTmp2 + ((iTmp0 + iTmp4 + iTmp5 - iTmp2) << 1) + ( ( iTmp3 - iTmp1)  << 2) + (  iTmp5 << 3 ) + (( iTmp4 + iTmp5 ) << 4);
669      pcOutputPlaneData[ iXPos ] = (Pel) ClipBD((iSum + 32) >> 6, bitDepth);
670      pcTmpIn += 2;
671    }
672    pcOutputPlaneData += iOutputStride;
673    pcInputPlaneData  += iInputStride ;
674  }
675};
676
677template<UInt bitDepth>
678inline Pel TRenFilter<bitDepth>::xMedian3(Pel* pcData)
679{
680  Bool bGT01 = pcData[0] >  pcData[1];
681  Bool bGT12 = pcData[1] >  pcData[2];
682  Bool bGT20 = pcData[2] >  pcData[0];
683
684  return ( (bGT01 && bGT20) || (!bGT01 && !bGT20) ) ?  pcData[0] : ( ( (bGT12 && bGT01) || (!bGT12 && !bGT01) ) ?  pcData[1] : pcData[2]) ;
685}
686
687template<UInt bitDepth>
688Void TRenFilter<bitDepth>::lineMedian3( PelImage* pcImage )
689{
690
691  PelImage* pcTemp = pcImage->create();
692
693  for (UInt uiCurPlane = 0; uiCurPlane < pcImage->getNumberOfPlanes(); uiCurPlane++)
694  {
695    PelImagePlane* pcImPlane   = pcImage->getPlane(uiCurPlane);
696    PelImagePlane* pcTempPlane = pcTemp ->getPlane(uiCurPlane);
697
698    UInt uiWidth  = pcImPlane->getWidth();
699    UInt uiHeight = pcImPlane->getHeight();
700
701    Pel* pcImData   = pcImPlane  ->getPlaneData();
702    Pel* pcTempData = pcTempPlane->getPlaneData();
703
704    UInt uiImDataStride   = pcImPlane  ->getStride();
705    UInt uiTempDataStride = pcTempPlane->getStride();
706
707    for(UInt uiPosY = 0; uiPosY < uiHeight; uiPosY++)
708    {
709      for(UInt uiPosX = 0; uiPosX < uiWidth; uiPosX++)
710      {
711        if ( (uiPosX >= 1) && (uiPosX < (uiWidth - 2)) )
712        {
713          pcTempData[uiPosX] = xMedian3(pcImData + uiPosX - 1);
714        }
715        else
716        {
717          pcTempData[uiPosX] = pcImData[uiPosX];
718        }
719      }
720      pcTempData += uiTempDataStride;
721      pcImData   += uiImDataStride;
722    }
723  }
724
725  pcImage->assign(pcTemp);
726  delete pcTemp;
727}
728
729template<UInt bitDepth>
730Void TRenFilter<bitDepth>::convRect( PelImage* pcImage, UInt uiSize )
731{
732  DoubleImage cKernel(uiSize, uiSize,1,0);
733  cKernel.getPlane(0)->assign( 1 / ( Double( uiSize )  * Double( uiSize) ));
734  conv(pcImage, &cKernel);
735}
736
737template<UInt bitDepth>
738Void TRenFilter<bitDepth>::binominal( PelImage* pcInputImage, PelImage* pcOutputImage, UInt uiSize )
739{
740  assert( pcInputImage->getNumberOfFullPlanes()   == pcOutputImage->getNumberOfFullPlanes  () );
741  assert( pcInputImage->getNumberOfQuaterPlanes() == pcOutputImage->getNumberOfQuaterPlanes() );
742
743  UInt uiPlane;
744  for (uiPlane = 0; uiPlane < pcInputImage->getNumberOfPlanes(); uiPlane ++)
745  {
746    binominal( pcInputImage->getPlane(uiPlane), pcOutputImage->getPlane(uiPlane), uiSize );
747  }
748
749  for (  ; uiPlane < pcInputImage->getNumberOfPlanes(); uiPlane ++)
750  {
751    binominal( pcInputImage->getPlane(uiPlane), pcOutputImage->getPlane(uiPlane), uiSize >> 1 );
752 }
753}
754
755template<UInt bitDepth>
756Void TRenFilter<bitDepth>::binominal( PelImagePlane* pcInputPlane, PelImagePlane* pcOutputPlane, UInt uiSize )
757{
758  Int iWidth  = pcInputPlane ->getWidth ();
759  Int iHeight = pcInputPlane ->getHeight();
760
761  assert( pcOutputPlane->getWidth () == iWidth  );
762  assert( pcOutputPlane->getHeight() == iHeight );
763  assert( pcInputPlane ->getPad   () >= uiSize );
764  assert( pcOutputPlane->getPad   () >= uiSize );
765
766  if (uiSize == 0)
767  {
768    pcOutputPlane->assign( pcInputPlane );
769    return;
770  };
771
772  Int iInputStride  = pcInputPlane ->getStride();
773  Int iOutputStride = pcOutputPlane->getStride();
774  Int iTempStride   = iWidth + (uiSize << 1);
775
776
777  Pel* pcCurInputData  = pcInputPlane ->getPlaneData() - uiSize;
778  Pel* pcTempData      = new Pel[iTempStride * iHeight];
779  Pel* pcCurTempData   = pcTempData;
780
781  Pel (*fpFilter) ( Pel*, Int ) = NULL;
782
783  switch( uiSize )
784  {
785  case 1:
786    fpFilter = &TRenFilter<bitDepth>::xFiltBinom3;
787    break;
788  case 2:
789    fpFilter = &TRenFilter<bitDepth>::xFiltBinom5;
790    break;
791  case 3:
792    fpFilter = &TRenFilter<bitDepth>::xFiltBinom7;
793    break;
794  case 4:
795    fpFilter = &TRenFilter<bitDepth>::xFiltBinom9;
796    break;
797  default:
798      AOT(true);
799  }
800
801  for (Int iPosY = 0; iPosY < iHeight; iPosY++ )
802  {
803    for (Int iPosX = 0; iPosX < iWidth + (uiSize << 1); iPosX++)
804    {
805      pcCurTempData[iPosX] = (*fpFilter)(pcCurInputData + iPosX, iInputStride );
806    }
807    pcCurTempData   += iTempStride;
808    pcCurInputData  += iInputStride;
809  }
810
811  pcCurTempData   = pcTempData + uiSize;
812  Pel* pcCurOutputData = pcOutputPlane->getPlaneData();
813
814  for (Int iPosY = 0; iPosY < iHeight; iPosY++ )
815  {
816    for (Int iPosX = 0; iPosX < iWidth; iPosX++)
817    {
818      pcCurOutputData[iPosX] = (*fpFilter)(pcCurTempData + iPosX, 1);
819    }
820    pcCurTempData    += iTempStride;
821    pcCurOutputData  += iOutputStride;
822  }
823
824  delete[] pcTempData;
825}
826
827template<UInt bitDepth>
828Pel TRenFilter<bitDepth>::xFiltBinom3( Pel* pcInputData, Int iStride )
829{
830  Int iSum = pcInputData[-1 * iStride ] + pcInputData[ 0 ] +  (pcInputData[iStride ] << 1 );
831  return ClipBD( (iSum +  2) >>  2 , bitDepth);
832}
833
834template<UInt bitDepth>
835Pel TRenFilter<bitDepth>::xFiltBinom5( Pel* pcInputData, Int iStride )
836{
837    // { 1,4,6,4,1 }
838  Int iStride0  = 0;
839  Int iStrideM1 = iStride0  - iStride;
840  Int iStrideM2 = iStrideM1 - iStride;
841  Int iStrideP1 = iStride0  + iStride;
842  Int iStrideP2 = iStrideP1 + iStride;
843
844  Int iTmp0 = pcInputData[iStrideM2] + pcInputData[iStrideP2];
845  Int iTmp1 = pcInputData[iStrideM1] + pcInputData[iStrideP1];
846  Int iTmp2 = pcInputData[iStride0 ];
847
848  Int iSum = iTmp0 +  (iTmp2 << 1) + ((iTmp1 + iTmp2) << 2);
849  return ClipBD( (iSum +  8) >>  4 , bitDepth);
850}
851
852template<UInt bitDepth>
853Pel TRenFilter<bitDepth>::xFiltBinom7( Pel* pcInputData, Int iStride )
854{
855    // { 1,6,15,20,15,6,1 }
856  Int iStride0  = 0;
857  Int iStrideM1 = iStride0  - iStride;
858  Int iStrideM2 = iStrideM1 - iStride;
859  Int iStrideM3 = iStrideM1 - iStride;
860  Int iStrideP1 = iStride0  + iStride;
861  Int iStrideP2 = iStrideP1 + iStride;
862  Int iStrideP3 = iStrideP1 + iStride;
863
864  Int iTmp0 = pcInputData[iStrideM3] + pcInputData[iStrideP3];
865  Int iTmp1 = pcInputData[iStrideM2] + pcInputData[iStrideP2];
866  Int iTmp2 = pcInputData[iStrideM1] + pcInputData[iStrideP1];
867  Int iTmp3 = pcInputData[iStride0];
868
869  Int iSum = iTmp0 - iTmp2 + ( iTmp1  << 1) + ( (iTmp1 + iTmp3) << 2) + ((iTmp2 + iTmp3) << 4);
870
871  return ClipBD( (iSum +  32) >>  6 , bitDepth);
872}
873
874template<UInt bitDepth>
875Pel TRenFilter<bitDepth>::xFiltBinom9( Pel* pcInputData, Int iStride )
876{ 
877  // {  1     8    28    56    70    56    28     8     1 }
878  Int iStride0  = 0;
879  Int iStrideM1 = iStride0  - iStride;
880  Int iStrideM2 = iStrideM1 - iStride;
881  Int iStrideM3 = iStrideM1 - iStride;
882  Int iStrideM4 = iStrideM1 - iStride;
883  Int iStrideP1 = iStride0  + iStride;
884  Int iStrideP2 = iStrideP1 + iStride;
885  Int iStrideP3 = iStrideP1 + iStride;
886  Int iStrideP4 = iStrideP1 + iStride;
887
888  Int iTmp0 = pcInputData[iStrideM4] + pcInputData[iStrideP4];
889  Int iTmp1 = pcInputData[iStrideM3] + pcInputData[iStrideP3];
890  Int iTmp2 = pcInputData[iStrideM2] + pcInputData[iStrideP2];
891  Int iTmp3 = pcInputData[iStrideM1] + pcInputData[iStrideP1];
892  Int iTmp4 = pcInputData[iStride0];
893
894  Int iSum = iTmp0 + ((iTmp4 ) << 1) + ( ( iTmp4 - iTmp2 ) << 2) +  ( (iTmp1 - iTmp3) << 3 ) +  ((iTmp2 ) << 5) + ((iTmp3+ iTmp4 ) << 6);
895
896  return ClipBD( (iSum +  128) >>  8 , bitDepth);
897}
898
899template<UInt bitDepth>
900Pel TRenFilter<bitDepth>::interpCHSpline(Double dX, Double dS0, Double dS1, Int iQ0, Int iQ1, Int iQ2, Int iQ3)
901{
902  Double dSq = (dX - dS0) / (dS1 - dS0);
903
904  Double adP[4];
905  Double dSqP2 = dSq * dSq;
906  Double dSqP3 = dSqP2 * dSq;
907
908  adP[0] = 1 - 3 * dSqP2 + 2 * dSqP3;
909  adP[1] = dSq - 2 * dSqP2 + dSqP3;
910  adP[2] = 3 * dSqP2 - 2 * dSqP3;
911  adP[3] = -dSqP2 + dSqP3;
912
913  Double dQ  = adP[0] * iQ0 + adP[1] * iQ1 + adP[2] * iQ2 + adP[3] * iQ3 ;
914
915  Pel cQ = (Pel) ( dQ + 0.5);
916
917  cQ = ( cQ < 0   ? 0   : cQ );
918  cQ = ( cQ > 255 ? 255 : cQ );
919
920  return cQ;
921
922}
923
924template<UInt bitDepth>
925Void TRenFilter<bitDepth>::diffHorSym(PelImage* pcInputImage, IntImage* pcOutputImage)
926{
927  for (UInt uiCurPlane = 0; uiCurPlane < pcInputImage->getNumberOfPlanes(); uiCurPlane++)
928  {
929    diffHorSym( pcInputImage->getPlane(uiCurPlane), pcOutputImage->getPlane(uiCurPlane));
930  };
931}
932
933template<UInt bitDepth>
934Void TRenFilter<bitDepth>::diffHorSym(PelImagePlane* pcInputPlane, IntImagePlane* pcOutputPlane)
935{
936  UInt uiInputStride = pcInputPlane ->getStride();
937  UInt uiOutputStride = pcOutputPlane->getStride();
938  UInt uiWidth        = pcInputPlane ->getWidth();
939  UInt uiHeight       = pcInputPlane ->getHeight();
940
941  Pel*   pcInputData   = pcInputPlane ->getPlaneData();
942  Int*   piOutputData  = pcOutputPlane->getPlaneData();
943
944  for (UInt uiPosY = 0; uiPosY < uiHeight; uiPosY++)
945  {
946    for (UInt uiPosX = 1; uiPosX < uiWidth-1; uiPosX++)
947    {
948      piOutputData[uiPosX] = ((Int) pcInputData[uiPosX+1] - (Int) pcInputData[uiPosX-1]);
949      piOutputData[uiPosX] /= 2;
950    };
951
952    piOutputData[0] = piOutputData[1];
953    piOutputData[uiWidth-1] = piOutputData[uiWidth-2];
954    pcInputData += uiInputStride;
955    piOutputData  += uiOutputStride;
956
957  };
958}
959
960template<UInt bitDepth>
961Void TRenFilter<bitDepth>::laplace( DoubleImage* pcInputImage, DoubleImage* pcOutputImage )
962{
963  for (UInt uiCurPlane = 0; uiCurPlane < pcInputImage->getNumberOfPlanes(); uiCurPlane++)
964  {
965    DoubleImagePlane* pcInputPlane  = pcInputImage  ->getPlane(uiCurPlane);
966    DoubleImagePlane* pcOutputPlane = pcOutputImage ->getPlane(uiCurPlane);
967
968    UInt uiWidth  = pcInputPlane->getWidth();
969    UInt uiHeight = pcInputPlane->getHeight();
970
971    Double* pdInputData  = pcInputPlane  ->getPlaneData();
972    Double* pdOutputData = pcOutputPlane ->getPlaneData();
973
974    for (UInt uiPosY = 1; uiPosY < uiHeight-1; uiPosY++)
975    {
976      UInt uOff = uiPosY * uiWidth;
977      for(UInt uiPosX = 1; uiPosX < uiWidth-1; uiPosX++)
978      {
979        UInt uOff2 = uOff + uiPosX;
980        pdOutputData[uOff2] =     4 * pdInputData[uOff2]
981        -   pdInputData[uOff2 - 1]
982        -   pdInputData[uOff2 + 1]
983        -   pdInputData[uOff2 - uiWidth]
984        -   pdInputData[uOff2 + uiWidth];
985      }
986    };
987
988    // left and right margin
989    for (UInt uiPosY = 1; uiPosY < uiHeight-1; uiPosY++)
990    {
991      UInt uOff  = uiPosY * uiWidth;
992      pdOutputData[uOff] = 3 * pdInputData[uOff]
993      -   pdInputData[uOff + 1]
994      -   pdInputData[uOff - uiWidth]
995      -   pdInputData[uOff + uiWidth];
996
997
998      uOff = (uiPosY + 1) * uiWidth - 1;
999      pdOutputData[uOff] = 3 * pdInputData[uOff]
1000      -   pdInputData[uOff - 1]
1001      -   pdInputData[uOff - uiWidth]
1002      -   pdInputData[uOff + uiWidth];
1003    }
1004
1005    for (UInt uiPosX = 1; uiPosX < uiWidth-1; uiPosX++)
1006    {
1007      UInt uOff  = uiPosX;
1008      pdOutputData[uOff] = 3 * pdInputData[uOff]
1009      -   pdInputData[uOff + 1]
1010      -   pdInputData[uOff - 1]
1011      -   pdInputData[uOff + uiWidth];
1012
1013
1014      uOff = (uiHeight - 1) * uiWidth + uiPosX;
1015      pdOutputData[uOff] = 3 * pdInputData[uOff]
1016      -   pdInputData[uOff + 1]
1017      -   pdInputData[uOff - 1]
1018      -   pdInputData[uOff - uiWidth];
1019    }
1020
1021    UInt uOff = 0;
1022    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff+1] - pdInputData[ uOff + uiWidth];
1023    uOff = uiWidth - 1;
1024    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff-1] - pdInputData[ uOff + uiWidth ];
1025    uOff = (uiHeight - 1) * uiWidth;
1026    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff+1] - pdInputData[ uOff - uiWidth];
1027    uOff = uiHeight * uiWidth - 1;
1028    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff-1] - pdInputData[ uOff - uiWidth];
1029
1030  }
1031}
1032
1033template<UInt bitDepth>
1034Void TRenFilter<bitDepth>::conv( PelImage* pcImage, DoubleImage* pcKernel )
1035{
1036  PelImage* pcTemp = pcImage->create();
1037
1038  DoubleImagePlane* pcKernelPlane = 0;
1039  for (UInt uiCurPlane = 0; uiCurPlane < pcImage->getNumberOfPlanes(); uiCurPlane++) {
1040
1041    PelImagePlane* pcPlane     = pcImage->getPlane(uiCurPlane);
1042    PelImagePlane* pcTempPlane = pcTemp ->getPlane(uiCurPlane);
1043
1044    if ( uiCurPlane <= pcKernel->getNumberOfPlanes() )
1045    {
1046      pcKernelPlane = pcKernel->getPlane(uiCurPlane);
1047    };
1048
1049    UInt uiWidth  = pcPlane->getWidth();
1050    UInt uiHeight = pcPlane->getHeight();
1051
1052    UInt uiKernelWidth  = pcKernelPlane->getWidth();
1053    UInt uiKernelHeight = pcKernelPlane->getHeight();
1054
1055    Pel*    pcData         = pcPlane      ->getPlaneData();
1056    Pel*    pcTempData     = pcTempPlane  ->getPlaneData();
1057    Double* pdKernelData   = pcKernelPlane->getPlaneData();
1058
1059    UInt uiDataStride       = pcPlane      ->getStride();
1060    UInt uiTempDataStride   = pcTempPlane  ->getStride();
1061    UInt uiKernelDataStride = pcKernelPlane->getStride();
1062
1063    for(UInt uiPosY = 0; uiPosY < uiHeight; uiPosY++)
1064    {
1065      UInt uOff = uiPosY * uiTempDataStride;
1066      for(UInt uiPosX = 0; uiPosX < uiWidth; uiPosX++)
1067      {
1068        Double dSum = 0;
1069        for(UInt uKY = 0; uKY < uiKernelHeight; uKY++)
1070        {
1071          UInt uKOff = uKY * uiKernelDataStride;
1072
1073          Int iYSrc = uiPosY - (uiKernelHeight/2) + uKY;
1074
1075          if (iYSrc < 0)
1076            iYSrc = -iYSrc;
1077
1078          if (iYSrc >= (Int)uiHeight)
1079            iYSrc = 2*uiHeight - iYSrc - 1;
1080
1081          UInt uSrcOff = iYSrc * uiDataStride;
1082
1083          for(UInt uKX = 0; uKX < uiKernelWidth; uKX++)
1084          {
1085            Int iXSrc = uiPosX - (uiKernelWidth/2) + uKX;
1086
1087            if (iXSrc < 0)
1088              iXSrc = -iXSrc;
1089
1090            if (iXSrc >= (Int)uiWidth)
1091              iXSrc = 2*uiWidth - iXSrc - 1;
1092
1093            dSum += pcData[uSrcOff + iXSrc] * pdKernelData[uKOff + uKX];
1094          }
1095        }
1096        pcTempData[uOff + uiPosX] = (Pel) (dSum + ( ( dSum < 0 ) ? -0.5 : 0.5)  );
1097      }
1098    }
1099  }
1100
1101  pcImage->assign(pcTemp);
1102  delete pcTemp;
1103}
1104
1105
1106// Horizontal Up sampling luma
1107template<UInt bitDepth>
1108Void TRenFilter<bitDepth>::sampleHorUp( Int iLog2HorSampFac, Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1109{
1110  TRenInterpFilter<bitDepth> cFilter;
1111  switch ( iLog2HorSampFac )
1112  {
1113  case 0:
1114    xDistributeArray              ( pcInputPlaneData, iInputStride, 1 , 1, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride, 1, 1 );
1115    break;
1116  case 1:
1117    xDistributeArray              ( pcInputPlaneData, iInputStride, 1 , 1, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride, 2, 1 );
1118    cFilter.xCTI_FilterHalfHor    ( pcInputPlaneData, iInputStride,     1, iInputWidth, iHeight, iOutputStride, 2, ++pcOutputPlaneData );
1119    break;
1120  case 2:
1121    xDistributeArray              ( pcInputPlaneData, iInputStride, 1 , 1, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride, 4, 1 );
1122    cFilter.xCTI_FilterQuarter0Hor( pcInputPlaneData, iInputStride, 1, iInputWidth, iHeight, iOutputStride, 4, ++pcOutputPlaneData );
1123    cFilter.xCTI_FilterHalfHor    ( pcInputPlaneData, iInputStride, 1, iInputWidth, iHeight, iOutputStride, 4, ++pcOutputPlaneData );
1124    cFilter.xCTI_FilterQuarter1Hor( pcInputPlaneData, iInputStride, 1, iInputWidth, iHeight, iOutputStride, 4, ++pcOutputPlaneData );
1125    break;
1126  }
1127}
1128
1129// horizontal up sampling chroma
1130template<UInt bitDepth>
1131Void TRenFilter<bitDepth>::sampleCHorUp(Int iLog2HorSampFac, Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1132{
1133  switch ( iLog2HorSampFac )
1134  {
1135  case 0:
1136    xDistributeArray( pcInputPlaneData,   iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                  , iOutputStride, 1 , 1 );
1137    break;
1138  case 1:
1139    xDistributeArray( pcInputPlaneData,   iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                  , iOutputStride, 2 , 1 );
1140    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +1, iOutputStride, 2 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1141    break;
1142  case 2:
1143    xDistributeArray( pcInputPlaneData,   iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                  , iOutputStride, 4 , 1 );
1144    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +1, iOutputStride, 4 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_QUA0 );
1145    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +2, iOutputStride, 4 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1146    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +3, iOutputStride, 4 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_QUA1 );
1147    break;
1148  }
1149}
1150
1151template<UInt bitDepth>
1152Void TRenFilter<bitDepth>::sampleCUpHorUp( Int iLog2HorSampFac, Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1153{
1154
1155  switch ( iLog2HorSampFac )
1156  {
1157  case 0:
1158    xDistributeArray( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData                -2, iOutputStride, 2,  2 );
1159    xInterpVerChroma( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData+1*iOutputStride-2, iOutputStride, 2 , 2, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1160    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 2, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData+1                , iOutputStride, 2 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1161    break;
1162  case 1:
1163    xDistributeArray( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData                -4, iOutputStride, 4 , 2 );
1164    xInterpVerChroma( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData+1*iOutputStride-4, iOutputStride, 4 , 2, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1165    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 4, 1, iInputWidth, iHeight*2 , pcOutputPlaneData                +1, iOutputStride, 4 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_QUA0 );
1166    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 4, 1, iInputWidth, iHeight*2 , pcOutputPlaneData                +2, iOutputStride, 4 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1167    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 4, 1, iInputWidth, iHeight*2 , pcOutputPlaneData                +3, iOutputStride, 4 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_QUA1 );
1168    break;
1169  case 2:
1170    xDistributeArray( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData                -8, iOutputStride, 8 , 2 );
1171    xInterpVerChroma( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData+1*iOutputStride-8, iOutputStride, 8 , 2, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1172    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +1, iOutputStride, 8 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_OCT0 );
1173    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +2, iOutputStride, 8 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_QUA0 );
1174    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +3, iOutputStride, 8 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_OCT1 );
1175    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +4, iOutputStride, 8 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VPS04_C_HAL );
1176    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +5, iOutputStride, 8 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_OCT2 );
1177    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +6, iOutputStride, 8 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_QUA1 );
1178    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +7, iOutputStride, 8 , 1, &TRenInterpFilter<REN_BIT_DEPTH>::xCTI_Filter_VP04_C_OCT3 );
1179    break;
1180  }
1181}
1182
1183// Down Sampling
1184// Down sample luma
1185template<UInt bitDepth>
1186Void TRenFilter<bitDepth>::sampleHorDown(Int iLog2HorSampFac,  Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1187{
1188  switch ( iLog2HorSampFac )
1189  {
1190  case 0:
1191    xDistributeArray( pcInputPlaneData, iInputStride, 1, 1, iInputWidth,iHeight, pcOutputPlaneData, iOutputStride, 1 , 1 );
1192    break;
1193  case 1:
1194    xSampleDownHor2(pcInputPlaneData, iInputStride, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride);
1195    break;
1196  case 2:
1197    xSampleDownHor4(pcInputPlaneData, iInputStride, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride);
1198    break;
1199  }
1200}
1201
1202template<UInt bitDepth>
1203Void TRenFilter<bitDepth>::sampleCHorDown(Int iLog2HorSampFac,  Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1204{
1205  //GT: currently the same as for luma
1206  sampleHorDown( iLog2HorSampFac, pcInputPlaneData, iInputStride, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride);
1207}
1208
1209
1210
1211// Up sampling chroma
1212template<UInt bitDepth>
1213Void TRenFilter<bitDepth>::sampleCDownHorDown( Int iLog2HorSampFac,  Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iInputHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1214{
1215  // create buffer
1216  Int iBufferStride   = iInputWidth >> (iLog2HorSampFac + 1);
1217  Pel* piBuffer       = new Pel[ iBufferStride * (iInputHeight+2) ];
1218
1219  switch ( iLog2HorSampFac )
1220  {
1221  case 0:
1222    xSampleDownHor2( pcInputPlaneData - iInputStride,  iInputStride, iInputWidth  , iInputHeight+1, piBuffer,  iBufferStride);
1223    break;
1224  case 1:
1225    xSampleDownHor4( pcInputPlaneData - iInputStride , iInputStride,  iInputWidth , iInputHeight+1, piBuffer, iBufferStride);
1226    break;
1227  case 2:
1228    xSampleDownHor8( pcInputPlaneData - iInputStride , iInputStride,  iInputWidth  , iInputHeight+1, piBuffer, iBufferStride);
1229    break;
1230  }
1231  xSampleDownVer2( piBuffer + iBufferStride       , iBufferStride, iBufferStride, iInputHeight,   pcOutputPlaneData, iOutputStride);
1232  delete[] piBuffer;
1233}
1234
1235template<UInt bitDepth>
1236Void TRenFilter<bitDepth>::xDistributeArray(const Pel* pcSrc, Int iSrcStride, Int iSrcStepX, Int iSrcStepY, Int iWidth, Int iHeight, Pel* pcDst, Int iDstStride, Int iDstStepX, Int iDstStepY)
1237{
1238  iDstStride *= iDstStepY;
1239  iSrcStride *= iSrcStepY;
1240  for (Int iYPos = 0; iYPos < iHeight; iYPos++ )
1241  {
1242    Pel* pcCurDst = pcDst;
1243    const Pel* pcCurSrc  = pcSrc;
1244    for (Int iXPos = 0; iXPos < iWidth; iXPos ++)
1245    {
1246      *pcCurDst = *pcCurSrc;
1247
1248      pcCurDst += iDstStepX;
1249      pcCurSrc += iSrcStepX;
1250    }
1251    pcDst  += iDstStride;
1252    pcSrc  += iSrcStride;
1253  }
1254}
1255
1256template<UInt bitDepth>
1257Void TRenFilter<bitDepth>::xInterpHorChroma( Pel* piSrc, Int iSrcStride, Int iSrcStepX, Int iSrcStepY, Int iWidth, Int iHeight, Pel* piDst, Int iDstStride, Int iDstStepX, Int iDstStepY, FpChromaIntFilt fpFilter )
1258{
1259  Int   iSum;
1260  Pel*  piSrcTmp;
1261
1262  TRenInterpFilter<REN_BIT_DEPTH> cFilter;
1263  for ( Int y = iHeight; y != 0; y-- )
1264  {
1265    piSrcTmp = piSrc - iSrcStepX;
1266    for ( Int x = 0; x < iWidth; x++ )
1267    {
1268      iSum      = (cFilter.*fpFilter)( piSrcTmp,  iSrcStepX );
1269      piDst[x * iDstStepX ] =  ClipBD ((iSum +  32) >>  6 , bitDepth);
1270      piSrcTmp+= iSrcStepX;
1271    }
1272    piSrc += iSrcStride * iSrcStepY;
1273    piDst += iDstStride * iDstStepY;
1274  }
1275}
1276
1277template<UInt bitDepth>
1278Void TRenFilter<bitDepth>::xInterpVerChroma( Pel* piSrc, Int iSrcStride, Int iSrcStepX, Int iSrcStepY, Int iWidth, Int iHeight, Pel* piDst, Int iDstStride, Int iDstStepX, Int iDstStepY, FpChromaIntFilt fpFilter )
1279{ 
1280  Int   iSum;
1281  Pel*  piSrcTmp;
1282
1283  TRenInterpFilter<bitDepth> cFilter;
1284  for ( Int y = iHeight; y != 0; y-- )
1285  {
1286    piSrcTmp = piSrc - iSrcStepY * iSrcStride;
1287    for ( Int x = 0; x < iWidth; x++ )
1288    {
1289      iSum      = (cFilter.*fpFilter)( piSrcTmp,  iSrcStepY * iSrcStride );
1290      piDst[x * iDstStepX ]  =  ClipBD ((iSum +  32) >>  6, bitDepth );
1291      piSrcTmp += iSrcStepX;
1292    }
1293    piSrc += iSrcStride * iSrcStepY;
1294    piDst += iDstStride * iDstStepY;
1295  }
1296}
1297
1298template<UInt bitDepth>
1299Void TRenFilter<bitDepth>::xSampleDownHor2( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iHeight, Pel* piDst, Int iDstStride  )
1300{ 
1301
1302  Int   iSum;
1303  Pel*  piSrcTmp;
1304
1305
1306  for ( Int y = iHeight; y != 0; y-- )
1307  {
1308    piSrcTmp = piSrc - 1 ;
1309    for ( Int x = 0; x < (iSrcWidth >> 1); x++ )
1310    {
1311      // { 1,2,1 }
1312      iSum = piSrcTmp[0] + piSrcTmp[2] +  (piSrcTmp[1] << 1);
1313      piDst[x] = ClipBD( (iSum +  2) >>  2 , bitDepth);
1314      piSrcTmp += 2;
1315    }
1316    piSrc += iSrcStride;
1317    piDst += iDstStride;
1318  }
1319};
1320
1321template<UInt bitDepth>
1322Void TRenFilter<bitDepth>::xSampleDownVer2( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iSrcHeight, Pel* piDst, Int iDstStride  )
1323{
1324  Int   iSum;
1325  Pel*  piSrcTmp;
1326
1327  for ( Int y = (iSrcHeight >> 1); y != 0; y-- )
1328  {
1329    piSrcTmp = piSrc -1 * iSrcStride;
1330    for ( Int x = 0; x < iSrcWidth; x++ )
1331    {
1332      // { 1,2,1 }
1333      iSum = piSrcTmp[0] + piSrcTmp[ iSrcStride << 1] +  (piSrcTmp[ iSrcStride ] << 1);
1334      piDst[x] = ClipBD( (iSum +  2) >>  2, bitDepth );
1335      piSrcTmp += 1;
1336    }
1337    piSrc += (iSrcStride << 1);
1338    piDst += iDstStride;
1339  }
1340};
1341
1342template<UInt bitDepth>
1343Void TRenFilter<bitDepth>::xSampleDownHor4( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iHeight, Pel* piDst, Int iDstStride  )
1344{ 
1345
1346  Int   iSum;
1347  Pel*  piSrcTmp;
1348
1349  Int iTmp0, iTmp1, iTmp2;
1350
1351  for ( Int y = iHeight; y != 0; y-- )
1352  {
1353    piSrcTmp = piSrc -2 ;
1354    for ( Int x = 0; x < (iSrcWidth >> 2); x++ )
1355    {
1356      // { 1,4,6,4,1 }
1357      iTmp0 = piSrcTmp[0] + piSrcTmp[4];
1358      iTmp1 = piSrcTmp[1] + piSrcTmp[3];
1359      iTmp2 = piSrcTmp[2];
1360
1361      iSum = iTmp0 +  (iTmp2 << 1) + ((iTmp1 + iTmp2) << 2);
1362      piDst[x] = ClipBD( (iSum +  8) >>  4, bitDepth );
1363      piSrcTmp += 4;
1364    }
1365    piSrc += iSrcStride;
1366    piDst += iDstStride;
1367  }
1368};
1369
1370template<UInt bitDepth>
1371Void TRenFilter<bitDepth>::xSampleDownHor8( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iHeight, Pel* piDst, Int iDstStride  )
1372{
1373  Int   iSum;
1374  Pel*  piSrcTmp;
1375
1376  Int iTmp0, iTmp1, iTmp2, iTmp3;
1377
1378  for ( Int y = iHeight; y != 0; y-- )
1379  {
1380    piSrcTmp = piSrc -3;
1381    for ( Int x = 0; x < (iSrcWidth >> 3); x++ )
1382    {
1383      // { 1,6,15,20,15,6,1 }
1384      iTmp0 = piSrcTmp[0] + piSrcTmp[6];
1385      iTmp1 = piSrcTmp[1] + piSrcTmp[5];
1386      iTmp2 = piSrcTmp[2] + piSrcTmp[4];
1387      iTmp3 = piSrcTmp[3];
1388
1389      iSum = iTmp0 - iTmp2 + ( iTmp1  << 1) + ( (iTmp1 + iTmp3) << 2) + ((iTmp2 + iTmp3) << 4);
1390      piDst[x] = ClipBD( (iSum +  32) >>  6 , bitDepth);
1391      piSrcTmp += 8;
1392    }
1393    piSrc += iSrcStride;
1394    piDst += iDstStride;
1395  }
1396};
1397
1398template<UInt bitDepth>
1399Void TRenFilter<bitDepth>::xDilate( Pel* piSrc, Int iSrcStride, Int iWidth, Int iHeight, Pel* piDst, Int iDstStride, Int iSize, Bool bVerticalDir, Bool bToTopOrLeft )
1400{
1401  Int iFDimStart   = 0;
1402  Int iInc         = 1;
1403  Int iSDimStart   = 0;
1404
1405  Int iFDimSrcStrd = bVerticalDir ? 1          : iSrcStride;
1406  Int iFDimDstStrd = bVerticalDir ? 1          : iDstStride;
1407
1408  Int iSDimSrcStrd = bVerticalDir ? iSrcStride : 1;
1409  Int iSDimDstStrd = bVerticalDir ? iDstStride : 1;
1410
1411  Int iFDimEnd     = bVerticalDir ? iWidth -1  : iHeight - 1;
1412  Int iSDimEnd     = bVerticalDir ? iHeight-1  : iWidth  - 1;
1413
1414  if ( bToTopOrLeft )
1415  {
1416    iSDimStart    = iSDimEnd;
1417    iSDimEnd      = 0;
1418    iInc         *= -1;
1419  }
1420
1421  for (Int iPosFDim = iFDimStart; iPosFDim <= iFDimEnd; iPosFDim++ )
1422  {
1423    Int  iCount      = 0;
1424    Bool bLastWasOne = false;
1425    Bool bDilate     = false;
1426    Int  iPosSDim    = iSDimStart;
1427    Bool bContinue   = true;
1428
1429    while ( bContinue )
1430    {
1431      if ( iCount == iSize )
1432      {
1433        iCount  = 0;
1434        bDilate = false;
1435      }
1436
1437      Pel iVal = piSrc[iPosSDim*iSDimSrcStrd];
1438      if( iVal == 0 && bLastWasOne )
1439      {
1440        iCount  = 0;
1441        bDilate = true;
1442      }
1443
1444      if( bDilate )
1445      {
1446        piDst[iPosSDim*iSDimDstStrd] = REN_USED_PEL;
1447        iCount++;
1448      }
1449      else
1450      {
1451        piDst[iPosSDim*iSDimDstStrd] = iVal;
1452      }
1453
1454
1455      bLastWasOne = (iVal == REN_USED_PEL);
1456      bContinue   = (iPosSDim != iSDimEnd);
1457      iPosSDim    += iInc;
1458    }
1459
1460    piSrc += iFDimSrcStrd;
1461    piDst += iFDimDstStrd;
1462  }
1463};
1464
1465
1466template class TRenFilter<REN_BIT_DEPTH>;
1467
1468template Bool TRenFilter<REN_BIT_DEPTH>::compare   (TRenImage<Pel     >*, TRenImage<Pel>*      );
1469template Bool TRenFilter<REN_BIT_DEPTH>::compare   (TRenImagePlane<Pel>*, TRenImagePlane<Pel>* );
1470                         
1471template Void TRenFilter<REN_BIT_DEPTH>::mirrorHor( TRenImage<Double>        *pcImage );
1472template Void TRenFilter<REN_BIT_DEPTH>::mirrorHor( TRenImage<Pel>           *pcImage );
1473template Void TRenFilter<REN_BIT_DEPTH>::mirrorHor( TRenImage<Int>           *pcImage );
1474template Void TRenFilter<REN_BIT_DEPTH>::mirrorHor( TRenImagePlane<Pel>      *pcImagePlane );
1475
1476#endif
1477
Note: See TracBrowser for help on using the repository browser.