source: SHVCSoftware/branches/HM-10.0-dev-SHM/source/Lib/TLibCommon/TComPicYuv.cpp @ 824

Last change on this file since 824 was 54, checked in by seregin, 12 years ago

port simulcast

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