source: 3DVCSoftware/branches/HTM-14.1-update-dev1-MediaTek/source/Lib/TLibCommon/TComPicYuv.cpp @ 1253

Last change on this file since 1253 was 1200, checked in by tech, 9 years ago

Update to HM-16.5.
Starting point for further re-activation of 3D-tools.

Includes:

active:

  • MV-HEVC
  • 3D-HLS (apart from DLT)
  • VSO

inactive:

  • remaining 3D-HEVC tools.
  • Property svn:eol-style set to native
File size: 10.9 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     TComPicYuv.cpp
35    \brief    picture YUV buffer class
36*/
37
38#include <cstdlib>
39#include <assert.h>
40#include <memory.h>
41
42#ifdef __APPLE__
43#include <malloc/malloc.h>
44#else
45#include <malloc.h>
46#endif
47
48#include "TComPicYuv.h"
49#include "TLibVideoIO/TVideoIOYuv.h"
50
51//! \ingroup TLibCommon
52//! \{
53
54TComPicYuv::TComPicYuv()
55{
56  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
57  {
58    m_apiPicBuf[i]    = NULL;   // Buffer (including margin)
59    m_piPicOrg[i]     = NULL;    // m_apiPicBufY + m_iMarginLuma*getStride() + m_iMarginLuma
60  }
61
62  for(UInt i=0; i<MAX_NUM_CHANNEL_TYPE; i++)
63  {
64    m_ctuOffsetInBuffer[i]=0;
65    m_subCuOffsetInBuffer[i]=0;
66  }
67
68  m_bIsBorderExtended = false;
69}
70
71
72
73
74TComPicYuv::~TComPicYuv()
75{
76}
77
78
79
80
81Void TComPicYuv::create ( const Int iPicWidth,                ///< picture width
82                          const Int iPicHeight,               ///< picture height
83                          const ChromaFormat chromaFormatIDC, ///< chroma format
84                          const UInt uiMaxCUWidth,            ///< used for generating offsets to CUs. Can use iPicWidth if no offsets are required
85                          const UInt uiMaxCUHeight,           ///< used for generating offsets to CUs. Can use iPicHeight if no offsets are required
86                          const UInt uiMaxCUDepth,            ///< used for generating offsets to CUs. Can use 0 if no offsets are required
87                          const Bool bUseMargin)              ///< if true, then a margin of uiMaxCUWidth+16 and uiMaxCUHeight+16 is created around the image.
88
89{
90  m_iPicWidth         = iPicWidth;
91  m_iPicHeight        = iPicHeight;
92
93#if H_3D_IV_MERGE
94  m_iNumCuInWidth   = m_iPicWidth / m_iCuWidth;
95  m_iNumCuInWidth  += ( m_iPicWidth % m_iCuWidth ) ? 1 : 0;
96
97  m_iBaseUnitWidth  = uiMaxCUWidth  >> uiMaxCUDepth;
98  m_iBaseUnitHeight = uiMaxCUHeight >> uiMaxCUDepth;
99#endif
100
101  m_chromaFormatIDC   = chromaFormatIDC;
102  m_iMarginX          = (bUseMargin?uiMaxCUWidth:0) + 16;   // for 16-byte alignment
103  m_iMarginY          = (bUseMargin?uiMaxCUHeight:0) + 16;  // margin for 8-tap filter and infinite padding
104  m_bIsBorderExtended = false;
105
106  // assign the picture arrays and set up the ptr to the top left of the original picture
107  {
108    Int chan=0;
109    for(; chan<getNumberValidComponents(); chan++)
110    {
111      const ComponentID ch=ComponentID(chan);
112      m_apiPicBuf[chan] = (Pel*)xMalloc( Pel, getStride(ch)       * getTotalHeight(ch));
113      m_piPicOrg[chan]  = m_apiPicBuf[chan] + (m_iMarginY >> getComponentScaleY(ch))   * getStride(ch)       + (m_iMarginX >> getComponentScaleX(ch));
114    }
115    for(;chan<MAX_NUM_COMPONENT; chan++)
116    {
117      m_apiPicBuf[chan] = NULL;
118      m_piPicOrg[chan]  = NULL;
119    }
120  }
121
122
123  const Int numCuInWidth  = m_iPicWidth  / uiMaxCUWidth  + (m_iPicWidth  % uiMaxCUWidth  != 0);
124  const Int numCuInHeight = m_iPicHeight / uiMaxCUHeight + (m_iPicHeight % uiMaxCUHeight != 0);
125  for(Int chan=0; chan<2; chan++)
126  {
127    const ComponentID ch=ComponentID(chan);
128    const Int ctuHeight=uiMaxCUHeight>>getComponentScaleY(ch);
129    const Int ctuWidth=uiMaxCUWidth>>getComponentScaleX(ch);
130    const Int stride = getStride(ch);
131
132    m_ctuOffsetInBuffer[chan] = new Int[numCuInWidth * numCuInHeight];
133
134    for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
135    {
136      for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
137      {
138        m_ctuOffsetInBuffer[chan][cuRow * numCuInWidth + cuCol] = stride * cuRow * ctuHeight + cuCol * ctuWidth;
139      }
140    }
141
142    m_subCuOffsetInBuffer[chan] = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
143
144    const Int numSubBlockPartitions=(1<<uiMaxCUDepth);
145    const Int minSubBlockHeight    =(ctuHeight >> uiMaxCUDepth);
146    const Int minSubBlockWidth     =(ctuWidth  >> uiMaxCUDepth);
147
148    for (Int buRow = 0; buRow < numSubBlockPartitions; buRow++)
149    {
150      for (Int buCol = 0; buCol < numSubBlockPartitions; buCol++)
151      {
152        m_subCuOffsetInBuffer[chan][(buRow << uiMaxCUDepth) + buCol] = stride  * buRow * minSubBlockHeight + buCol * minSubBlockWidth;
153      }
154    }
155  }
156  return;
157}
158
159
160
161Void TComPicYuv::destroy()
162{
163  for(Int chan=0; chan<MAX_NUM_COMPONENT; chan++)
164  {
165    m_piPicOrg[chan] = NULL;
166
167    if( m_apiPicBuf[chan] )
168    {
169      xFree( m_apiPicBuf[chan] );
170      m_apiPicBuf[chan] = NULL;
171    }
172  }
173
174  for(UInt chan=0; chan<MAX_NUM_CHANNEL_TYPE; chan++)
175  {
176    if (m_ctuOffsetInBuffer[chan])
177    {
178      delete[] m_ctuOffsetInBuffer[chan];
179      m_ctuOffsetInBuffer[chan] = NULL;
180    }
181    if (m_subCuOffsetInBuffer[chan])
182    {
183      delete[] m_subCuOffsetInBuffer[chan];
184      m_subCuOffsetInBuffer[chan] = NULL;
185    }
186  }
187}
188
189
190
191Void  TComPicYuv::copyToPic (TComPicYuv*  pcPicYuvDst) const
192{
193  assert( m_iPicWidth  == pcPicYuvDst->getWidth(COMPONENT_Y)  );
194  assert( m_iPicHeight == pcPicYuvDst->getHeight(COMPONENT_Y) );
195  assert( m_chromaFormatIDC == pcPicYuvDst->getChromaFormat() );
196
197  for(Int chan=0; chan<getNumberValidComponents(); chan++)
198  {
199    const ComponentID ch=ComponentID(chan);
200    ::memcpy ( pcPicYuvDst->getBuf(ch), m_apiPicBuf[ch], sizeof (Pel) * getStride(ch) * getTotalHeight(ch));
201  }
202  return;
203}
204
205
206Void TComPicYuv::extendPicBorder ()
207{
208  if ( m_bIsBorderExtended )
209  {
210    return;
211  }
212
213  for(Int chan=0; chan<getNumberValidComponents(); chan++)
214  {
215    const ComponentID ch=ComponentID(chan);
216    Pel *piTxt=getAddr(ch); // piTxt = point to (0,0) of image within bigger picture.
217    const Int iStride=getStride(ch);
218    const Int iWidth=getWidth(ch);
219    const Int iHeight=getHeight(ch);
220    const Int iMarginX=getMarginX(ch);
221    const Int iMarginY=getMarginY(ch);
222
223    Pel*  pi = piTxt;
224    // do left and right margins
225    for (Int y = 0; y < iHeight; y++)
226    {
227      for (Int x = 0; x < iMarginX; x++ )
228      {
229        pi[ -iMarginX + x ] = pi[0];
230        pi[    iWidth + x ] = pi[iWidth-1];
231      }
232      pi += iStride;
233    }
234
235    // pi is now the (0,height) (bottom left of image within bigger picture
236    pi -= (iStride + iMarginX);
237    // pi is now the (-marginX, height-1)
238    for (Int y = 0; y < iMarginY; y++ )
239    {
240      ::memcpy( pi + (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
241    }
242
243    // pi is still (-marginX, height-1)
244    pi -= ((iHeight-1) * iStride);
245    // pi is now (-marginX, 0)
246    for (Int y = 0; y < iMarginY; y++ )
247    {
248      ::memcpy( pi - (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
249    }
250  }
251
252  m_bIsBorderExtended = true;
253}
254
255
256
257// NOTE: This function is never called, but may be useful for developers.
258Void TComPicYuv::dump (const Char* pFileName, const BitDepths &bitDepths, Bool bAdd) const
259{
260  FILE* pFile;
261  if (!bAdd)
262  {
263    pFile = fopen (pFileName, "wb");
264  }
265  else
266  {
267    pFile = fopen (pFileName, "ab");
268  }
269
270
271  for(Int chan = 0; chan < getNumberValidComponents(); chan++)
272  {
273    const ComponentID  ch     = ComponentID(chan);
274    const Int          shift  = bitDepths.recon[toChannelType(ch)] - 8;
275    const Int          offset = (shift>0)?(1<<(shift-1)):0;
276    const Pel         *pi     = getAddr(ch);
277    const Int          stride = getStride(ch);
278    const Int          height = getHeight(ch);
279    const Int          width  = getWidth(ch);
280
281    for (Int y = 0; y < height; y++ )
282    {
283      for (Int x = 0; x < width; x++ )
284      {
285        UChar uc = (UChar)Clip3<Pel>(0, 255, (pi[x]+offset)>>shift);
286        fwrite( &uc, sizeof(UChar), 1, pFile );
287      }
288      pi += stride;
289    }
290  }
291
292  fclose(pFile);
293}
294#if H_3D
295#if H_3D_IV_MERGE
296Void
297TComPicYuv::getTopLeftSamplePos( Int iCuAddr, Int iAbsZorderIdx, Int& riX, Int& riY )
298{
299  Int iRastPartIdx    = g_auiZscanToRaster[iAbsZorderIdx];
300  Int iCuSizeInBases  = m_iCuWidth   / m_iBaseUnitWidth;
301  Int iCuX            = iCuAddr      % m_iNumCuInWidth;
302  Int iCuY            = iCuAddr      / m_iNumCuInWidth;
303  Int iBaseX          = iRastPartIdx % iCuSizeInBases;
304  Int iBaseY          = iRastPartIdx / iCuSizeInBases;
305  riX                 = iCuX * m_iCuWidth  + iBaseX * m_iBaseUnitWidth;
306  riY                 = iCuY * m_iCuHeight + iBaseY * m_iBaseUnitHeight; 
307}
308
309Void
310TComPicYuv::getCUAddrAndPartIdx( Int iX, Int iY, Int& riCuAddr, Int& riAbsZorderIdx )
311{
312  Int iCuX            = iX / m_iCuWidth;
313  Int iCuY            = iY / m_iCuHeight;
314  Int iBaseX          = ( iX - iCuX * m_iCuWidth  ) / m_iBaseUnitWidth;
315  Int iBaseY          = ( iY - iCuY * m_iCuHeight ) / m_iBaseUnitHeight;
316  Int iCuSizeInBases  = m_iCuWidth                  / m_iBaseUnitWidth;
317  riCuAddr            = iCuY   * m_iNumCuInWidth + iCuX;
318  Int iRastPartIdx    = iBaseY * iCuSizeInBases  + iBaseX;
319  riAbsZorderIdx      = g_auiRasterToZscan[ iRastPartIdx ];
320}
321#endif
322Void TComPicYuv::setLumaTo( Pel pVal )
323{
324  xSetPels( getLumaAddr(), getStride(), getWidth(), getHeight(), pVal );
325}
326#endif
327#if NH_3D_VSO
328Void TComPicYuv::setChromaTo( Pel pVal )
329{
330  xSetPels( getAddr( COMPONENT_Cb ), getStride( COMPONENT_Cb ), getWidth( COMPONENT_Cb), getHeight( COMPONENT_Cb ), pVal ); 
331  xSetPels( getAddr( COMPONENT_Cr ), getStride( COMPONENT_Cr ), getWidth( COMPONENT_Cr), getHeight( COMPONENT_Cr ), pVal );
332}
333
334Void TComPicYuv::xSetPels( Pel* piPelSource , Int iSourceStride, Int iWidth, Int iHeight, Pel iVal )
335{
336  for (Int iYPos = 0; iYPos < iHeight; iYPos++)
337  {
338    for (Int iXPos = 0; iXPos < iWidth; iXPos++)
339    {
340      piPelSource[iXPos] = iVal; 
341    }
342    piPelSource += iSourceStride; 
343  }
344}
345#endif
346//! \}
Note: See TracBrowser for help on using the repository browser.