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

Last change on this file since 1166 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
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-2014, 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}
62
63Void TComYuv::create( UInt iWidth, UInt iHeight, ChromaFormat chromaFormatIDC )
64{
65  // set width and height
66  m_iWidth   = iWidth;
67  m_iHeight  = iHeight;
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  }
75}
76
77Void TComYuv::destroy()
78{
79  // memory free
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  }
84}
85
86Void TComYuv::clear()
87{
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  }
93}
94
95
96
97
98Void TComYuv::copyToPicYuv   ( TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
99{
100  for(Int ch=0; ch<getNumberValidComponents(); ch++)
101    copyToPicComponent  ( ComponentID(ch), pcPicYuvDst, ctuRsAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx );
102}
103
104Void TComYuv::copyToPicComponent  ( const ComponentID ch, TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
105{
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-- )
116  {
117    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
118    pDst += iDstStride;
119    pSrc += iSrcStride;
120  }
121}
122
123
124
125
126Void TComYuv::copyFromPicYuv   ( const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
127{
128  for(Int ch=0; ch<getNumberValidComponents(); ch++)
129    copyFromPicComponent  ( ComponentID(ch), pcPicYuvSrc, ctuRsAddr, uiAbsZorderIdx );
130}
131
132Void TComYuv::copyFromPicComponent  ( const ComponentID ch, const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
133{
134        Pel* pDst     = getAddr(ch);
135  const Pel* pSrc     = pcPicYuvSrc->getAddr ( ch, ctuRsAddr, uiAbsZorderIdx );
136
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-- )
143  {
144    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
145    pDst += iDstStride;
146    pSrc += iSrcStride;
147  }
148}
149
150
151
152
153Void TComYuv::copyToPartYuv( TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
154{
155  for(Int ch=0; ch<getNumberValidComponents(); ch++)
156    copyToPartComponent  ( ComponentID(ch), pcYuvDst, uiDstPartIdx );
157}
158
159Void TComYuv::copyToPartComponent( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
160{
161  const Pel* pSrc     = getAddr(ch);
162        Pel* pDst     = pcYuvDst->getAddr( ch, uiDstPartIdx );
163
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-- )
170  {
171    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
172    pDst += iDstStride;
173    pSrc += iSrcStride;
174  }
175}
176
177
178
179
180Void TComYuv::copyPartToYuv( TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
181{
182  for(Int ch=0; ch<getNumberValidComponents(); ch++)
183    copyPartToComponent  ( ComponentID(ch), pcYuvDst, uiSrcPartIdx );
184}
185
186Void TComYuv::copyPartToComponent( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
187{
188  const Pel* pSrc     = getAddr(ch, uiSrcPartIdx);
189        Pel* pDst     = pcYuvDst->getAddr(ch, 0 );
190
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-- )
198  {
199    ::memcpy( pDst, pSrc, sizeof(Pel)*uiWidth);
200    pDst += iDstStride;
201    pSrc += iSrcStride;
202  }
203}
204
205
206
207
208Void TComYuv::copyPartToPartYuv   ( TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidth, const UInt iHeight ) const
209{
210  for(Int ch=0; ch<getNumberValidComponents(); ch++)
211    copyPartToPartComponent   (ComponentID(ch), pcYuvDst, uiPartIdx, iWidth>>getComponentScaleX(ComponentID(ch)), iHeight>>getComponentScaleY(ComponentID(ch)) );
212}
213
214Void TComYuv::copyPartToPartComponent  ( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidthComponent, const UInt iHeightComponent ) const
215{
216  const Pel* pSrc =           getAddr(ch, uiPartIdx);
217        Pel* pDst = pcYuvDst->getAddr(ch, uiPartIdx);
218  if( pSrc == pDst )
219  {
220    //th not a good idea
221    //th best would be to fix the caller
222    return ;
223  }
224
225  const UInt  iSrcStride = getStride(ch);
226  const UInt  iDstStride = pcYuvDst->getStride(ch);
227  for ( UInt y = iHeightComponent; y != 0; y-- )
228  {
229    ::memcpy( pDst, pSrc, iWidthComponent * sizeof(Pel) );
230    pSrc += iSrcStride;
231    pDst += iDstStride;
232  }
233}
234
235
236
237
238Void TComYuv::copyPartToPartComponentMxN  ( const ComponentID ch, TComYuv* pcYuvDst, const TComRectangle &rect) const
239{
240  const Pel* pSrc =           getAddrPix( ch, rect.x0, rect.y0 );
241        Pel* pDst = pcYuvDst->getAddrPix( ch, rect.x0, rect.y0 );
242  if( pSrc == pDst )
243  {
244    //th not a good idea
245    //th best would be to fix the caller
246    return ;
247  }
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-- )
254  {
255    ::memcpy( pDst, pSrc, uiWidthComponent * sizeof( Pel ) );
256    pSrc += iSrcStride;
257    pDst += iDstStride;
258  }
259}
260
261
262
263
264Void TComYuv::addClip( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize )
265{
266  for(Int chan=0; chan<getNumberValidComponents(); chan++)
267  {
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-- )
285    {
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;
297    }
298  }
299}
300
301
302
303
304Void TComYuv::subtract( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize )
305{
306  for(Int chan=0; chan<getNumberValidComponents(); chan++)
307  {
308    const ComponentID ch=ComponentID(chan);
309    const Int uiPartWidth =uiPartSize>>getComponentScaleX(ch);
310    const Int uiPartHeight=uiPartSize>>getComponentScaleY(ch);
311
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-- )
321    {
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;
329    }
330  }
331}
332
333
334
335
336Void TComYuv::addAvg( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt iPartUnitIdx, const UInt uiWidth, const UInt uiHeight )
337{
338  for(Int chan=0; chan<getNumberValidComponents(); chan++)
339  {
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 );
344
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)
356    {
357      assert(0);
358      exit(-1);
359    }
360    else if (iWidth&2)
361    {
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      }
373    }
374    else
375    {
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      }
389    }
390  }
391}
392
393Void TComYuv::removeHighFreq( const TComYuv* pcYuvSrc, const UInt uiPartIdx, const UInt uiWidth, UInt const uiHeight )
394{
395  for(Int chan=0; chan<getNumberValidComponents(); chan++)
396  {
397    const ComponentID ch=ComponentID(chan);
398#if !DISABLING_CLIP_FOR_BIPREDME
399    const ChannelType chType=toChannelType(ch);
400#endif
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-- )
411    {
412      for ( Int x = iWidth-1; x >= 0; x-- )
413      {
414#if DISABLING_CLIP_FOR_BIPREDME
415        pDst[x ] = (2 * pDst[x]) - pSrc[x];
416#else
417        pDst[x ] = Clip((2 * pDst[x]) - pSrc[x], chType);
418#endif
419      }
420      pSrc += iSrcStride;
421      pDst += iDstStride;
422    }
423  }
424}
425
426//! \}
Note: See TracBrowser for help on using the repository browser.