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

Last change on this file since 1348 was 1324, checked in by seregin, 9 years ago

port rev 4402

  • Property svn:eol-style set to native
File size: 14.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-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 comp=0; comp<MAX_NUM_COMPONENT; comp++)
71  {
72    // memory allocation
73    m_apiBuf[comp]  = (Pel*)xMalloc( Pel, getWidth(ComponentID(comp))*getHeight(ComponentID(comp)) );
74  }
75}
76
77Void TComYuv::destroy()
78{
79  // memory free
80  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
81  {
82    if (m_apiBuf[comp]!=NULL)
83    {
84      xFree( m_apiBuf[comp] );
85      m_apiBuf[comp] = NULL;
86    }
87  }
88}
89
90Void TComYuv::clear()
91{
92  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
93  {
94    if (m_apiBuf[comp]!=NULL)
95    {
96      ::memset( m_apiBuf[comp], 0, ( getWidth(ComponentID(comp)) * getHeight(ComponentID(comp))  )*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 comp=0; comp<getNumberValidComponents(); comp++)
107  {
108    copyToPicComponent  ( ComponentID(comp), pcPicYuvDst, ctuRsAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx );
109  }
110}
111
112Void TComYuv::copyToPicComponent  ( const ComponentID compID, TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
113{
114  const Int iWidth  = getWidth(compID) >>uiPartDepth;
115  const Int iHeight = getHeight(compID)>>uiPartDepth;
116
117  const Pel* pSrc     = getAddr(compID, uiPartIdx, iWidth);
118        Pel* pDst     = pcPicYuvDst->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
119
120  const UInt  iSrcStride  = getStride(compID);
121  const UInt  iDstStride  = pcPicYuvDst->getStride(compID);
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 comp=0; comp<getNumberValidComponents(); comp++)
137  {
138    copyFromPicComponent  ( ComponentID(comp), pcPicYuvSrc, ctuRsAddr, uiAbsZorderIdx );
139  }
140}
141
142Void TComYuv::copyFromPicComponent  ( const ComponentID compID, const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
143{
144        Pel* pDst     = getAddr(compID);
145  const Pel* pSrc     = pcPicYuvSrc->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
146
147  const UInt iDstStride  = getStride(compID);
148  const UInt iSrcStride  = pcPicYuvSrc->getStride(compID);
149  const Int  iWidth=getWidth(compID);
150  const Int  iHeight=getHeight(compID);
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 comp=0; comp<getNumberValidComponents(); comp++)
166  {
167    copyToPartComponent  ( ComponentID(comp), pcYuvDst, uiDstPartIdx );
168  }
169}
170
171Void TComYuv::copyToPartComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
172{
173  const Pel* pSrc     = getAddr(compID);
174        Pel* pDst     = pcYuvDst->getAddr( compID, uiDstPartIdx );
175
176  const UInt iSrcStride  = getStride(compID);
177  const UInt iDstStride  = pcYuvDst->getStride(compID);
178  const Int  iWidth=getWidth(compID);
179  const Int  iHeight=getHeight(compID);
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 comp=0; comp<getNumberValidComponents(); comp++)
195  {
196    copyPartToComponent  ( ComponentID(comp), pcYuvDst, uiSrcPartIdx );
197  }
198}
199
200Void TComYuv::copyPartToComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
201{
202  const Pel* pSrc     = getAddr(compID, uiSrcPartIdx);
203        Pel* pDst     = pcYuvDst->getAddr(compID, 0 );
204
205  const UInt  iSrcStride  = getStride(compID);
206  const UInt  iDstStride  = pcYuvDst->getStride(compID);
207
208  const UInt uiHeight = pcYuvDst->getHeight(compID);
209  const UInt uiWidth = pcYuvDst->getWidth(compID);
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 comp=0; comp<getNumberValidComponents(); comp++)
225  {
226    copyPartToPartComponent   (ComponentID(comp), pcYuvDst, uiPartIdx, iWidth>>getComponentScaleX(ComponentID(comp)), iHeight>>getComponentScaleY(ComponentID(comp)) );
227  }
228}
229
230Void TComYuv::copyPartToPartComponent  ( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidthComponent, const UInt iHeightComponent ) const
231{
232  const Pel* pSrc =           getAddr(compID, uiPartIdx);
233        Pel* pDst = pcYuvDst->getAddr(compID, 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(compID);
242  const UInt  iDstStride = pcYuvDst->getStride(compID);
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 compID, TComYuv* pcYuvDst, const TComRectangle &rect) const
255{
256  const Pel* pSrc =           getAddrPix( compID, rect.x0, rect.y0 );
257        Pel* pDst = pcYuvDst->getAddrPix( compID, 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(compID);
266  const UInt  iDstStride = pcYuvDst->getStride(compID);
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 comp=0; comp<getNumberValidComponents(); comp++)
283  {
284    const ComponentID compID=ComponentID(comp);
285    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
286    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
287
288    const Pel* pSrc0 = pcYuvSrc0->getAddr(compID, uiTrUnitIdx, uiPartWidth );
289    const Pel* pSrc1 = pcYuvSrc1->getAddr(compID, uiTrUnitIdx, uiPartWidth );
290          Pel* pDst  = getAddr(compID, uiTrUnitIdx, uiPartWidth );
291
292    const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
293    const UInt iSrc1Stride = pcYuvSrc1->getStride(compID);
294    const UInt iDstStride  = getStride(compID);
295    const Int clipbd = clipBitDepths.recon[toChannelType(compID)];
296#if O0043_BEST_EFFORT_DECODING
297    const Int bitDepthDelta = clipBitDepths.stream[toChannelType(compID)] - 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 comp=0; comp<getNumberValidComponents(); comp++)
323  {
324    const ComponentID compID=ComponentID(comp);
325    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
326    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
327
328    const Pel* pSrc0 = pcYuvSrc0->getAddr( compID, uiTrUnitIdx, uiPartWidth );
329    const Pel* pSrc1 = pcYuvSrc1->getAddr( compID, uiTrUnitIdx, uiPartWidth );
330          Pel* pDst  = getAddr( compID, uiTrUnitIdx, uiPartWidth );
331
332    const Int  iSrc0Stride = pcYuvSrc0->getStride(compID);
333    const Int  iSrc1Stride = pcYuvSrc1->getStride(compID);
334    const Int  iDstStride  = getStride(compID);
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 comp=0; comp<getNumberValidComponents(); comp++)
355  {
356    const ComponentID compID=ComponentID(comp);
357    const Pel* pSrc0  = pcYuvSrc0->getAddr( compID, iPartUnitIdx );
358    const Pel* pSrc1  = pcYuvSrc1->getAddr( compID, iPartUnitIdx );
359    Pel* pDst   = getAddr( compID, iPartUnitIdx );
360
361    const UInt  iSrc0Stride = pcYuvSrc0->getStride(compID);
362    const UInt  iSrc1Stride = pcYuvSrc1->getStride(compID);
363    const UInt  iDstStride  = getStride(compID);
364    const Int   clipbd      = clipBitDepths.recon[toChannelType(compID)];
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(compID);
369    const Int   iHeight     = uiHeight >> getComponentScaleY(compID);
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,
410                              const UInt uiPartIdx,
411                              const UInt uiWidth,
412                              const UInt uiHeight,
413                              const Int bitDepths[MAX_NUM_CHANNEL_TYPE],
414                              const Bool bClipToBitDepths
415                              )
416{
417  for(Int comp=0; comp<getNumberValidComponents(); comp++)
418  {
419    const ComponentID compID=ComponentID(comp);
420    const Pel* pSrc  = pcYuvSrc->getAddr(compID, uiPartIdx);
421    Pel* pDst  = getAddr(compID, uiPartIdx);
422
423    const Int iSrcStride = pcYuvSrc->getStride(compID);
424    const Int iDstStride = getStride(compID);
425    const Int iWidth  = uiWidth >>getComponentScaleX(compID);
426    const Int iHeight = uiHeight>>getComponentScaleY(compID);
427    if (bClipToBitDepths)
428    {
429      const Int clipBd=bitDepths[toChannelType(compID)];
430      for ( Int y = iHeight-1; y >= 0; y-- )
431      {
432        for ( Int x = iWidth-1; x >= 0; x-- )
433        {
434          pDst[x ] = ClipBD((2 * pDst[x]) - pSrc[x], clipBd);
435        }
436        pSrc += iSrcStride;
437        pDst += iDstStride;
438      }
439    }
440    else
441    {
442      for ( Int y = iHeight-1; y >= 0; y-- )
443      {
444        for ( Int x = iWidth-1; x >= 0; x-- )
445        {
446          pDst[x ] = (2 * pDst[x]) - pSrc[x];
447        }
448        pSrc += iSrcStride;
449        pDst += iDstStride;
450      }
451    }
452  }
453}
454
455//! \}
Note: See TracBrowser for help on using the repository browser.