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

Last change on this file since 1309 was 1287, checked in by seregin, 9 years ago

port rev 4322 (g_bitDepth)

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