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

Last change on this file since 824 was 815, checked in by seregin, 10 years ago

merge with SHM-6-dev branch

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