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

Last change on this file since 1165 was 1029, checked in by seregin, 10 years ago

merge with SHM-upgrade branch

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