source: 3DVCSoftware/branches/HTM-DEV-0.2-dev/source/Lib/TLibRenderer/TRenFilter.cpp @ 438

Last change on this file since 438 was 438, checked in by tech, 11 years ago

Integrated 3D encoder control, camera parameters, renderer and MV fixes.

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