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

Last change on this file since 1302 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
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-2015, 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)
83    {
84      xFree( m_apiBuf[ch] );
85      m_apiBuf[ch] = NULL;
86    }
87  }
88}
89
90Void TComYuv::clear()
91{
92  for(Int ch=0; ch<MAX_NUM_COMPONENT; ch++)
93  {
94    if (m_apiBuf[ch]!=NULL)
95    {
96      ::memset( m_apiBuf[ch], 0, ( getWidth(ComponentID(ch)) * getHeight(ComponentID(ch))  )*sizeof(Pel) );
97    }
98  }
99}
100
101
102
103
104Void TComYuv::copyToPicYuv   ( TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
105{
106  for(Int ch=0; ch<getNumberValidComponents(); ch++)
107  {
108    copyToPicComponent  ( ComponentID(ch), pcPicYuvDst, ctuRsAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx );
109  }
110}
111
112Void TComYuv::copyToPicComponent  ( const ComponentID ch, TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
113{
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-- )
124  {
125    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
126    pDst += iDstStride;
127    pSrc += iSrcStride;
128  }
129}
130
131
132
133
134Void TComYuv::copyFromPicYuv   ( const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
135{
136  for(Int ch=0; ch<getNumberValidComponents(); ch++)
137  {
138    copyFromPicComponent  ( ComponentID(ch), pcPicYuvSrc, ctuRsAddr, uiAbsZorderIdx );
139  }
140}
141
142Void TComYuv::copyFromPicComponent  ( const ComponentID ch, const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
143{
144        Pel* pDst     = getAddr(ch);
145  const Pel* pSrc     = pcPicYuvSrc->getAddr ( ch, ctuRsAddr, uiAbsZorderIdx );
146
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-- )
153  {
154    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
155    pDst += iDstStride;
156    pSrc += iSrcStride;
157  }
158}
159
160
161
162
163Void TComYuv::copyToPartYuv( TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
164{
165  for(Int ch=0; ch<getNumberValidComponents(); ch++)
166  {
167    copyToPartComponent  ( ComponentID(ch), pcYuvDst, uiDstPartIdx );
168  }
169}
170
171Void TComYuv::copyToPartComponent( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
172{
173  const Pel* pSrc     = getAddr(ch);
174        Pel* pDst     = pcYuvDst->getAddr( ch, uiDstPartIdx );
175
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-- )
182  {
183    ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth);
184    pDst += iDstStride;
185    pSrc += iSrcStride;
186  }
187}
188
189
190
191
192Void TComYuv::copyPartToYuv( TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
193{
194  for(Int ch=0; ch<getNumberValidComponents(); ch++)
195  {
196    copyPartToComponent  ( ComponentID(ch), pcYuvDst, uiSrcPartIdx );
197  }
198}
199
200Void TComYuv::copyPartToComponent( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
201{
202  const Pel* pSrc     = getAddr(ch, uiSrcPartIdx);
203        Pel* pDst     = pcYuvDst->getAddr(ch, 0 );
204
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-- )
212  {
213    ::memcpy( pDst, pSrc, sizeof(Pel)*uiWidth);
214    pDst += iDstStride;
215    pSrc += iSrcStride;
216  }
217}
218
219
220
221
222Void TComYuv::copyPartToPartYuv   ( TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidth, const UInt iHeight ) const
223{
224  for(Int ch=0; ch<getNumberValidComponents(); ch++)
225  {
226    copyPartToPartComponent   (ComponentID(ch), pcYuvDst, uiPartIdx, iWidth>>getComponentScaleX(ComponentID(ch)), iHeight>>getComponentScaleY(ComponentID(ch)) );
227  }
228}
229
230Void TComYuv::copyPartToPartComponent  ( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidthComponent, const UInt iHeightComponent ) const
231{
232  const Pel* pSrc =           getAddr(ch, uiPartIdx);
233        Pel* pDst = pcYuvDst->getAddr(ch, uiPartIdx);
234  if( pSrc == pDst )
235  {
236    //th not a good idea
237    //th best would be to fix the caller
238    return ;
239  }
240
241  const UInt  iSrcStride = getStride(ch);
242  const UInt  iDstStride = pcYuvDst->getStride(ch);
243  for ( UInt y = iHeightComponent; y != 0; y-- )
244  {
245    ::memcpy( pDst, pSrc, iWidthComponent * sizeof(Pel) );
246    pSrc += iSrcStride;
247    pDst += iDstStride;
248  }
249}
250
251
252
253
254Void TComYuv::copyPartToPartComponentMxN  ( const ComponentID ch, TComYuv* pcYuvDst, const TComRectangle &rect) const
255{
256  const Pel* pSrc =           getAddrPix( ch, rect.x0, rect.y0 );
257        Pel* pDst = pcYuvDst->getAddrPix( ch, rect.x0, rect.y0 );
258  if( pSrc == pDst )
259  {
260    //th not a good idea
261    //th best would be to fix the caller
262    return ;
263  }
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-- )
270  {
271    ::memcpy( pDst, pSrc, uiWidthComponent * sizeof( Pel ) );
272    pSrc += iSrcStride;
273    pDst += iDstStride;
274  }
275}
276
277
278
279
280Void TComYuv::addClip( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize, const BitDepths &clipBitDepths )
281{
282  for(Int chan=0; chan<getNumberValidComponents(); chan++)
283  {
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);
295    const Int clipbd = clipBitDepths.recon[toChannelType(ch)];
296#if O0043_BEST_EFFORT_DECODING
297    const Int bitDepthDelta = clipBitDepths.stream[toChannelType(ch)] - clipbd;
298#endif
299
300    for ( Int y = uiPartHeight-1; y >= 0; y-- )
301    {
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    }
314  }
315}
316
317
318
319
320Void TComYuv::subtract( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize )
321{
322  for(Int chan=0; chan<getNumberValidComponents(); chan++)
323  {
324    const ComponentID ch=ComponentID(chan);
325    const Int uiPartWidth =uiPartSize>>getComponentScaleX(ch);
326    const Int uiPartHeight=uiPartSize>>getComponentScaleY(ch);
327
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-- )
337    {
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;
345    }
346  }
347}
348
349
350
351
352Void TComYuv::addAvg( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt iPartUnitIdx, const UInt uiWidth, const UInt uiHeight, const BitDepths &clipBitDepths )
353{
354  for(Int chan=0; chan<getNumberValidComponents(); chan++)
355  {
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 );
360
361    const UInt  iSrc0Stride = pcYuvSrc0->getStride(ch);
362    const UInt  iSrc1Stride = pcYuvSrc1->getStride(ch);
363    const UInt  iDstStride  = getStride(ch);
364    const Int   clipbd      = clipBitDepths.recon[toChannelType(ch)];
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)
372    {
373      assert(0);
374      exit(-1);
375    }
376    else if (iWidth&2)
377    {
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      }
389    }
390    else
391    {
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      }
405    }
406  }
407}
408
409Void TComYuv::removeHighFreq( const TComYuv* pcYuvSrc, const UInt uiPartIdx, const UInt uiWidth, UInt const uiHeight )
410{
411  for(Int chan=0; chan<getNumberValidComponents(); chan++)
412  {
413    const ComponentID ch=ComponentID(chan);
414#if !DISABLING_CLIP_FOR_BIPREDME
415    const ChannelType chType=toChannelType(ch);
416#endif
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-- )
427    {
428      for ( Int x = iWidth-1; x >= 0; x-- )
429      {
430#if DISABLING_CLIP_FOR_BIPREDME
431        pDst[x ] = (2 * pDst[x]) - pSrc[x];
432#else
433        pDst[x ] = Clip((2 * pDst[x]) - pSrc[x], chType);
434#endif
435      }
436      pSrc += iSrcStride;
437      pDst += iDstStride;
438    }
439  }
440}
441
442//! \}
Note: See TracBrowser for help on using the repository browser.