source: 3DVCSoftware/branches/HTM-3.0-Qualcomm/source/Lib/TLibRenderer/TRenFilter.cpp @ 64

Last change on this file since 64 was 56, checked in by hschwarz, 13 years ago

updated trunk (move to HM6.1)

  • Property svn:eol-style set to native
File size: 50.3 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->getNumberOfPlanes(); 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}
936
937Void TRenFilter::laplace( DoubleImage* pcInputImage, DoubleImage* pcOutputImage )
938{
939  for (UInt uiCurPlane = 0; uiCurPlane < pcInputImage->getNumberOfPlanes(); uiCurPlane++)
940  {
941    DoubleImagePlane* pcInputPlane  = pcInputImage  ->getPlane(uiCurPlane);
942    DoubleImagePlane* pcOutputPlane = pcOutputImage ->getPlane(uiCurPlane);
943
944    UInt uiWidth  = pcInputPlane->getWidth();
945    UInt uiHeight = pcInputPlane->getHeight();
946
947    Double* pdInputData  = pcInputPlane  ->getPlaneData();
948    Double* pdOutputData = pcOutputPlane ->getPlaneData();
949
950    for (UInt uiPosY = 1; uiPosY < uiHeight-1; uiPosY++)
951    {
952      UInt uOff = uiPosY * uiWidth;
953      for(UInt uiPosX = 1; uiPosX < uiWidth-1; uiPosX++)
954      {
955        UInt uOff2 = uOff + uiPosX;
956        pdOutputData[uOff2] =     4 * pdInputData[uOff2]
957        -   pdInputData[uOff2 - 1]
958        -   pdInputData[uOff2 + 1]
959        -   pdInputData[uOff2 - uiWidth]
960        -   pdInputData[uOff2 + uiWidth];
961      }
962    };
963
964    // left and right margin
965    for (UInt uiPosY = 1; uiPosY < uiHeight-1; uiPosY++)
966    {
967      UInt uOff  = uiPosY * uiWidth;
968      pdOutputData[uOff] = 3 * pdInputData[uOff]
969      -   pdInputData[uOff + 1]
970      -   pdInputData[uOff - uiWidth]
971      -   pdInputData[uOff + uiWidth];
972
973
974      uOff = (uiPosY + 1) * uiWidth - 1;
975      pdOutputData[uOff] = 3 * pdInputData[uOff]
976      -   pdInputData[uOff - 1]
977      -   pdInputData[uOff - uiWidth]
978      -   pdInputData[uOff + uiWidth];
979    }
980
981    for (UInt uiPosX = 1; uiPosX < uiWidth-1; uiPosX++)
982    {
983      UInt uOff  = uiPosX;
984      pdOutputData[uOff] = 3 * pdInputData[uOff]
985      -   pdInputData[uOff + 1]
986      -   pdInputData[uOff - 1]
987      -   pdInputData[uOff + uiWidth];
988
989
990      uOff = (uiHeight - 1) * uiWidth + uiPosX;
991      pdOutputData[uOff] = 3 * pdInputData[uOff]
992      -   pdInputData[uOff + 1]
993      -   pdInputData[uOff - 1]
994      -   pdInputData[uOff - uiWidth];
995    }
996
997    UInt uOff = 0;
998    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff+1] - pdInputData[ uOff + uiWidth];
999    uOff = uiWidth - 1;
1000    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff-1] - pdInputData[ uOff + uiWidth ];
1001    uOff = (uiHeight - 1) * uiWidth;
1002    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff+1] - pdInputData[ uOff - uiWidth];
1003    uOff = uiHeight * uiWidth - 1;
1004    pdOutputData[uOff] = 2 * pdInputData[uOff] - pdInputData[uOff-1] - pdInputData[ uOff - uiWidth];
1005
1006  }
1007}
1008
1009
1010Void TRenFilter::conv( PelImage* pcImage, DoubleImage* pcKernel )
1011{
1012  PelImage* pcTemp = pcImage->create();
1013
1014  DoubleImagePlane* pcKernelPlane = 0;
1015  for (UInt uiCurPlane = 0; uiCurPlane < pcImage->getNumberOfPlanes(); uiCurPlane++) {
1016
1017    PelImagePlane* pcPlane     = pcImage->getPlane(uiCurPlane);
1018    PelImagePlane* pcTempPlane = pcTemp ->getPlane(uiCurPlane);
1019
1020    if ( uiCurPlane <= pcKernel->getNumberOfPlanes() )
1021    {
1022      pcKernelPlane = pcKernel->getPlane(uiCurPlane);
1023    };
1024
1025    UInt uiWidth  = pcPlane->getWidth();
1026    UInt uiHeight = pcPlane->getHeight();
1027
1028    UInt uiKernelWidth  = pcKernelPlane->getWidth();
1029    UInt uiKernelHeight = pcKernelPlane->getHeight();
1030
1031    Pel*    pcData         = pcPlane      ->getPlaneData();
1032    Pel*    pcTempData     = pcTempPlane  ->getPlaneData();
1033    Double* pdKernelData   = pcKernelPlane->getPlaneData();
1034
1035    UInt uiDataStride       = pcPlane      ->getStride();
1036    UInt uiTempDataStride   = pcTempPlane  ->getStride();
1037    UInt uiKernelDataStride = pcKernelPlane->getStride();
1038
1039    for(UInt uiPosY = 0; uiPosY < uiHeight; uiPosY++)
1040    {
1041      UInt uOff = uiPosY * uiTempDataStride;
1042      for(UInt uiPosX = 0; uiPosX < uiWidth; uiPosX++)
1043      {
1044        Double dSum = 0;
1045        for(UInt uKY = 0; uKY < uiKernelHeight; uKY++)
1046        {
1047          UInt uKOff = uKY * uiKernelDataStride;
1048
1049          Int iYSrc = uiPosY - (uiKernelHeight/2) + uKY;
1050
1051          if (iYSrc < 0)
1052            iYSrc = -iYSrc;
1053
1054          if (iYSrc >= (Int)uiHeight)
1055            iYSrc = 2*uiHeight - iYSrc - 1;
1056
1057          UInt uSrcOff = iYSrc * uiDataStride;
1058
1059          for(UInt uKX = 0; uKX < uiKernelWidth; uKX++)
1060          {
1061            Int iXSrc = uiPosX - (uiKernelWidth/2) + uKX;
1062
1063            if (iXSrc < 0)
1064              iXSrc = -iXSrc;
1065
1066            if (iXSrc >= (Int)uiWidth)
1067              iXSrc = 2*uiWidth - iXSrc - 1;
1068
1069            dSum += pcData[uSrcOff + iXSrc] * pdKernelData[uKOff + uKX];
1070          }
1071        }
1072        pcTempData[uOff + uiPosX] = (Pel) (dSum + ( ( dSum < 0 ) ? -0.5 : 0.5)  );
1073      }
1074    }
1075  }
1076
1077  pcImage->assign(pcTemp);
1078  delete pcTemp;
1079}
1080
1081
1082// Horizontal Up sampling luma
1083Void TRenFilter::sampleHorUp( Int iLog2HorSampFac, Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1084{
1085  TRenInterpFilter cFilter;
1086  switch ( iLog2HorSampFac )
1087  {
1088  case 0:
1089    xDistributeArray              ( pcInputPlaneData, iInputStride, 1 , 1, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride, 1, 1 );
1090    break;
1091  case 1:
1092    xDistributeArray              ( pcInputPlaneData, iInputStride, 1 , 1, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride, 2, 1 );
1093    cFilter.xCTI_FilterHalfHor    ( pcInputPlaneData, iInputStride,     1, iInputWidth, iHeight, iOutputStride, 2, ++pcOutputPlaneData );
1094    break;
1095  case 2:
1096    xDistributeArray              ( pcInputPlaneData, iInputStride, 1 , 1, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride, 4, 1 );
1097    cFilter.xCTI_FilterQuarter0Hor( pcInputPlaneData, iInputStride, 1, iInputWidth, iHeight, iOutputStride, 4, ++pcOutputPlaneData );
1098    cFilter.xCTI_FilterHalfHor    ( pcInputPlaneData, iInputStride, 1, iInputWidth, iHeight, iOutputStride, 4, ++pcOutputPlaneData );
1099    cFilter.xCTI_FilterQuarter1Hor( pcInputPlaneData, iInputStride, 1, iInputWidth, iHeight, iOutputStride, 4, ++pcOutputPlaneData );
1100    break;
1101  }
1102}
1103
1104// horizontal up sampling chroma
1105Void TRenFilter::sampleCHorUp(Int iLog2HorSampFac, Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1106{
1107  switch ( iLog2HorSampFac )
1108  {
1109  case 0:
1110    xDistributeArray( pcInputPlaneData,   iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                  , iOutputStride, 1 , 1 );
1111    break;
1112  case 1:
1113    xDistributeArray( pcInputPlaneData,   iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                  , iOutputStride, 2 , 1 );
1114    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +1, iOutputStride, 2 , 1, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1115    break;
1116  case 2:
1117    xDistributeArray( pcInputPlaneData,   iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                  , iOutputStride, 4 , 1 );
1118    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +1, iOutputStride, 4 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_QUA0 );
1119    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +2, iOutputStride, 4 , 1, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1120    xInterpHorChroma( pcInputPlaneData  , iInputStride  , 1, 1, iInputWidth,   iHeight   , pcOutputPlaneData                +3, iOutputStride, 4 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_QUA1 );
1121    break;
1122  }
1123}
1124
1125Void TRenFilter::sampleCUpHorUp( Int iLog2HorSampFac, Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1126{
1127
1128  switch ( iLog2HorSampFac )
1129  {
1130  case 0:
1131    xDistributeArray( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData                -2, iOutputStride, 2,  2 );
1132    xInterpVerChroma( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData+1*iOutputStride-2, iOutputStride, 2 , 2, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1133    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 2, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData+1                , iOutputStride, 2 , 1, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1134    break;
1135  case 1:
1136    xDistributeArray( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData                -4, iOutputStride, 4 , 2 );
1137    xInterpVerChroma( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData+1*iOutputStride-4, iOutputStride, 4 , 2, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1138    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 4, 1, iInputWidth, iHeight*2 , pcOutputPlaneData                +1, iOutputStride, 4 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_QUA0 );
1139    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 4, 1, iInputWidth, iHeight*2 , pcOutputPlaneData                +2, iOutputStride, 4 , 1, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1140    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 4, 1, iInputWidth, iHeight*2 , pcOutputPlaneData                +3, iOutputStride, 4 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_QUA1 );
1141    break;
1142  case 2:
1143    xDistributeArray( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData                -8, iOutputStride, 8 , 2 );
1144    xInterpVerChroma( pcInputPlaneData-1, iInputStride  , 1, 1, iInputWidth+3, iHeight   , pcOutputPlaneData+1*iOutputStride-8, iOutputStride, 8 , 2, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1145    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +1, iOutputStride, 8 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_OCT0 );
1146    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +2, iOutputStride, 8 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_QUA0 );
1147    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +3, iOutputStride, 8 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_OCT1 );
1148    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +4, iOutputStride, 8 , 1, &TRenInterpFilter::xCTI_Filter_VPS04_C_HAL );
1149    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +5, iOutputStride, 8 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_OCT2 );
1150    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +6, iOutputStride, 8 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_QUA1 );
1151    xInterpHorChroma( pcOutputPlaneData , iOutputStride , 8, 1, iInputWidth,   iHeight*2 , pcOutputPlaneData                +7, iOutputStride, 8 , 1, &TRenInterpFilter::xCTI_Filter_VP04_C_OCT3 );
1152    break;
1153  }
1154}
1155
1156
1157// Down Sampling
1158// Down sample luma
1159Void TRenFilter::sampleHorDown(Int iLog2HorSampFac,  Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1160{
1161  switch ( iLog2HorSampFac )
1162  {
1163  case 0:
1164    xDistributeArray( pcInputPlaneData, iInputStride, 1, 1, iInputWidth,iHeight, pcOutputPlaneData, iOutputStride, 1 , 1 );
1165    break;
1166  case 1:
1167    xSampleDownHor2(pcInputPlaneData, iInputStride, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride);
1168    break;
1169  case 2:
1170    xSampleDownHor4(pcInputPlaneData, iInputStride, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride);
1171    break;
1172  }
1173}
1174
1175
1176Void TRenFilter::sampleCHorDown(Int iLog2HorSampFac,  Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1177{
1178  //GT: currently the same as for luma
1179  sampleHorDown( iLog2HorSampFac, pcInputPlaneData, iInputStride, iInputWidth, iHeight, pcOutputPlaneData, iOutputStride);
1180}
1181
1182
1183
1184// Up sampling chroma
1185Void TRenFilter::sampleCDownHorDown( Int iLog2HorSampFac,  Pel* pcInputPlaneData, Int iInputStride, Int iInputWidth, Int iInputHeight, Pel* pcOutputPlaneData, Int iOutputStride  )
1186{
1187  // create buffer
1188  Int iBufferStride   = iInputWidth >> (iLog2HorSampFac + 1);
1189  Pel* piBuffer       = new Pel[ iBufferStride * (iInputHeight+2) ];
1190
1191  switch ( iLog2HorSampFac )
1192  {
1193  case 0:
1194    xSampleDownHor2( pcInputPlaneData - iInputStride,  iInputStride, iInputWidth  , iInputHeight+1, piBuffer,  iBufferStride);
1195    break;
1196  case 1:
1197    xSampleDownHor4( pcInputPlaneData - iInputStride , iInputStride,  iInputWidth , iInputHeight+1, piBuffer, iBufferStride);
1198    break;
1199  case 2:
1200    xSampleDownHor8( pcInputPlaneData - iInputStride , iInputStride,  iInputWidth  , iInputHeight+1, piBuffer, iBufferStride);
1201    break;
1202  }
1203  xSampleDownVer2( piBuffer + iBufferStride       , iBufferStride, iBufferStride, iInputHeight,   pcOutputPlaneData, iOutputStride);
1204  delete[] piBuffer;
1205}
1206
1207Void TRenFilter::xDistributeArray(Pel* pcSrc, Int iSrcStride, Int iSrcStepX, Int iSrcStepY, Int iWidth, Int iHeight, Pel* pcDst, Int iDstStride, Int iDstStepX, Int iDstStepY)
1208{
1209  iDstStride *= iDstStepY;
1210  iSrcStride *= iSrcStepY;
1211  for (Int iYPos = 0; iYPos < iHeight; iYPos++ )
1212  {
1213    Pel* pcCurDst = pcDst;
1214    Pel* pcCurSrc  = pcSrc;
1215    for (Int iXPos = 0; iXPos < iWidth; iXPos ++)
1216    {
1217      *pcCurDst = *pcCurSrc;
1218
1219      pcCurDst += iDstStepX;
1220      pcCurSrc += iSrcStepX;
1221    }
1222    pcDst  += iDstStride;
1223    pcSrc  += iSrcStride;
1224  }
1225}
1226
1227
1228Void TRenFilter::xInterpHorChroma( Pel* piSrc, Int iSrcStride, Int iSrcStepX, Int iSrcStepY, Int iWidth, Int iHeight, Pel* piDst, Int iDstStride, Int iDstStepX, Int iDstStepY, FpChromaIntFilt fpFilter )
1229{
1230  Int   iSum;
1231  Pel*  piSrcTmp;
1232
1233  TRenInterpFilter cFilter;
1234  for ( Int y = iHeight; y != 0; y-- )
1235  {
1236    piSrcTmp = piSrc - iSrcStepX;
1237    for ( Int x = 0; x < iWidth; x++ )
1238    {
1239      iSum      = (cFilter.*fpFilter)( piSrcTmp,  iSrcStepX );
1240      piDst[x * iDstStepX ] =  Clip ((iSum +  32) >>  6 );
1241      piSrcTmp+= iSrcStepX;
1242    }
1243    piSrc += iSrcStride * iSrcStepY;
1244    piDst += iDstStride * iDstStepY;
1245  }
1246}
1247
1248Void TRenFilter::xInterpVerChroma( Pel* piSrc, Int iSrcStride, Int iSrcStepX, Int iSrcStepY, Int iWidth, Int iHeight, Pel* piDst, Int iDstStride, Int iDstStepX, Int iDstStepY, FpChromaIntFilt fpFilter )
1249{
1250  Int   iSum;
1251  Pel*  piSrcTmp;
1252
1253  TRenInterpFilter cFilter;
1254  for ( Int y = iHeight; y != 0; y-- )
1255  {
1256    piSrcTmp = piSrc - iSrcStepY * iSrcStride;
1257    for ( Int x = 0; x < iWidth; x++ )
1258    {
1259      iSum      = (cFilter.*fpFilter)( piSrcTmp,  iSrcStepY * iSrcStride );
1260      piDst[x * iDstStepX ]  =  Clip ((iSum +  32) >>  6 );
1261      piSrcTmp += iSrcStepX;
1262    }
1263    piSrc += iSrcStride * iSrcStepY;
1264    piDst += iDstStride * iDstStepY;
1265  }
1266}
1267
1268
1269Void TRenFilter::xSampleDownHor2( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iHeight, Pel* piDst, Int iDstStride  )
1270{
1271  Int   iSum;
1272  Pel*  piSrcTmp;
1273
1274
1275  for ( Int y = iHeight; y != 0; y-- )
1276  {
1277    piSrcTmp = piSrc - 1 ;
1278    for ( Int x = 0; x < (iSrcWidth >> 1); x++ )
1279    {
1280      // { 1,2,1 }
1281      iSum = piSrcTmp[0] + piSrcTmp[2] +  (piSrcTmp[1] << 1);
1282      piDst[x] = Clip( (iSum +  2) >>  2 );
1283      piSrcTmp += 2;
1284    }
1285    piSrc += iSrcStride;
1286    piDst += iDstStride;
1287  }
1288};
1289
1290Void TRenFilter::xSampleDownVer2( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iSrcHeight, Pel* piDst, Int iDstStride  )
1291{
1292  Int   iSum;
1293  Pel*  piSrcTmp;
1294
1295  for ( Int y = (iSrcHeight >> 1); y != 0; y-- )
1296  {
1297    piSrcTmp = piSrc -1 * iSrcStride;
1298    for ( Int x = 0; x < iSrcWidth; x++ )
1299    {
1300      // { 1,2,1 }
1301      iSum = piSrcTmp[0] + piSrcTmp[ iSrcStride << 1] +  (piSrcTmp[ iSrcStride ] << 1);
1302      piDst[x] = Clip( (iSum +  2) >>  2 );
1303      piSrcTmp += 1;
1304    }
1305    piSrc += (iSrcStride << 1);
1306    piDst += iDstStride;
1307  }
1308};
1309
1310Void TRenFilter::xSampleDownHor4( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iHeight, Pel* piDst, Int iDstStride  )
1311{
1312  Int   iSum;
1313  Pel*  piSrcTmp;
1314
1315  Int iTmp0, iTmp1, iTmp2;
1316
1317  for ( Int y = iHeight; y != 0; y-- )
1318  {
1319    piSrcTmp = piSrc -2 ;
1320    for ( Int x = 0; x < (iSrcWidth >> 2); x++ )
1321    {
1322      // { 1,4,6,4,1 }
1323      iTmp0 = piSrcTmp[0] + piSrcTmp[4];
1324      iTmp1 = piSrcTmp[1] + piSrcTmp[3];
1325      iTmp2 = piSrcTmp[2];
1326
1327      iSum = iTmp0 +  (iTmp2 << 1) + ((iTmp1 + iTmp2) << 2);
1328      piDst[x] = Clip( (iSum +  8) >>  4 );
1329      piSrcTmp += 4;
1330    }
1331    piSrc += iSrcStride;
1332    piDst += iDstStride;
1333  }
1334};
1335
1336Void TRenFilter::xSampleDownHor8( Pel* piSrc, Int iSrcStride, Int iSrcWidth, Int iHeight, Pel* piDst, Int iDstStride  )
1337{
1338  Int   iSum;
1339  Pel*  piSrcTmp;
1340
1341  Int iTmp0, iTmp1, iTmp2, iTmp3;
1342
1343  for ( Int y = iHeight; y != 0; y-- )
1344  {
1345    piSrcTmp = piSrc -3;
1346    for ( Int x = 0; x < (iSrcWidth >> 3); x++ )
1347    {
1348      // { 1,6,15,20,15,6,1 }
1349      iTmp0 = piSrcTmp[0] + piSrcTmp[6];
1350      iTmp1 = piSrcTmp[1] + piSrcTmp[5];
1351      iTmp2 = piSrcTmp[2] + piSrcTmp[4];
1352      iTmp3 = piSrcTmp[3];
1353
1354      iSum = iTmp0 - iTmp2 + ( iTmp1  << 1) + ( (iTmp1 + iTmp3) << 2) + ((iTmp2 + iTmp3) << 4);
1355      piDst[x] = Clip( (iSum +  32) >>  6 );
1356      piSrcTmp += 8;
1357    }
1358    piSrc += iSrcStride;
1359    piDst += iDstStride;
1360  }
1361};
1362
1363Void TRenFilter::xDilate( Pel* piSrc, Int iSrcStride, Int iWidth, Int iHeight, Pel* piDst, Int iDstStride, Int iSize, Bool bVerticalDir, Bool bToTopOrLeft )
1364{
1365  Int iFDimStart   = 0;
1366  Int iInc         = 1;
1367  Int iSDimStart   = 0;
1368
1369  Int iFDimSrcStrd = bVerticalDir ? 1          : iSrcStride;
1370  Int iFDimDstStrd = bVerticalDir ? 1          : iDstStride;
1371
1372  Int iSDimSrcStrd = bVerticalDir ? iSrcStride : 1;
1373  Int iSDimDstStrd = bVerticalDir ? iDstStride : 1;
1374
1375  Int iFDimEnd     = bVerticalDir ? iWidth -1  : iHeight - 1;
1376  Int iSDimEnd     = bVerticalDir ? iHeight-1  : iWidth  - 1;
1377
1378  if ( bToTopOrLeft )
1379  {
1380    iSDimStart    = iSDimEnd;
1381    iSDimEnd      = 0;
1382    iInc         *= -1;
1383  }
1384
1385  for (Int iPosFDim = iFDimStart; iPosFDim <= iFDimEnd; iPosFDim++ )
1386  {
1387    Int  iCount      = 0;
1388    Bool bLastWasOne = false;
1389    Bool bDilate     = false;
1390    Int  iPosSDim    = iSDimStart;
1391    Bool bContinue   = true;
1392
1393    while ( bContinue )
1394    {
1395      if ( iCount == iSize )
1396      {
1397        iCount  = 0;
1398        bDilate = false;
1399      }
1400
1401      Pel iVal = piSrc[iPosSDim*iSDimSrcStrd];
1402      if( iVal == 0 && bLastWasOne )
1403      {
1404        iCount  = 0;
1405        bDilate = true;
1406      }
1407
1408      if( bDilate )
1409      {
1410        piDst[iPosSDim*iSDimDstStrd] = REN_USED_PEL;
1411        iCount++;
1412      }
1413      else
1414      {
1415        piDst[iPosSDim*iSDimDstStrd] = iVal;
1416      }
1417
1418
1419      bLastWasOne = (iVal == REN_USED_PEL);
1420      bContinue   = (iPosSDim != iSDimEnd);
1421      iPosSDim    += iInc;
1422    }
1423
1424    piSrc += iFDimSrcStrd;
1425    piDst += iFDimDstStrd;
1426  }
1427};
1428
1429
1430template Bool TRenFilter::compare   (TRenImage<Pel     >*, TRenImage<Pel>*      );
1431template Bool TRenFilter::compare   (TRenImagePlane<Pel>*, TRenImagePlane<Pel>* );
1432
1433template Void TRenFilter::mirrorHor(        TRenImage<Double>        *pcImage );
1434template Void TRenFilter::mirrorHor(        TRenImage<Pel>           *pcImage );
1435template Void TRenFilter::mirrorHor(        TRenImage<Int>           *pcImage );
1436template Void TRenFilter::mirrorHor(        TRenImagePlane<Pel>      *pcImagePlane );
Note: See TracBrowser for help on using the repository browser.