source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComPicYuv.cpp @ 885

Last change on this file since 885 was 872, checked in by tech, 11 years ago

Merged HTM-10.0-dev0@871. (MV-HEVC 7 HLS)

  • Property svn:eol-style set to native
File size: 13.0 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     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
50//! \ingroup TLibCommon
51//! \{
52
53TComPicYuv::TComPicYuv()
54{
55  m_apiPicBufY      = NULL;   // Buffer (including margin)
56  m_apiPicBufU      = NULL;
57  m_apiPicBufV      = NULL;
58 
59  m_piPicOrgY       = NULL;    // m_apiPicBufY + m_iMarginLuma*getStride() + m_iMarginLuma
60  m_piPicOrgU       = NULL;
61  m_piPicOrgV       = NULL;
62 
63  m_bIsBorderExtended = false;
64}
65
66TComPicYuv::~TComPicYuv()
67{
68}
69
70Void TComPicYuv::create( Int iPicWidth, Int iPicHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth )
71{
72  m_iPicWidth       = iPicWidth;
73  m_iPicHeight      = iPicHeight;
74 
75  // --> After config finished!
76  m_iCuWidth        = uiMaxCUWidth;
77  m_iCuHeight       = uiMaxCUHeight;
78
79#if H_3D_IV_MERGE
80  m_iNumCuInWidth   = m_iPicWidth / m_iCuWidth;
81  m_iNumCuInWidth  += ( m_iPicWidth % m_iCuWidth ) ? 1 : 0;
82
83  m_iBaseUnitWidth  = uiMaxCUWidth  >> uiMaxCUDepth;
84  m_iBaseUnitHeight = uiMaxCUHeight >> uiMaxCUDepth;
85#endif
86  Int numCuInWidth  = m_iPicWidth  / m_iCuWidth  + (m_iPicWidth  % m_iCuWidth  != 0);
87  Int numCuInHeight = m_iPicHeight / m_iCuHeight + (m_iPicHeight % m_iCuHeight != 0);
88 
89  m_iLumaMarginX    = g_uiMaxCUWidth  + 16; // for 16-byte alignment
90  m_iLumaMarginY    = g_uiMaxCUHeight + 16;  // margin for 8-tap filter and infinite padding
91 
92  m_iChromaMarginX  = m_iLumaMarginX>>1;
93  m_iChromaMarginY  = m_iLumaMarginY>>1;
94 
95  m_apiPicBufY      = (Pel*)xMalloc( Pel, ( m_iPicWidth       + (m_iLumaMarginX  <<1)) * ( m_iPicHeight       + (m_iLumaMarginY  <<1)));
96  m_apiPicBufU      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
97  m_apiPicBufV      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
98 
99  m_piPicOrgY       = m_apiPicBufY + m_iLumaMarginY   * getStride()  + m_iLumaMarginX;
100  m_piPicOrgU       = m_apiPicBufU + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
101  m_piPicOrgV       = m_apiPicBufV + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
102 
103  m_bIsBorderExtended = false;
104 
105  m_cuOffsetY = new Int[numCuInWidth * numCuInHeight];
106  m_cuOffsetC = new Int[numCuInWidth * numCuInHeight];
107  for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
108  {
109    for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
110    {
111      m_cuOffsetY[cuRow * numCuInWidth + cuCol] = getStride() * cuRow * m_iCuHeight + cuCol * m_iCuWidth;
112      m_cuOffsetC[cuRow * numCuInWidth + cuCol] = getCStride() * cuRow * (m_iCuHeight / 2) + cuCol * (m_iCuWidth / 2);
113    }
114  }
115 
116  m_buOffsetY = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
117  m_buOffsetC = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
118  for (Int buRow = 0; buRow < (1 << uiMaxCUDepth); buRow++)
119  {
120    for (Int buCol = 0; buCol < (1 << uiMaxCUDepth); buCol++)
121    {
122      m_buOffsetY[(buRow << uiMaxCUDepth) + buCol] = getStride() * buRow * (uiMaxCUHeight >> uiMaxCUDepth) + buCol * (uiMaxCUWidth  >> uiMaxCUDepth);
123      m_buOffsetC[(buRow << uiMaxCUDepth) + buCol] = getCStride() * buRow * (uiMaxCUHeight / 2 >> uiMaxCUDepth) + buCol * (uiMaxCUWidth / 2 >> uiMaxCUDepth);
124    }
125  }
126  return;
127}
128
129Void TComPicYuv::destroy()
130{
131  m_piPicOrgY       = NULL;
132  m_piPicOrgU       = NULL;
133  m_piPicOrgV       = NULL;
134 
135  if( m_apiPicBufY ){ xFree( m_apiPicBufY );    m_apiPicBufY = NULL; }
136  if( m_apiPicBufU ){ xFree( m_apiPicBufU );    m_apiPicBufU = NULL; }
137  if( m_apiPicBufV ){ xFree( m_apiPicBufV );    m_apiPicBufV = NULL; }
138
139  delete[] m_cuOffsetY;
140  delete[] m_cuOffsetC;
141  delete[] m_buOffsetY;
142  delete[] m_buOffsetC;
143}
144
145Void TComPicYuv::createLuma( Int iPicWidth, Int iPicHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth )
146{
147  m_iPicWidth       = iPicWidth;
148  m_iPicHeight      = iPicHeight;
149 
150  // --> After config finished!
151  m_iCuWidth        = uiMaxCUWidth;
152  m_iCuHeight       = uiMaxCUHeight;
153 
154  Int numCuInWidth  = m_iPicWidth  / m_iCuWidth  + (m_iPicWidth  % m_iCuWidth  != 0);
155  Int numCuInHeight = m_iPicHeight / m_iCuHeight + (m_iPicHeight % m_iCuHeight != 0);
156 
157  m_iLumaMarginX    = g_uiMaxCUWidth  + 16; // for 16-byte alignment
158  m_iLumaMarginY    = g_uiMaxCUHeight + 16;  // margin for 8-tap filter and infinite padding
159 
160  m_apiPicBufY      = (Pel*)xMalloc( Pel, ( m_iPicWidth       + (m_iLumaMarginX  <<1)) * ( m_iPicHeight       + (m_iLumaMarginY  <<1)));
161  m_piPicOrgY       = m_apiPicBufY + m_iLumaMarginY   * getStride()  + m_iLumaMarginX;
162 
163  m_cuOffsetY = new Int[numCuInWidth * numCuInHeight];
164  m_cuOffsetC = NULL;
165  for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
166  {
167    for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
168    {
169      m_cuOffsetY[cuRow * numCuInWidth + cuCol] = getStride() * cuRow * m_iCuHeight + cuCol * m_iCuWidth;
170    }
171  }
172 
173  m_buOffsetY = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
174  m_buOffsetC = NULL;
175  for (Int buRow = 0; buRow < (1 << uiMaxCUDepth); buRow++)
176  {
177    for (Int buCol = 0; buCol < (1 << uiMaxCUDepth); buCol++)
178    {
179      m_buOffsetY[(buRow << uiMaxCUDepth) + buCol] = getStride() * buRow * (uiMaxCUHeight >> uiMaxCUDepth) + buCol * (uiMaxCUWidth  >> uiMaxCUDepth);
180    }
181  }
182  return;
183}
184
185Void TComPicYuv::destroyLuma()
186{
187  m_piPicOrgY       = NULL;
188 
189  if( m_apiPicBufY ){ xFree( m_apiPicBufY );    m_apiPicBufY = NULL; }
190 
191  delete[] m_cuOffsetY;
192  delete[] m_buOffsetY;
193}
194
195Void  TComPicYuv::copyToPic (TComPicYuv*  pcPicYuvDst)
196{
197  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
198  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
199 
200  ::memcpy ( pcPicYuvDst->getBufY(), m_apiPicBufY, sizeof (Pel) * ( m_iPicWidth       + (m_iLumaMarginX   << 1)) * ( m_iPicHeight       + (m_iLumaMarginY   << 1)) );
201  ::memcpy ( pcPicYuvDst->getBufU(), m_apiPicBufU, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
202  ::memcpy ( pcPicYuvDst->getBufV(), m_apiPicBufV, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
203  return;
204}
205
206Void  TComPicYuv::copyToPicLuma (TComPicYuv*  pcPicYuvDst)
207{
208  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
209  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
210 
211  ::memcpy ( pcPicYuvDst->getBufY(), m_apiPicBufY, sizeof (Pel) * ( m_iPicWidth       + (m_iLumaMarginX   << 1)) * ( m_iPicHeight       + (m_iLumaMarginY   << 1)) );
212  return;
213}
214
215Void  TComPicYuv::copyToPicCb (TComPicYuv*  pcPicYuvDst)
216{
217  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
218  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
219 
220  ::memcpy ( pcPicYuvDst->getBufU(), m_apiPicBufU, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
221  return;
222}
223
224Void  TComPicYuv::copyToPicCr (TComPicYuv*  pcPicYuvDst)
225{
226  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
227  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
228 
229  ::memcpy ( pcPicYuvDst->getBufV(), m_apiPicBufV, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
230  return;
231}
232
233Void TComPicYuv::extendPicBorder ()
234{
235  if ( m_bIsBorderExtended ) return;
236 
237  xExtendPicCompBorder( getLumaAddr(), getStride(),  getWidth(),      getHeight(),      m_iLumaMarginX,   m_iLumaMarginY   );
238  xExtendPicCompBorder( getCbAddr()  , getCStride(), getWidth() >> 1, getHeight() >> 1, m_iChromaMarginX, m_iChromaMarginY );
239  xExtendPicCompBorder( getCrAddr()  , getCStride(), getWidth() >> 1, getHeight() >> 1, m_iChromaMarginX, m_iChromaMarginY );
240 
241  m_bIsBorderExtended = true;
242}
243
244Void TComPicYuv::xExtendPicCompBorder  (Pel* piTxt, Int iStride, Int iWidth, Int iHeight, Int iMarginX, Int iMarginY)
245{
246  Int   x, y;
247  Pel*  pi;
248 
249  pi = piTxt;
250  for ( y = 0; y < iHeight; y++)
251  {
252    for ( x = 0; x < iMarginX; x++ )
253    {
254      pi[ -iMarginX + x ] = pi[0];
255      pi[    iWidth + x ] = pi[iWidth-1];
256    }
257    pi += iStride;
258  }
259 
260  pi -= (iStride + iMarginX);
261  for ( y = 0; y < iMarginY; y++ )
262  {
263    ::memcpy( pi + (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
264  }
265 
266  pi -= ((iHeight-1) * iStride);
267  for ( y = 0; y < iMarginY; y++ )
268  {
269    ::memcpy( pi - (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
270  }
271}
272
273
274Void TComPicYuv::dump (Char* pFileName, Bool bAdd)
275{
276  FILE* pFile;
277  if (!bAdd)
278  {
279    pFile = fopen (pFileName, "wb");
280  }
281  else
282  {
283    pFile = fopen (pFileName, "ab");
284  }
285 
286  Int     shift = g_bitDepthY-8;
287  Int     offset = (shift>0)?(1<<(shift-1)):0;
288 
289  Int   x, y;
290  UChar uc;
291 
292  Pel*  piY   = getLumaAddr();
293  Pel*  piCb  = getCbAddr();
294  Pel*  piCr  = getCrAddr();
295 
296  for ( y = 0; y < m_iPicHeight; y++ )
297  {
298    for ( x = 0; x < m_iPicWidth; x++ )
299    {
300      uc = (UChar)Clip3<Pel>(0, 255, (piY[x]+offset)>>shift);
301     
302      fwrite( &uc, sizeof(UChar), 1, pFile );
303    }
304    piY += getStride();
305  }
306 
307  shift = g_bitDepthC-8;
308  offset = (shift>0)?(1<<(shift-1)):0;
309
310  for ( y = 0; y < m_iPicHeight >> 1; y++ )
311  {
312    for ( x = 0; x < m_iPicWidth >> 1; x++ )
313    {
314      uc = (UChar)Clip3<Pel>(0, 255, (piCb[x]+offset)>>shift);
315      fwrite( &uc, sizeof(UChar), 1, pFile );
316    }
317    piCb += getCStride();
318  }
319 
320  for ( y = 0; y < m_iPicHeight >> 1; y++ )
321  {
322    for ( x = 0; x < m_iPicWidth >> 1; x++ )
323    {
324      uc = (UChar)Clip3<Pel>(0, 255, (piCr[x]+offset)>>shift);
325      fwrite( &uc, sizeof(UChar), 1, pFile );
326    }
327    piCr += getCStride();
328  }
329 
330  fclose(pFile);
331}
332
333#if H_3D
334#if H_3D_IV_MERGE
335Void
336TComPicYuv::getTopLeftSamplePos( Int iCuAddr, Int iAbsZorderIdx, Int& riX, Int& riY )
337{
338  Int iRastPartIdx    = g_auiZscanToRaster[iAbsZorderIdx];
339  Int iCuSizeInBases  = m_iCuWidth   / m_iBaseUnitWidth;
340  Int iCuX            = iCuAddr      % m_iNumCuInWidth;
341  Int iCuY            = iCuAddr      / m_iNumCuInWidth;
342  Int iBaseX          = iRastPartIdx % iCuSizeInBases;
343  Int iBaseY          = iRastPartIdx / iCuSizeInBases;
344  riX                 = iCuX * m_iCuWidth  + iBaseX * m_iBaseUnitWidth;
345  riY                 = iCuY * m_iCuHeight + iBaseY * m_iBaseUnitHeight; 
346}
347
348Void
349TComPicYuv::getCUAddrAndPartIdx( Int iX, Int iY, Int& riCuAddr, Int& riAbsZorderIdx )
350{
351  Int iCuX            = iX / m_iCuWidth;
352  Int iCuY            = iY / m_iCuHeight;
353  Int iBaseX          = ( iX - iCuX * m_iCuWidth  ) / m_iBaseUnitWidth;
354  Int iBaseY          = ( iY - iCuY * m_iCuHeight ) / m_iBaseUnitHeight;
355  Int iCuSizeInBases  = m_iCuWidth                  / m_iBaseUnitWidth;
356  riCuAddr            = iCuY   * m_iNumCuInWidth + iCuX;
357  Int iRastPartIdx    = iBaseY * iCuSizeInBases  + iBaseX;
358  riAbsZorderIdx      = g_auiRasterToZscan[ iRastPartIdx ];
359}
360#endif
361Void TComPicYuv::setLumaTo( Pel pVal )
362{
363  xSetPels( getLumaAddr(), getStride(), getWidth(), getHeight(), pVal );
364}
365
366Void TComPicYuv::setChromaTo( Pel pVal )
367{
368  xSetPels( getCbAddr(), getCStride(), getWidth() >> 1, getHeight() >> 1, pVal ); 
369  xSetPels( getCrAddr(), getCStride(), getWidth() >> 1, getHeight() >> 1, pVal );
370}
371
372Void TComPicYuv::xSetPels( Pel* piPelSource , Int iSourceStride, Int iWidth, Int iHeight, Pel iVal )
373{
374  for (Int iYPos = 0; iYPos < iHeight; iYPos++)
375  {
376    for (Int iXPos = 0; iXPos < iWidth; iXPos++)
377    {
378      piPelSource[iXPos] = iVal; 
379    }
380    piPelSource += iSourceStride; 
381  }
382}
383#endif
384
385//! \}
Note: See TracBrowser for help on using the repository browser.