source: SHVCSoftware/trunk/source/Lib/TLibCommon/TComPicYuv.cpp @ 1115

Last change on this file since 1115 was 906, checked in by seregin, 10 years ago

merge SHM-dev

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