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

Last change on this file since 1550 was 1549, checked in by seregin, 9 years ago

port rev 4732, update copyright notice to include 2016

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