source: 3DVCSoftware/branches/HTM-16.2-dev/source/Lib/TLibCommon/TComYuv.cpp @ 1412

Last change on this file since 1412 was 1412, checked in by tech, 7 years ago
  • Update HM-16.18
  • Cleanups
  • Encoder Extension

-- Representation formats
-- Parameter set sharing
-- GOP configuration

  • Property svn:eol-style set to native
File size: 21.4 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2017, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/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/** \file     TComYuv.cpp
35    \brief    general YUV buffer class
36    \todo     this should be merged with TComPicYuv
37*/
38
39#include <stdlib.h>
40#include <memory.h>
41#include <assert.h>
42#include <math.h>
43
44#include "CommonDef.h"
45#include "TComYuv.h"
46#include "TComInterpolationFilter.h"
47
48//! \ingroup TLibCommon
49//! \{
50
51TComYuv::TComYuv()
52{
53  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
54  {
55    m_apiBuf[comp] = NULL;
56  }
57}
58
59TComYuv::~TComYuv()
60{
61  destroy();
62}
63
64Void TComYuv::create( UInt iWidth, UInt iHeight, ChromaFormat chromaFormatIDC )
65{
66  destroy();
67  // set width and height
68  m_iWidth   = iWidth;
69  m_iHeight  = iHeight;
70  m_chromaFormatIDC = chromaFormatIDC;
71
72  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
73  {
74    // memory allocation
75    m_apiBuf[comp]  = (Pel*)xMalloc( Pel, getWidth(ComponentID(comp))*getHeight(ComponentID(comp)) );
76  }
77}
78
79Void TComYuv::destroy()
80{
81  // memory free
82  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
83  {
84    if (m_apiBuf[comp]!=NULL)
85    {
86      xFree( m_apiBuf[comp] );
87      m_apiBuf[comp] = NULL;
88    }
89  }
90}
91
92Void TComYuv::clear()
93{
94  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
95  {
96    if (m_apiBuf[comp]!=NULL)
97    {
98      ::memset( m_apiBuf[comp], 0, ( getWidth(ComponentID(comp)) * getHeight(ComponentID(comp))  )*sizeof(Pel) );
99    }
100  }
101}
102
103
104
105
106Void TComYuv::copyToPicYuv   ( TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
107{
108  for(Int comp=0; comp<getNumberValidComponents(); comp++)
109  {
110    copyToPicComponent  ( ComponentID(comp), pcPicYuvDst, ctuRsAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx );
111  }
112}
113
114Void TComYuv::copyToPicComponent  ( const ComponentID compID, TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
115{
116  const Int iWidth  = getWidth(compID) >>uiPartDepth;
117  const Int iHeight = getHeight(compID)>>uiPartDepth;
118
119  const Pel* pSrc     = getAddr(compID, uiPartIdx, iWidth);
120        Pel* pDst     = pcPicYuvDst->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
121
122  const UInt  iSrcStride  = getStride(compID);
123  const UInt  iDstStride  = pcPicYuvDst->getStride(compID);
124
125  for ( Int y = iHeight; y != 0; y-- )
126  {
127    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
128#if ENC_DEC_TRACE && NH_MV_ENC_DEC_TRAC
129    if ( g_traceCopyBack && compID == COMPONENT_Y)
130    { 
131      std::stringstream strStr; 
132      for ( Int x = 0; x < iWidth; x++)
133      {     
134        strStr << pSrc[ x ] << " " ; 
135      }
136      printStrIndent( true, strStr.str() );
137    }
138#endif
139    pDst += iDstStride;
140    pSrc += iSrcStride;
141  }
142}
143
144
145
146
147Void TComYuv::copyFromPicYuv   ( const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
148{
149  for(Int comp=0; comp<getNumberValidComponents(); comp++)
150  {
151    copyFromPicComponent  ( ComponentID(comp), pcPicYuvSrc, ctuRsAddr, uiAbsZorderIdx );
152  }
153}
154
155Void TComYuv::copyFromPicComponent  ( const ComponentID compID, const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
156{
157        Pel* pDst     = getAddr(compID);
158  const Pel* pSrc     = pcPicYuvSrc->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
159
160  const UInt iDstStride  = getStride(compID);
161  const UInt iSrcStride  = pcPicYuvSrc->getStride(compID);
162  const Int  iWidth=getWidth(compID);
163  const Int  iHeight=getHeight(compID);
164
165  for (Int y = iHeight; y != 0; y-- )
166  {
167    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
168    pDst += iDstStride;
169    pSrc += iSrcStride;
170  }
171}
172
173
174
175
176Void TComYuv::copyToPartYuv( TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
177{
178  for(Int comp=0; comp<getNumberValidComponents(); comp++)
179  {
180    copyToPartComponent  ( ComponentID(comp), pcYuvDst, uiDstPartIdx );
181  }
182}
183
184Void TComYuv::copyToPartComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
185{
186  const Pel* pSrc     = getAddr(compID);
187        Pel* pDst     = pcYuvDst->getAddr( compID, uiDstPartIdx );
188
189  const UInt iSrcStride  = getStride(compID);
190  const UInt iDstStride  = pcYuvDst->getStride(compID);
191  const Int  iWidth=getWidth(compID);
192  const Int  iHeight=getHeight(compID);
193
194  for (Int y = iHeight; y != 0; y-- )
195  {
196    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
197    pDst += iDstStride;
198    pSrc += iSrcStride;
199  }
200}
201
202
203
204
205Void TComYuv::copyPartToYuv( TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
206{
207  for(Int comp=0; comp<getNumberValidComponents(); comp++)
208  {
209    copyPartToComponent  ( ComponentID(comp), pcYuvDst, uiSrcPartIdx );
210  }
211}
212
213Void TComYuv::copyPartToComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
214{
215  const Pel* pSrc     = getAddr(compID, uiSrcPartIdx);
216        Pel* pDst     = pcYuvDst->getAddr(compID, 0 );
217
218  const UInt  iSrcStride  = getStride(compID);
219  const UInt  iDstStride  = pcYuvDst->getStride(compID);
220
221  const UInt uiHeight = pcYuvDst->getHeight(compID);
222  const UInt uiWidth = pcYuvDst->getWidth(compID);
223
224  for ( UInt y = uiHeight; y != 0; y-- )
225  {
226    ::memcpy( pDst, pSrc, sizeof(Pel)*uiWidth);
227    pDst += iDstStride;
228    pSrc += iSrcStride;
229  }
230}
231
232
233
234
235Void TComYuv::copyPartToPartYuv   ( TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidth, const UInt iHeight ) const
236{
237  for(Int comp=0; comp<getNumberValidComponents(); comp++)
238  {
239    copyPartToPartComponent   (ComponentID(comp), pcYuvDst, uiPartIdx, iWidth>>getComponentScaleX(ComponentID(comp)), iHeight>>getComponentScaleY(ComponentID(comp)) );
240  }
241}
242
243Void TComYuv::copyPartToPartComponent  ( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidthComponent, const UInt iHeightComponent ) const
244{
245  const Pel* pSrc =           getAddr(compID, uiPartIdx);
246        Pel* pDst = pcYuvDst->getAddr(compID, uiPartIdx);
247  if( pSrc == pDst )
248  {
249    //th not a good idea
250    //th best would be to fix the caller
251    return ;
252  }
253
254  const UInt  iSrcStride = getStride(compID);
255  const UInt  iDstStride = pcYuvDst->getStride(compID);
256  for ( UInt y = iHeightComponent; y != 0; y-- )
257  {
258    ::memcpy( pDst, pSrc, iWidthComponent * sizeof(Pel) );
259    pSrc += iSrcStride;
260    pDst += iDstStride;
261  }
262}
263
264
265
266
267Void TComYuv::copyPartToPartComponentMxN  ( const ComponentID compID, TComYuv* pcYuvDst, const TComRectangle &rect) const
268{
269  const Pel* pSrc =           getAddrPix( compID, rect.x0, rect.y0 );
270        Pel* pDst = pcYuvDst->getAddrPix( compID, rect.x0, rect.y0 );
271  if( pSrc == pDst )
272  {
273    //th not a good idea
274    //th best would be to fix the caller
275    return ;
276  }
277
278  const UInt  iSrcStride = getStride(compID);
279  const UInt  iDstStride = pcYuvDst->getStride(compID);
280  const UInt uiHeightComponent=rect.height;
281  const UInt uiWidthComponent=rect.width;
282  for ( UInt y = uiHeightComponent; y != 0; y-- )
283  {
284    ::memcpy( pDst, pSrc, uiWidthComponent * sizeof( Pel ) );
285    pSrc += iSrcStride;
286    pDst += iDstStride;
287  }
288}
289
290
291
292
293Void TComYuv::addClip( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize, const BitDepths &clipBitDepths )
294{
295  for(Int comp=0; comp<getNumberValidComponents(); comp++)
296  {
297    const ComponentID compID=ComponentID(comp);
298    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
299    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
300
301    const Pel* pSrc0 = pcYuvSrc0->getAddr(compID, uiTrUnitIdx, uiPartWidth );
302    const Pel* pSrc1 = pcYuvSrc1->getAddr(compID, uiTrUnitIdx, uiPartWidth );
303          Pel* pDst  = getAddr(compID, uiTrUnitIdx, uiPartWidth );
304
305    const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
306    const UInt iSrc1Stride = pcYuvSrc1->getStride(compID);
307    const UInt iDstStride  = getStride(compID);
308    const Int clipbd = clipBitDepths.recon[toChannelType(compID)];
309#if O0043_BEST_EFFORT_DECODING
310    const Int bitDepthDelta = clipBitDepths.stream[toChannelType(compID)] - clipbd;
311#endif
312
313    for ( Int y = uiPartHeight-1; y >= 0; y-- )
314    {
315      for ( Int x = uiPartWidth-1; x >= 0; x-- )
316      {
317#if O0043_BEST_EFFORT_DECODING
318        pDst[x] = Pel(ClipBD<Int>( Int(pSrc0[x]) + rightShiftEvenRounding<Pel>(pSrc1[x], bitDepthDelta), clipbd));
319#else
320        pDst[x] = Pel(ClipBD<Int>( Int(pSrc0[x]) + Int(pSrc1[x]), clipbd));
321#endif
322      }
323      pSrc0 += iSrc0Stride;
324      pSrc1 += iSrc1Stride;
325      pDst  += iDstStride;
326    }
327  }
328}
329
330
331
332
333Void TComYuv::subtract( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize )
334{
335  for(Int comp=0; comp<getNumberValidComponents(); comp++)
336  {
337    const ComponentID compID=ComponentID(comp);
338    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
339    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
340
341    const Pel* pSrc0 = pcYuvSrc0->getAddr( compID, uiTrUnitIdx, uiPartWidth );
342    const Pel* pSrc1 = pcYuvSrc1->getAddr( compID, uiTrUnitIdx, uiPartWidth );
343          Pel* pDst  = getAddr( compID, uiTrUnitIdx, uiPartWidth );
344
345    const Int  iSrc0Stride = pcYuvSrc0->getStride(compID);
346    const Int  iSrc1Stride = pcYuvSrc1->getStride(compID);
347    const Int  iDstStride  = getStride(compID);
348
349    for (Int y = uiPartHeight-1; y >= 0; y-- )
350    {
351      for (Int x = uiPartWidth-1; x >= 0; x-- )
352      {
353        pDst[x] = pSrc0[x] - pSrc1[x];
354      }
355      pSrc0 += iSrc0Stride;
356      pSrc1 += iSrc1Stride;
357      pDst  += iDstStride;
358    }
359  }
360}
361
362
363
364
365Void TComYuv::addAvg( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt iPartUnitIdx, const UInt uiWidth, const UInt uiHeight, const BitDepths &clipBitDepths )
366{
367  for(Int comp=0; comp<getNumberValidComponents(); comp++)
368  {
369    const ComponentID compID=ComponentID(comp);
370    const Pel* pSrc0  = pcYuvSrc0->getAddr( compID, iPartUnitIdx );
371    const Pel* pSrc1  = pcYuvSrc1->getAddr( compID, iPartUnitIdx );
372    Pel* pDst   = getAddr( compID, iPartUnitIdx );
373
374    const UInt  iSrc0Stride = pcYuvSrc0->getStride(compID);
375    const UInt  iSrc1Stride = pcYuvSrc1->getStride(compID);
376    const UInt  iDstStride  = getStride(compID);
377    const Int   clipbd      = clipBitDepths.recon[toChannelType(compID)];
378    const Int   shiftNum    = std::max<Int>(2, (IF_INTERNAL_PREC - clipbd)) + 1;
379    const Int   offset      = ( 1 << ( shiftNum - 1 ) ) + 2 * IF_INTERNAL_OFFS;
380
381    const Int   iWidth      = uiWidth  >> getComponentScaleX(compID);
382    const Int   iHeight     = uiHeight >> getComponentScaleY(compID);
383
384    if (iWidth&1)
385    {
386      assert(0);
387      exit(-1);
388    }
389    else if (iWidth&2)
390    {
391      for ( Int y = 0; y < iHeight; y++ )
392      {
393        for (Int x=0 ; x < iWidth; x+=2 )
394        {
395          pDst[ x + 0 ] = ClipBD( rightShift(( pSrc0[ x + 0 ] + pSrc1[ x + 0 ] + offset ), shiftNum), clipbd );
396          pDst[ x + 1 ] = ClipBD( rightShift(( pSrc0[ x + 1 ] + pSrc1[ x + 1 ] + offset ), shiftNum), clipbd );
397        }
398        pSrc0 += iSrc0Stride;
399        pSrc1 += iSrc1Stride;
400        pDst  += iDstStride;
401      }
402    }
403    else
404    {
405      for ( Int y = 0; y < iHeight; y++ )
406      {
407        for (Int x=0 ; x < iWidth; x+=4 )
408        {
409          pDst[ x + 0 ] = ClipBD( rightShift(( pSrc0[ x + 0 ] + pSrc1[ x + 0 ] + offset ), shiftNum), clipbd );
410          pDst[ x + 1 ] = ClipBD( rightShift(( pSrc0[ x + 1 ] + pSrc1[ x + 1 ] + offset ), shiftNum), clipbd );
411          pDst[ x + 2 ] = ClipBD( rightShift(( pSrc0[ x + 2 ] + pSrc1[ x + 2 ] + offset ), shiftNum), clipbd );
412          pDst[ x + 3 ] = ClipBD( rightShift(( pSrc0[ x + 3 ] + pSrc1[ x + 3 ] + offset ), shiftNum), clipbd );
413        }
414        pSrc0 += iSrc0Stride;
415        pSrc1 += iSrc1Stride;
416        pDst  += iDstStride;
417      }
418    }
419  }
420}
421
422Void TComYuv::removeHighFreq( const TComYuv* pcYuvSrc,
423                              const UInt uiPartIdx,
424                              const UInt uiWidth,
425                              const UInt uiHeight,
426                              const Int bitDepths[MAX_NUM_CHANNEL_TYPE],
427                              const Bool bClipToBitDepths
428                              )
429{
430  for(Int comp=0; comp<getNumberValidComponents(); comp++)
431  {
432    const ComponentID compID=ComponentID(comp);
433    const Pel* pSrc  = pcYuvSrc->getAddr(compID, uiPartIdx);
434    Pel* pDst  = getAddr(compID, uiPartIdx);
435
436    const Int iSrcStride = pcYuvSrc->getStride(compID);
437    const Int iDstStride = getStride(compID);
438    const Int iWidth  = uiWidth >>getComponentScaleX(compID);
439    const Int iHeight = uiHeight>>getComponentScaleY(compID);
440    if (bClipToBitDepths)
441    {
442      const Int clipBd=bitDepths[toChannelType(compID)];
443      for ( Int y = iHeight-1; y >= 0; y-- )
444      {
445        for ( Int x = iWidth-1; x >= 0; x-- )
446        {
447          pDst[x ] = ClipBD((2 * pDst[x]) - pSrc[x], clipBd);
448        }
449        pSrc += iSrcStride;
450        pDst += iDstStride;
451      }
452    }
453    else
454    {
455      for ( Int y = iHeight-1; y >= 0; y-- )
456      {
457        for ( Int x = iWidth-1; x >= 0; x-- )
458        {
459          pDst[x ] = (2 * pDst[x]) - pSrc[x];
460        }
461        pSrc += iSrcStride;
462        pDst += iDstStride;
463      }
464    }
465  }
466}
467
468#if NH_3D_VSO
469Void TComYuv::addClipPartLuma( Int bitDepth, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize )
470{
471  Int x, y;
472
473  Pel* pSrc0 = pcYuvSrc0->getAddr( COMPONENT_Y, uiTrUnitIdx);
474  Pel* pSrc1 = pcYuvSrc1->getAddr( COMPONENT_Y, uiTrUnitIdx);
475  Pel* pDst  =            getAddr( COMPONENT_Y, uiTrUnitIdx);
476
477  UInt iSrc0Stride = pcYuvSrc0->getStride( COMPONENT_Y );
478  UInt iSrc1Stride = pcYuvSrc1->getStride( COMPONENT_Y );
479  UInt iDstStride  =            getStride( COMPONENT_Y );
480  for ( y = uiPartSize-1; y >= 0; y-- )
481  {
482    for ( x = uiPartSize-1; x >= 0; x-- )
483    {
484      pDst[x] = ClipBD( pSrc0[x] + pSrc1[x], bitDepth );     
485    }
486    pSrc0 += iSrc0Stride;
487    pSrc1 += iSrc1Stride;
488    pDst  += iDstStride;
489  }
490}
491#endif
492
493#if NH_3D
494Void TComYuv::addARP( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, Bool bClip, const BitDepths &clipBitDepths )
495{
496  addARPLuma   ( pcYuvSrc0, pcYuvSrc1, uiAbsPartIdx, uiWidth   , uiHeight    , bClip , clipBitDepths);
497  addARPChroma ( pcYuvSrc0, pcYuvSrc1, uiAbsPartIdx, uiWidth>>1, uiHeight>>1 , bClip , clipBitDepths);
498}
499
500Void TComYuv::addARPLuma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, Bool bClip, const BitDepths &clipBitDepths )
501{
502  Int x, y;
503
504  Pel* pSrc0 = pcYuvSrc0->getAddr( COMPONENT_Y, uiAbsPartIdx );
505  Pel* pSrc1 = pcYuvSrc1->getAddr( COMPONENT_Y, uiAbsPartIdx );
506  Pel* pDst  = getAddr( COMPONENT_Y, uiAbsPartIdx );
507
508  UInt iSrc0Stride = pcYuvSrc0->getStride(COMPONENT_Y);
509  UInt iSrc1Stride = pcYuvSrc1->getStride(COMPONENT_Y);
510  UInt iDstStride  = getStride(COMPONENT_Y);
511  const Int clipbd = clipBitDepths.recon[CHANNEL_TYPE_LUMA];
512  Int iIFshift = IF_INTERNAL_PREC - clipbd;
513  Int iOffSet  = ( 1 << ( iIFshift - 1 ) ) + IF_INTERNAL_OFFS;
514  for ( y = uiHeight-1; y >= 0; y-- )
515  {
516    for ( x = uiWidth-1; x >= 0; x-- )
517    {
518      pDst[x] = pSrc0[x] + pSrc1[x];
519      if( bClip )
520      {
521        pDst[x] = Pel(ClipBD<Int>(Int( ( pDst[x] + iOffSet ) >> iIFshift ), clipbd));
522      }
523    }
524    pSrc0 += iSrc0Stride;
525    pSrc1 += iSrc1Stride;
526    pDst  += iDstStride;
527  }
528}
529
530Void TComYuv::addARPChroma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, Bool bClip, const BitDepths &clipBitDepths )
531{
532  Int x, y;
533
534  Pel* pSrcU0 = pcYuvSrc0->getAddr( COMPONENT_Cb, uiAbsPartIdx );
535  Pel* pSrcU1 = pcYuvSrc1->getAddr( COMPONENT_Cb, uiAbsPartIdx );
536  Pel* pSrcV0 = pcYuvSrc0->getAddr( COMPONENT_Cr, uiAbsPartIdx );
537  Pel* pSrcV1 = pcYuvSrc1->getAddr( COMPONENT_Cr, uiAbsPartIdx );
538  Pel* pDstU = getAddr( COMPONENT_Cb, uiAbsPartIdx );
539  Pel* pDstV = getAddr( COMPONENT_Cr, uiAbsPartIdx );
540
541  UInt  iSrc0StrideCb = pcYuvSrc0->getStride(COMPONENT_Cb);
542  UInt  iSrc1StrideCb = pcYuvSrc1->getStride(COMPONENT_Cb);
543  UInt  iDstStrideCb  = getStride(COMPONENT_Cb);
544
545  UInt  iSrc0StrideCr = pcYuvSrc0->getStride(COMPONENT_Cr);
546  UInt  iSrc1StrideCr = pcYuvSrc1->getStride(COMPONENT_Cr);
547  UInt  iDstStrideCr  = getStride(COMPONENT_Cr);
548
549  const Int clipbd = clipBitDepths.recon[CHANNEL_TYPE_CHROMA];
550  Int iIFshift = IF_INTERNAL_PREC - clipbd;
551  Int iOffSet  = ( 1 << ( iIFshift - 1 ) ) + IF_INTERNAL_OFFS;
552
553  for ( y = uiHeight-1; y >= 0; y-- )
554  {
555    for ( x = uiWidth-1; x >= 0; x-- )
556    {
557      pDstU[x] = pSrcU0[x] + pSrcU1[x];
558      pDstV[x] = pSrcV0[x] + pSrcV1[x];
559      if( bClip )
560      {
561        pDstU[x] = Pel(ClipBD<Int>( Int( ( pDstU[x] + iOffSet ) >> iIFshift ), clipbd));
562        pDstV[x] = Pel(ClipBD<Int>( Int( ( pDstV[x] + iOffSet ) >> iIFshift ), clipbd));
563      }
564    }
565
566    pSrcU0 += iSrc0StrideCb;
567    pSrcU1 += iSrc1StrideCb;
568    pSrcV0 += iSrc0StrideCr;
569    pSrcV1 += iSrc1StrideCr;
570    pDstU  += iDstStrideCb;
571    pDstV  += iDstStrideCr;
572  }
573}
574
575Void TComYuv::subtractARP( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiAbsPartIdx, UInt uiWidth , UInt uiHeight )
576{
577  subtractARPLuma  ( pcYuvSrc0, pcYuvSrc1,  uiAbsPartIdx, uiWidth    , uiHeight    );
578
579  if (uiWidth > 8 && pcYuvSrc1->getNumberValidComponents() > 1)
580  {
581    subtractARPChroma( pcYuvSrc0, pcYuvSrc1,  uiAbsPartIdx, uiWidth>>1 , uiHeight>>1 );
582}
583}
584
585Void TComYuv::subtractARPLuma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiAbsPartIdx, UInt uiWidth , UInt uiHeight )
586{
587  Int x, y;
588
589  Pel* pSrc0 = pcYuvSrc0->getAddr(COMPONENT_Y, uiAbsPartIdx );
590  Pel* pSrc1 = pcYuvSrc1->getAddr(COMPONENT_Y, uiAbsPartIdx );
591  Pel* pDst  = getAddr           (COMPONENT_Y, uiAbsPartIdx );
592
593  Int  iSrc0Stride = pcYuvSrc0->getStride(COMPONENT_Y);
594  Int  iSrc1Stride = pcYuvSrc1->getStride(COMPONENT_Y);
595  Int  iDstStride  = getStride(COMPONENT_Y);
596  for ( y = uiHeight-1; y >= 0; y-- )
597  {
598    for ( x = uiWidth-1; x >= 0; x-- )
599    {
600      pDst[x] = pSrc0[x] - pSrc1[x];
601    }
602    pSrc0 += iSrc0Stride;
603    pSrc1 += iSrc1Stride;
604    pDst  += iDstStride;
605  }
606}
607
608Void TComYuv::subtractARPChroma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiAbsPartIdx, UInt uiWidth , UInt uiHeight )
609{
610  Int x, y;
611
612  Pel* pSrcU0 = pcYuvSrc0->getAddr(COMPONENT_Cb, uiAbsPartIdx );
613  Pel* pSrcU1 = pcYuvSrc1->getAddr(COMPONENT_Cb, uiAbsPartIdx );
614  Pel* pSrcV0 = pcYuvSrc0->getAddr(COMPONENT_Cr, uiAbsPartIdx );
615  Pel* pSrcV1 = pcYuvSrc1->getAddr(COMPONENT_Cr, uiAbsPartIdx );
616  Pel* pDstU  = getAddr(COMPONENT_Cb, uiAbsPartIdx );
617  Pel* pDstV  = getAddr(COMPONENT_Cr, uiAbsPartIdx );
618
619  Int  iSrc0Stride = pcYuvSrc0->getStride(COMPONENT_Cb);
620  Int  iSrc1Stride = pcYuvSrc1->getStride(COMPONENT_Cb);
621  Int  iDstStride  = getStride( COMPONENT_Cb );
622  for ( y = uiHeight-1; y >= 0; y-- )
623  {
624    for ( x = uiWidth-1; x >= 0; x-- )
625    {
626      pDstU[x] = pSrcU0[x] - pSrcU1[x];
627      pDstV[x] = pSrcV0[x] - pSrcV1[x];
628    }
629    pSrcU0 += iSrc0Stride;
630    pSrcU1 += iSrc1Stride;
631    pSrcV0 += iSrc0Stride;
632    pSrcV1 += iSrc1Stride;
633    pDstU  += iDstStride;
634    pDstV  += iDstStride;
635  }
636}
637
638Void TComYuv::multiplyARP( UInt uiAbsPartIdx , UInt uiWidth , UInt uiHeight , UChar dW )
639{
640  multiplyARPLuma( uiAbsPartIdx , uiWidth , uiHeight , dW );
641
642  if ( uiWidth > 8 && getNumberValidComponents() > 1 )
643  {
644    multiplyARPChroma( uiAbsPartIdx , uiWidth >> 1 , uiHeight >> 1 , dW );
645}
646}
647
648Void TComYuv::xxMultiplyLine( Pel* pSrcDst , UInt uiWidth , UChar dW )
649{
650  assert( dW == 2 );
651  for( UInt x = 0 ; x < uiWidth ; x++ )
652    pSrcDst[x] =  pSrcDst[x] >> 1;
653}
654
655Void TComYuv::multiplyARPLuma( UInt uiAbsPartIdx , UInt uiWidth , UInt uiHeight , UChar dW )
656{
657  Pel* pDst  = getAddr(COMPONENT_Y, uiAbsPartIdx );
658  Int  iDstStride  = getStride(COMPONENT_Y);
659  for ( Int y = uiHeight-1; y >= 0; y-- )
660  {
661    xxMultiplyLine( pDst , uiWidth , dW );
662    pDst  += iDstStride;
663  }
664}
665
666Void TComYuv::multiplyARPChroma( UInt uiAbsPartIdx , UInt uiWidth , UInt uiHeight , UChar dW )
667{
668  Pel* pDstU  = getAddr( COMPONENT_Cb, uiAbsPartIdx );
669  Pel* pDstV  = getAddr( COMPONENT_Cr, uiAbsPartIdx );
670
671  Int  iDstStride  = getStride( COMPONENT_Cb );
672  for ( Int y = uiHeight-1; y >= 0; y-- )
673  {
674    xxMultiplyLine( pDstU , uiWidth , dW );
675    xxMultiplyLine( pDstV , uiWidth , dW );
676    pDstU  += iDstStride;
677    pDstV  += iDstStride;
678  }
679}
680#endif
681
682//! \}
Note: See TracBrowser for help on using the repository browser.