source: SHVCSoftware/branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPicYuv.cpp @ 567

Last change on this file since 567 was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

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