source: 3DVCSoftware/branches/0.3-poznan-univ/source/Lib/TLibRenderer/TRenFilter.cpp @ 28

Last change on this file since 28 was 28, checked in by poznan-univ, 13 years ago

Poznan Tools

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