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

Last change on this file since 399 was 332, checked in by tech, 12 years ago

Merged branch 6.1-Cleanup@329.

  • Property svn:eol-style set to native
File size: 15.3 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-2012, 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#if FIX_APPENCTOP_T_ONLY
64  m_cuOffsetY       = NULL;
65  m_cuOffsetC       = NULL;
66  m_buOffsetY       = NULL;
67  m_buOffsetC       = NULL;
68#endif 
69
70  m_bIsBorderExtended = false;
71}
72
73TComPicYuv::~TComPicYuv()
74{
75}
76
77Void TComPicYuv::create( Int iPicWidth, Int iPicHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth )
78{
79  m_iPicWidth       = iPicWidth;
80  m_iPicHeight      = iPicHeight;
81 
82  // --> After config finished!
83  m_iCuWidth        = uiMaxCUWidth;
84  m_iCuHeight       = uiMaxCUHeight;
85
86  m_iNumCuInWidth   = m_iPicWidth / m_iCuWidth;
87  m_iNumCuInWidth  += ( m_iPicWidth % m_iCuWidth ) ? 1 : 0;
88
89  m_uiMaxCuDepth = uiMaxCUDepth;
90
91  m_iBaseUnitWidth  = uiMaxCUWidth  >> uiMaxCUDepth;
92  m_iBaseUnitHeight = uiMaxCUHeight >> uiMaxCUDepth;
93
94  Int numCuInWidth  = m_iPicWidth  / m_iCuWidth  + (m_iPicWidth  % m_iCuWidth  != 0);
95  Int numCuInHeight = m_iPicHeight / m_iCuHeight + (m_iPicHeight % m_iCuHeight != 0);
96 
97  m_iLumaMarginX    = g_uiMaxCUWidth  + PICYUV_PAD; // for 16-byte alignment
98  m_iLumaMarginY    = g_uiMaxCUHeight + PICYUV_PAD;  // margin for 8-tap filter and infinite padding
99 
100  m_iChromaMarginX  = m_iLumaMarginX>>1;
101  m_iChromaMarginY  = m_iLumaMarginY>>1;
102 
103  m_apiPicBufY      = (Pel*)xMalloc( Pel, ( m_iPicWidth       + (m_iLumaMarginX  <<1)) * ( m_iPicHeight       + (m_iLumaMarginY  <<1)));
104  m_apiPicBufU      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
105  m_apiPicBufV      = (Pel*)xMalloc( Pel, ((m_iPicWidth >> 1) + (m_iChromaMarginX<<1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY<<1)));
106 
107  m_piPicOrgY       = m_apiPicBufY + m_iLumaMarginY   * getStride()  + m_iLumaMarginX;
108  m_piPicOrgU       = m_apiPicBufU + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
109  m_piPicOrgV       = m_apiPicBufV + m_iChromaMarginY * getCStride() + m_iChromaMarginX;
110 
111  m_bIsBorderExtended = false;
112 
113  m_cuOffsetY = new Int[numCuInWidth * numCuInHeight];
114  m_cuOffsetC = new Int[numCuInWidth * numCuInHeight];
115  for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
116  {
117    for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
118    {
119      m_cuOffsetY[cuRow * numCuInWidth + cuCol] = getStride() * cuRow * m_iCuHeight + cuCol * m_iCuWidth;
120      m_cuOffsetC[cuRow * numCuInWidth + cuCol] = getCStride() * cuRow * (m_iCuHeight / 2) + cuCol * (m_iCuWidth / 2);
121    }
122  }
123 
124  m_buOffsetY = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
125  m_buOffsetC = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
126  for (Int buRow = 0; buRow < (1 << uiMaxCUDepth); buRow++)
127  {
128    for (Int buCol = 0; buCol < (1 << uiMaxCUDepth); buCol++)
129    {
130      m_buOffsetY[(buRow << uiMaxCUDepth) + buCol] = getStride() * buRow * (uiMaxCUHeight >> uiMaxCUDepth) + buCol * (uiMaxCUWidth  >> uiMaxCUDepth);
131      m_buOffsetC[(buRow << uiMaxCUDepth) + buCol] = getCStride() * buRow * (uiMaxCUHeight / 2 >> uiMaxCUDepth) + buCol * (uiMaxCUWidth / 2 >> uiMaxCUDepth);
132    }
133  }
134  return;
135}
136
137Void TComPicYuv::destroy()
138{
139  m_piPicOrgY       = NULL;
140  m_piPicOrgU       = NULL;
141  m_piPicOrgV       = NULL;
142 
143  if( m_apiPicBufY ){ xFree( m_apiPicBufY );    m_apiPicBufY = NULL; }
144  if( m_apiPicBufU ){ xFree( m_apiPicBufU );    m_apiPicBufU = NULL; }
145  if( m_apiPicBufV ){ xFree( m_apiPicBufV );    m_apiPicBufV = NULL; }
146#if FIX_APPENCTOP_T_ONLY
147  if( m_cuOffsetY )
148  {
149#endif
150  delete[] m_cuOffsetY;
151  delete[] m_cuOffsetC;
152  delete[] m_buOffsetY;
153  delete[] m_buOffsetC;
154#if FIX_APPENCTOP_T_ONLY
155  }
156#endif
157}
158
159Void TComPicYuv::createLuma( Int iPicWidth, Int iPicHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth )
160{
161  m_iPicWidth       = iPicWidth;
162  m_iPicHeight      = iPicHeight;
163 
164  // --> After config finished!
165  m_iCuWidth        = uiMaxCUWidth;
166  m_iCuHeight       = uiMaxCUHeight;
167  m_uiMaxCuDepth    = uiMaxCUDepth;
168
169  m_iNumCuInWidth   = m_iPicWidth / m_iCuWidth;
170  m_iNumCuInWidth  += ( m_iPicWidth % m_iCuWidth ) ? 1 : 0;
171
172  m_iBaseUnitWidth  = uiMaxCUWidth  >> uiMaxCUDepth;
173  m_iBaseUnitHeight = uiMaxCUHeight >> uiMaxCUDepth;
174
175 
176  Int numCuInWidth  = m_iPicWidth  / m_iCuWidth  + (m_iPicWidth  % m_iCuWidth  != 0);
177  Int numCuInHeight = m_iPicHeight / m_iCuHeight + (m_iPicHeight % m_iCuHeight != 0);
178 
179  m_iLumaMarginX    = g_uiMaxCUWidth  + PICYUV_PAD; // for 16-byte alignment
180  m_iLumaMarginY    = g_uiMaxCUHeight + PICYUV_PAD;  // margin for 8-tap filter and infinite padding
181 
182  m_apiPicBufY      = (Pel*)xMalloc( Pel, ( m_iPicWidth       + (m_iLumaMarginX  <<1)) * ( m_iPicHeight       + (m_iLumaMarginY  <<1)));
183  m_piPicOrgY       = m_apiPicBufY + m_iLumaMarginY   * getStride()  + m_iLumaMarginX;
184 
185  m_cuOffsetY = new Int[numCuInWidth * numCuInHeight];
186  m_cuOffsetC = NULL;
187  for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
188  {
189    for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
190    {
191      m_cuOffsetY[cuRow * numCuInWidth + cuCol] = getStride() * cuRow * m_iCuHeight + cuCol * m_iCuWidth;
192    }
193  }
194 
195  m_buOffsetY = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
196  m_buOffsetC = NULL;
197  for (Int buRow = 0; buRow < (1 << uiMaxCUDepth); buRow++)
198  {
199    for (Int buCol = 0; buCol < (1 << uiMaxCUDepth); buCol++)
200    {
201      m_buOffsetY[(buRow << uiMaxCUDepth) + buCol] = getStride() * buRow * (uiMaxCUHeight >> uiMaxCUDepth) + buCol * (uiMaxCUWidth  >> uiMaxCUDepth);
202    }
203  }
204  return;
205}
206
207Void TComPicYuv::destroyLuma()
208{
209  m_piPicOrgY       = NULL;
210 
211  if( m_apiPicBufY ){ xFree( m_apiPicBufY );    m_apiPicBufY = NULL; }
212 
213  delete[] m_cuOffsetY;
214  delete[] m_buOffsetY;
215}
216
217Void  TComPicYuv::copyToPic (TComPicYuv*  pcPicYuvDst)
218{
219  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
220  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
221 
222  ::memcpy ( pcPicYuvDst->getBufY(), m_apiPicBufY, sizeof (Pel) * ( m_iPicWidth       + (m_iLumaMarginX   << 1)) * ( m_iPicHeight       + (m_iLumaMarginY   << 1)) );
223  ::memcpy ( pcPicYuvDst->getBufU(), m_apiPicBufU, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
224  ::memcpy ( pcPicYuvDst->getBufV(), m_apiPicBufV, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
225  return;
226}
227
228Void  TComPicYuv::copyToPicLuma (TComPicYuv*  pcPicYuvDst)
229{
230  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
231  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
232 
233  ::memcpy ( pcPicYuvDst->getBufY(), m_apiPicBufY, sizeof (Pel) * ( m_iPicWidth       + (m_iLumaMarginX   << 1)) * ( m_iPicHeight       + (m_iLumaMarginY   << 1)) );
234  return;
235}
236
237Void  TComPicYuv::copyToPicCb (TComPicYuv*  pcPicYuvDst)
238{
239  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
240  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
241 
242  ::memcpy ( pcPicYuvDst->getBufU(), m_apiPicBufU, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
243  return;
244}
245
246Void  TComPicYuv::copyToPicCr (TComPicYuv*  pcPicYuvDst)
247{
248  assert( m_iPicWidth  == pcPicYuvDst->getWidth()  );
249  assert( m_iPicHeight == pcPicYuvDst->getHeight() );
250 
251  ::memcpy ( pcPicYuvDst->getBufV(), m_apiPicBufV, sizeof (Pel) * ((m_iPicWidth >> 1) + (m_iChromaMarginX << 1)) * ((m_iPicHeight >> 1) + (m_iChromaMarginY << 1)) );
252  return;
253}
254
255
256Void TComPicYuv::getLumaMinMax( Int *pMin, Int *pMax )
257{
258  Pel*  piY   = getLumaAddr();
259  Int   iMin  = (1<<(g_uiBitDepth))-1;
260  Int   iMax  = 0;
261  Int   x, y;
262 
263  for ( y = 0; y < m_iPicHeight; y++ )
264  {
265    for ( x = 0; x < m_iPicWidth; x++ )
266    {
267      if ( piY[x] < iMin ) iMin = piY[x];
268      if ( piY[x] > iMax ) iMax = piY[x];
269    }
270    piY += getStride();
271  }
272 
273  *pMin = iMin;
274  *pMax = iMax;
275}
276
277Void TComPicYuv::extendPicBorder ()
278{
279  if ( m_bIsBorderExtended ) return;
280 
281  xExtendPicCompBorder( getLumaAddr(), getStride(),  getWidth(),      getHeight(),      m_iLumaMarginX,   m_iLumaMarginY   );
282  xExtendPicCompBorder( getCbAddr()  , getCStride(), getWidth() >> 1, getHeight() >> 1, m_iChromaMarginX, m_iChromaMarginY );
283  xExtendPicCompBorder( getCrAddr()  , getCStride(), getWidth() >> 1, getHeight() >> 1, m_iChromaMarginX, m_iChromaMarginY );
284 
285  m_bIsBorderExtended = true;
286}
287
288Void TComPicYuv::xExtendPicCompBorder  (Pel* piTxt, Int iStride, Int iWidth, Int iHeight, Int iMarginX, Int iMarginY)
289{
290  Int   x, y;
291  Pel*  pi;
292 
293  pi = piTxt;
294  for ( y = 0; y < iHeight; y++)
295  {
296    for ( x = 0; x < iMarginX; x++ )
297    {
298      pi[ -iMarginX + x ] = pi[0];
299      pi[    iWidth + x ] = pi[iWidth-1];
300    }
301    pi += iStride;
302  }
303 
304  pi -= (iStride + iMarginX);
305  for ( y = 0; y < iMarginY; y++ )
306  {
307    ::memcpy( pi + (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
308  }
309 
310  pi -= ((iHeight-1) * iStride);
311  for ( y = 0; y < iMarginY; y++ )
312  {
313    ::memcpy( pi - (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
314  }
315}
316
317
318Void TComPicYuv::dump (char* pFileName, Bool bAdd)
319{
320  FILE* pFile;
321  if (!bAdd)
322  {
323    pFile = fopen (pFileName, "wb");
324  }
325  else
326  {
327    pFile = fopen (pFileName, "ab");
328  }
329 
330  Int     shift = g_uiBitIncrement;
331  Int     offset = (shift>0)?(1<<(shift-1)):0;
332 
333  Int   x, y;
334  UChar uc;
335 
336  Pel*  piY   = getLumaAddr();
337  Pel*  piCb  = getCbAddr();
338  Pel*  piCr  = getCrAddr();
339 
340  Pel  iMax = ((1<<(g_uiBitDepth))-1);
341 
342  for ( y = 0; y < m_iPicHeight; y++ )
343  {
344    for ( x = 0; x < m_iPicWidth; x++ )
345    {
346      uc = (UChar)Clip3<Pel>(0, iMax, (piY[x]+offset)>>shift);
347     
348      fwrite( &uc, sizeof(UChar), 1, pFile );
349    }
350    piY += getStride();
351  }
352 
353  for ( y = 0; y < m_iPicHeight >> 1; y++ )
354  {
355    for ( x = 0; x < m_iPicWidth >> 1; x++ )
356    {
357      uc = (UChar)Clip3<Pel>(0, iMax, (piCb[x]+offset)>>shift);
358      fwrite( &uc, sizeof(UChar), 1, pFile );
359    }
360    piCb += getCStride();
361  }
362 
363  for ( y = 0; y < m_iPicHeight >> 1; y++ )
364  {
365    for ( x = 0; x < m_iPicWidth >> 1; x++ )
366    {
367      uc = (UChar)Clip3<Pel>(0, iMax, (piCr[x]+offset)>>shift);
368      fwrite( &uc, sizeof(UChar), 1, pFile );
369    }
370    piCr += getCStride();
371  }
372 
373  fclose(pFile);
374}
375
376#if FIXED_ROUNDING_FRAME_MEMORY
377Void TComPicYuv::xFixedRoundingPic()
378{
379  Int   x, y;
380  Pel*  pRec    = getLumaAddr();
381  Int   iStride = getStride();
382  Int   iWidth  = getWidth();
383  Int   iHeight = getHeight();
384#if FULL_NBIT
385  Int   iOffset  = ((g_uiBitDepth-8)>0)?(1<<(g_uiBitDepth-8-1)):0;
386  Int   iMask   = (~0<<(g_uiBitDepth-8));
387  Int   iMaxBdi = g_uiBASE_MAX<<(g_uiBitDepth-8);
388#else
389  Int   iOffset  = (g_uiBitIncrement>0)?(1<<(g_uiBitIncrement-1)):0;
390  Int   iMask   = (~0<<g_uiBitIncrement);
391  Int   iMaxBdi = g_uiBASE_MAX<<g_uiBitIncrement;
392#endif
393
394  for( y = 0; y < iHeight; y++ )
395  {
396    for( x = 0; x < iWidth; x++ )
397    {
398#if IBDI_NOCLIP_RANGE
399      pRec[x] = ( pRec[x] + iOffset ) & iMask;
400#else
401      pRec[x] = ( pRec[x]+iOffset>iMaxBdi)? iMaxBdi : ((pRec[x]+iOffset) & iMask);
402#endif
403    }
404    pRec += iStride;
405  }
406
407  iHeight >>= 1;
408  iWidth  >>= 1;
409  iStride >>= 1;
410  pRec  = getCbAddr();
411
412  for( y = 0; y < iHeight; y++ )
413  {
414    for( x = 0; x < iWidth; x++ )
415    {
416#if IBDI_NOCLIP_RANGE
417      pRec[x] = ( pRec[x] + iOffset ) & iMask;
418#else
419      pRec[x] = ( pRec[x]+iOffset>iMaxBdi)? iMaxBdi : ((pRec[x]+iOffset) & iMask);
420#endif
421    }
422    pRec += iStride;
423  }
424
425  pRec  = getCrAddr();
426
427  for( y = 0; y < iHeight; y++ )
428  {
429    for( x = 0; x < iWidth; x++ )
430    {
431#if IBDI_NOCLIP_RANGE
432      pRec[x] = ( pRec[x] + iOffset ) & iMask;
433#else
434      pRec[x] = ( pRec[x]+iOffset>iMaxBdi)? iMaxBdi : ((pRec[x]+iOffset) & iMask);
435#endif
436    }
437    pRec += iStride;
438  }
439}
440#endif
441
442Void
443TComPicYuv::getTopLeftSamplePos( Int iCuAddr, Int iAbsZorderIdx, Int& riX, Int& riY )
444{
445  Int iRastPartIdx    = g_auiZscanToRaster[iAbsZorderIdx];
446  Int iCuSizeInBases  = m_iCuWidth   / m_iBaseUnitWidth;
447  Int iCuX            = iCuAddr      % m_iNumCuInWidth;
448  Int iCuY            = iCuAddr      / m_iNumCuInWidth;
449  Int iBaseX          = iRastPartIdx % iCuSizeInBases;
450  Int iBaseY          = iRastPartIdx / iCuSizeInBases;
451  riX                 = iCuX * m_iCuWidth  + iBaseX * m_iBaseUnitWidth;
452  riY                 = iCuY * m_iCuHeight + iBaseY * m_iBaseUnitHeight; 
453}
454
455Void
456TComPicYuv::getCUAddrAndPartIdx( Int iX, Int iY, Int& riCuAddr, Int& riAbsZorderIdx )
457{
458  Int iCuX            = iX / m_iCuWidth;
459  Int iCuY            = iY / m_iCuHeight;
460  Int iBaseX          = ( iX - iCuX * m_iCuWidth  ) / m_iBaseUnitWidth;
461  Int iBaseY          = ( iY - iCuY * m_iCuHeight ) / m_iBaseUnitHeight;
462  Int iCuSizeInBases  = m_iCuWidth                  / m_iBaseUnitWidth;
463  riCuAddr            = iCuY   * m_iNumCuInWidth + iCuX;
464  Int iRastPartIdx    = iBaseY * iCuSizeInBases  + iBaseX;
465  riAbsZorderIdx      = g_auiRasterToZscan[ iRastPartIdx ];
466}
467
468Void TComPicYuv::setLumaTo( Pel pVal )
469{
470  xSetPels( getLumaAddr(), getStride(), getWidth(), getHeight(), pVal );
471}
472
473Void TComPicYuv::setChromaTo( Pel pVal )
474{
475  xSetPels( getCbAddr(), getCStride(), getWidth() >> 1, getHeight() >> 1, pVal ); 
476  xSetPels( getCrAddr(), getCStride(), getWidth() >> 1, getHeight() >> 1, pVal );
477}
478
479Void TComPicYuv::xSetPels( Pel* piPelSource , Int iSourceStride, Int iWidth, Int iHeight, Pel iVal )
480{
481  for (Int iYPos = 0; iYPos < iHeight; iYPos++)
482  {
483    for (Int iXPos = 0; iXPos < iWidth; iXPos++)
484    {
485      piPelSource[iXPos] = iVal; 
486    }
487    piPelSource += iSourceStride; 
488  }
489}
490
491//! \}
Note: See TracBrowser for help on using the repository browser.