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

Last change on this file since 720 was 713, checked in by seregin, 11 years ago

merge with SHM-6-dev

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