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

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

Added missing parts.

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