source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TComYuv.cpp

Last change on this file was 1549, checked in by seregin, 9 years ago

port rev 4732, update copyright notice to include 2016

  • Property svn:eol-style set to native
File size: 14.2 KB
RevLine 
[313]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
[1029]4 * granted under this license.
[313]5 *
[1549]6 * Copyright (c) 2010-2016, ITU/ISO/IEC
[313]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{
[1029]53  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
54  {
55    m_apiBuf[comp] = NULL;
56  }
[313]57}
58
59TComYuv::~TComYuv()
60{
[1540]61  destroy();
[313]62}
63
[1029]64Void TComYuv::create( UInt iWidth, UInt iHeight, ChromaFormat chromaFormatIDC )
[313]65{
[1540]66  destroy();
[313]67  // set width and height
68  m_iWidth   = iWidth;
69  m_iHeight  = iHeight;
[1029]70  m_chromaFormatIDC = chromaFormatIDC;
71
[1313]72  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
[1029]73  {
74    // memory allocation
[1313]75    m_apiBuf[comp]  = (Pel*)xMalloc( Pel, getWidth(ComponentID(comp))*getHeight(ComponentID(comp)) );
[1029]76  }
[313]77}
78
79Void TComYuv::destroy()
80{
81  // memory free
[1313]82  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
[1029]83  {
[1313]84    if (m_apiBuf[comp]!=NULL)
[1246]85    {
[1313]86      xFree( m_apiBuf[comp] );
87      m_apiBuf[comp] = NULL;
[1246]88    }
[1029]89  }
[313]90}
91
92Void TComYuv::clear()
93{
[1313]94  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
[1029]95  {
[1313]96    if (m_apiBuf[comp]!=NULL)
[1246]97    {
[1313]98      ::memset( m_apiBuf[comp], 0, ( getWidth(ComponentID(comp)) * getHeight(ComponentID(comp))  )*sizeof(Pel) );
[1246]99    }
[1029]100  }
[313]101}
102
[1029]103
104
105
106Void TComYuv::copyToPicYuv   ( TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
[313]107{
[1313]108  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[1246]109  {
[1313]110    copyToPicComponent  ( ComponentID(comp), pcPicYuvDst, ctuRsAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx );
[1246]111  }
[313]112}
113
[1313]114Void TComYuv::copyToPicComponent  ( const ComponentID compID, TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
[313]115{
[1313]116  const Int iWidth  = getWidth(compID) >>uiPartDepth;
117  const Int iHeight = getHeight(compID)>>uiPartDepth;
[1029]118
[1313]119  const Pel* pSrc     = getAddr(compID, uiPartIdx, iWidth);
120        Pel* pDst     = pcPicYuvDst->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
[1029]121
[1313]122  const UInt  iSrcStride  = getStride(compID);
123  const UInt  iDstStride  = pcPicYuvDst->getStride(compID);
[1029]124
125  for ( Int y = iHeight; y != 0; y-- )
[313]126  {
127    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
128    pDst += iDstStride;
129    pSrc += iSrcStride;
130  }
131}
132
[1029]133
134
135
136Void TComYuv::copyFromPicYuv   ( const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
[313]137{
[1313]138  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[1246]139  {
[1313]140    copyFromPicComponent  ( ComponentID(comp), pcPicYuvSrc, ctuRsAddr, uiAbsZorderIdx );
[1246]141  }
[313]142}
143
[1313]144Void TComYuv::copyFromPicComponent  ( const ComponentID compID, const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
[313]145{
[1313]146        Pel* pDst     = getAddr(compID);
147  const Pel* pSrc     = pcPicYuvSrc->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
[313]148
[1313]149  const UInt iDstStride  = getStride(compID);
150  const UInt iSrcStride  = pcPicYuvSrc->getStride(compID);
151  const Int  iWidth=getWidth(compID);
152  const Int  iHeight=getHeight(compID);
[1029]153
154  for (Int y = iHeight; y != 0; y-- )
[313]155  {
[1029]156    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
[313]157    pDst += iDstStride;
158    pSrc += iSrcStride;
159  }
160}
161
[1029]162
163
164
165Void TComYuv::copyToPartYuv( TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
[313]166{
[1313]167  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[1246]168  {
[1313]169    copyToPartComponent  ( ComponentID(comp), pcYuvDst, uiDstPartIdx );
[1246]170  }
[313]171}
172
[1313]173Void TComYuv::copyToPartComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
[313]174{
[1313]175  const Pel* pSrc     = getAddr(compID);
176        Pel* pDst     = pcYuvDst->getAddr( compID, uiDstPartIdx );
[313]177
[1313]178  const UInt iSrcStride  = getStride(compID);
179  const UInt iDstStride  = pcYuvDst->getStride(compID);
180  const Int  iWidth=getWidth(compID);
181  const Int  iHeight=getHeight(compID);
[1029]182
183  for (Int y = iHeight; y != 0; y-- )
[313]184  {
[1029]185    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
[313]186    pDst += iDstStride;
187    pSrc += iSrcStride;
188  }
189}
190
[1029]191
192
193
194Void TComYuv::copyPartToYuv( TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
[313]195{
[1313]196  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[1246]197  {
[1313]198    copyPartToComponent  ( ComponentID(comp), pcYuvDst, uiSrcPartIdx );
[1246]199  }
[313]200}
201
[1313]202Void TComYuv::copyPartToComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
[313]203{
[1313]204  const Pel* pSrc     = getAddr(compID, uiSrcPartIdx);
205        Pel* pDst     = pcYuvDst->getAddr(compID, 0 );
[313]206
[1313]207  const UInt  iSrcStride  = getStride(compID);
208  const UInt  iDstStride  = pcYuvDst->getStride(compID);
[1029]209
[1313]210  const UInt uiHeight = pcYuvDst->getHeight(compID);
211  const UInt uiWidth = pcYuvDst->getWidth(compID);
[1029]212
213  for ( UInt y = uiHeight; y != 0; y-- )
[313]214  {
215    ::memcpy( pDst, pSrc, sizeof(Pel)*uiWidth);
216    pDst += iDstStride;
217    pSrc += iSrcStride;
218  }
219}
220
221
[1029]222
223
224Void TComYuv::copyPartToPartYuv   ( TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidth, const UInt iHeight ) const
[313]225{
[1313]226  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[1246]227  {
[1313]228    copyPartToPartComponent   (ComponentID(comp), pcYuvDst, uiPartIdx, iWidth>>getComponentScaleX(ComponentID(comp)), iHeight>>getComponentScaleY(ComponentID(comp)) );
[1246]229  }
[313]230}
231
[1313]232Void TComYuv::copyPartToPartComponent  ( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidthComponent, const UInt iHeightComponent ) const
[313]233{
[1315]234  const Pel* pSrc =           getAddr(compID, uiPartIdx);
[1313]235        Pel* pDst = pcYuvDst->getAddr(compID, uiPartIdx);
[313]236  if( pSrc == pDst )
237  {
238    //th not a good idea
[1029]239    //th best would be to fix the caller
[313]240    return ;
241  }
[1029]242
[1313]243  const UInt  iSrcStride = getStride(compID);
244  const UInt  iDstStride = pcYuvDst->getStride(compID);
[1029]245  for ( UInt y = iHeightComponent; y != 0; y-- )
[313]246  {
[1029]247    ::memcpy( pDst, pSrc, iWidthComponent * sizeof(Pel) );
[313]248    pSrc += iSrcStride;
249    pDst += iDstStride;
250  }
251}
252
[1029]253
254
255
[1313]256Void TComYuv::copyPartToPartComponentMxN  ( const ComponentID compID, TComYuv* pcYuvDst, const TComRectangle &rect) const
[313]257{
[1313]258  const Pel* pSrc =           getAddrPix( compID, rect.x0, rect.y0 );
259        Pel* pDst = pcYuvDst->getAddrPix( compID, rect.x0, rect.y0 );
[1029]260  if( pSrc == pDst )
[313]261  {
262    //th not a good idea
[1029]263    //th best would be to fix the caller
[313]264    return ;
265  }
[1029]266
[1313]267  const UInt  iSrcStride = getStride(compID);
268  const UInt  iDstStride = pcYuvDst->getStride(compID);
[1029]269  const UInt uiHeightComponent=rect.height;
270  const UInt uiWidthComponent=rect.width;
271  for ( UInt y = uiHeightComponent; y != 0; y-- )
[313]272  {
[1029]273    ::memcpy( pDst, pSrc, uiWidthComponent * sizeof( Pel ) );
274    pSrc += iSrcStride;
275    pDst += iDstStride;
[313]276  }
277}
278
[1029]279
280
281
[1287]282Void TComYuv::addClip( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize, const BitDepths &clipBitDepths )
[313]283{
[1313]284  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[313]285  {
[1313]286    const ComponentID compID=ComponentID(comp);
287    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
288    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
[1029]289
[1313]290    const Pel* pSrc0 = pcYuvSrc0->getAddr(compID, uiTrUnitIdx, uiPartWidth );
291    const Pel* pSrc1 = pcYuvSrc1->getAddr(compID, uiTrUnitIdx, uiPartWidth );
292          Pel* pDst  = getAddr(compID, uiTrUnitIdx, uiPartWidth );
[1029]293
[1313]294    const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
295    const UInt iSrc1Stride = pcYuvSrc1->getStride(compID);
296    const UInt iDstStride  = getStride(compID);
297    const Int clipbd = clipBitDepths.recon[toChannelType(compID)];
[1029]298#if O0043_BEST_EFFORT_DECODING
[1313]299    const Int bitDepthDelta = clipBitDepths.stream[toChannelType(compID)] - clipbd;
[1029]300#endif
301
302    for ( Int y = uiPartHeight-1; y >= 0; y-- )
[313]303    {
[1029]304      for ( Int x = uiPartWidth-1; x >= 0; x-- )
305      {
306#if O0043_BEST_EFFORT_DECODING
307        pDst[x] = Pel(ClipBD<Int>( Int(pSrc0[x]) + rightShiftEvenRounding<Pel>(pSrc1[x], bitDepthDelta), clipbd));
308#else
309        pDst[x] = Pel(ClipBD<Int>( Int(pSrc0[x]) + Int(pSrc1[x]), clipbd));
310#endif
311      }
312      pSrc0 += iSrc0Stride;
313      pSrc1 += iSrc1Stride;
314      pDst  += iDstStride;
[313]315    }
316  }
317}
318
319
[1029]320
321
322Void TComYuv::subtract( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize )
[313]323{
[1313]324  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[313]325  {
[1313]326    const ComponentID compID=ComponentID(comp);
327    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
328    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
[313]329
[1313]330    const Pel* pSrc0 = pcYuvSrc0->getAddr( compID, uiTrUnitIdx, uiPartWidth );
331    const Pel* pSrc1 = pcYuvSrc1->getAddr( compID, uiTrUnitIdx, uiPartWidth );
332          Pel* pDst  = getAddr( compID, uiTrUnitIdx, uiPartWidth );
[1029]333
[1313]334    const Int  iSrc0Stride = pcYuvSrc0->getStride(compID);
335    const Int  iSrc1Stride = pcYuvSrc1->getStride(compID);
336    const Int  iDstStride  = getStride(compID);
[1029]337
338    for (Int y = uiPartHeight-1; y >= 0; y-- )
[313]339    {
[1029]340      for (Int x = uiPartWidth-1; x >= 0; x-- )
341      {
342        pDst[x] = pSrc0[x] - pSrc1[x];
343      }
344      pSrc0 += iSrc0Stride;
345      pSrc1 += iSrc1Stride;
346      pDst  += iDstStride;
[313]347    }
348  }
349}
350
351
[1029]352
353
[1287]354Void TComYuv::addAvg( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt iPartUnitIdx, const UInt uiWidth, const UInt uiHeight, const BitDepths &clipBitDepths )
[313]355{
[1313]356  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[313]357  {
[1313]358    const ComponentID compID=ComponentID(comp);
359    const Pel* pSrc0  = pcYuvSrc0->getAddr( compID, iPartUnitIdx );
360    const Pel* pSrc1  = pcYuvSrc1->getAddr( compID, iPartUnitIdx );
361    Pel* pDst   = getAddr( compID, iPartUnitIdx );
[313]362
[1313]363    const UInt  iSrc0Stride = pcYuvSrc0->getStride(compID);
364    const UInt  iSrc1Stride = pcYuvSrc1->getStride(compID);
365    const UInt  iDstStride  = getStride(compID);
366    const Int   clipbd      = clipBitDepths.recon[toChannelType(compID)];
[1029]367    const Int   shiftNum    = std::max<Int>(2, (IF_INTERNAL_PREC - clipbd)) + 1;
368    const Int   offset      = ( 1 << ( shiftNum - 1 ) ) + 2 * IF_INTERNAL_OFFS;
369
[1313]370    const Int   iWidth      = uiWidth  >> getComponentScaleX(compID);
371    const Int   iHeight     = uiHeight >> getComponentScaleY(compID);
[1029]372
373    if (iWidth&1)
[313]374    {
[1029]375      assert(0);
376      exit(-1);
[313]377    }
[1029]378    else if (iWidth&2)
[313]379    {
[1029]380      for ( Int y = 0; y < iHeight; y++ )
381      {
382        for (Int x=0 ; x < iWidth; x+=2 )
383        {
384          pDst[ x + 0 ] = ClipBD( rightShift(( pSrc0[ x + 0 ] + pSrc1[ x + 0 ] + offset ), shiftNum), clipbd );
385          pDst[ x + 1 ] = ClipBD( rightShift(( pSrc0[ x + 1 ] + pSrc1[ x + 1 ] + offset ), shiftNum), clipbd );
386        }
387        pSrc0 += iSrc0Stride;
388        pSrc1 += iSrc1Stride;
389        pDst  += iDstStride;
390      }
[313]391    }
[1029]392    else
[313]393    {
[1029]394      for ( Int y = 0; y < iHeight; y++ )
395      {
396        for (Int x=0 ; x < iWidth; x+=4 )
397        {
398          pDst[ x + 0 ] = ClipBD( rightShift(( pSrc0[ x + 0 ] + pSrc1[ x + 0 ] + offset ), shiftNum), clipbd );
399          pDst[ x + 1 ] = ClipBD( rightShift(( pSrc0[ x + 1 ] + pSrc1[ x + 1 ] + offset ), shiftNum), clipbd );
400          pDst[ x + 2 ] = ClipBD( rightShift(( pSrc0[ x + 2 ] + pSrc1[ x + 2 ] + offset ), shiftNum), clipbd );
401          pDst[ x + 3 ] = ClipBD( rightShift(( pSrc0[ x + 3 ] + pSrc1[ x + 3 ] + offset ), shiftNum), clipbd );
402        }
403        pSrc0 += iSrc0Stride;
404        pSrc1 += iSrc1Stride;
405        pDst  += iDstStride;
406      }
[313]407    }
408  }
409}
410
[1313]411Void TComYuv::removeHighFreq( const TComYuv* pcYuvSrc,
412                              const UInt uiPartIdx,
413                              const UInt uiWidth,
[1324]414                              const UInt uiHeight,
415                              const Int bitDepths[MAX_NUM_CHANNEL_TYPE],
416                              const Bool bClipToBitDepths
[1313]417                              )
[313]418{
[1313]419  for(Int comp=0; comp<getNumberValidComponents(); comp++)
[313]420  {
[1313]421    const ComponentID compID=ComponentID(comp);
422    const Pel* pSrc  = pcYuvSrc->getAddr(compID, uiPartIdx);
423    Pel* pDst  = getAddr(compID, uiPartIdx);
[1029]424
[1313]425    const Int iSrcStride = pcYuvSrc->getStride(compID);
426    const Int iDstStride = getStride(compID);
427    const Int iWidth  = uiWidth >>getComponentScaleX(compID);
428    const Int iHeight = uiHeight>>getComponentScaleY(compID);
[1324]429    if (bClipToBitDepths)
[313]430    {
[1324]431      const Int clipBd=bitDepths[toChannelType(compID)];
432      for ( Int y = iHeight-1; y >= 0; y-- )
[1029]433      {
[1324]434        for ( Int x = iWidth-1; x >= 0; x-- )
435        {
436          pDst[x ] = ClipBD((2 * pDst[x]) - pSrc[x], clipBd);
437        }
438        pSrc += iSrcStride;
439        pDst += iDstStride;
[1029]440      }
[313]441    }
[1324]442    else
443    {
444      for ( Int y = iHeight-1; y >= 0; y-- )
445      {
446        for ( Int x = iWidth-1; x >= 0; x-- )
447        {
448          pDst[x ] = (2 * pDst[x]) - pSrc[x];
449        }
450        pSrc += iSrcStride;
451        pDst += iDstStride;
452      }
453    }
[313]454  }
455}
[1029]456
[313]457//! \}
Note: See TracBrowser for help on using the repository browser.