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

Last change on this file since 1323 was 1305, checked in by seregin, 9 years ago

port rev 4352

  • Property svn:eol-style set to native
File size: 10.4 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
[1029]4 * granted under this license.
[313]5 *
[1259]6 * Copyright (c) 2010-2015, 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"
[1029]49#include "TLibVideoIO/TVideoIOYuv.h"
[313]50
51//! \ingroup TLibCommon
52//! \{
53
54TComPicYuv::TComPicYuv()
55{
[1029]56  for(UInt i=0; i<MAX_NUM_COMPONENT; i++)
57  {
58    m_apiPicBuf[i]    = NULL;   // Buffer (including margin)
59    m_piPicOrg[i]     = NULL;    // m_apiPicBufY + m_iMarginLuma*getStride() + m_iMarginLuma
60  }
61
62  for(UInt i=0; i<MAX_NUM_CHANNEL_TYPE; i++)
63  {
64    m_ctuOffsetInBuffer[i]=0;
65    m_subCuOffsetInBuffer[i]=0;
66  }
67
[313]68  m_bIsBorderExtended = false;
69}
70
[1029]71
72
73
[313]74TComPicYuv::~TComPicYuv()
75{
76}
[815]77
[1305]78
79
80
81Void TComPicYuv::create ( const Int iPicWidth,                ///< picture width
82                          const Int iPicHeight,               ///< picture height
83                          const ChromaFormat chromaFormatIDC, ///< chroma format
84                          const UInt uiMaxCUWidth,            ///< used for generating offsets to CUs. Can use iPicWidth if no offsets are required
85                          const UInt uiMaxCUHeight,           ///< used for generating offsets to CUs. Can use iPicHeight if no offsets are required
86                          const UInt uiMaxCUDepth,            ///< used for generating offsets to CUs. Can use 0 if no offsets are required
[815]87#if SVC_EXTENSION
[1289]88                          const Bool bUseMargin,     ///< if true, then a margin of uiMaxCUWidth+16 and uiMaxCUHeight+16 is created around the image.
89                          const Window* conformanceWindow)
[869]90#else
[1305]91                          const Bool bUseMargin)              ///< if true, then a margin of uiMaxCUWidth+16 and uiMaxCUHeight+16 is created around the image.
[494]92#endif
[1305]93
[313]94{
[1305]95
[815]96#if SVC_EXTENSION
[869]97  if(conformanceWindow != NULL)
98  {
99    m_conformanceWindow = *conformanceWindow;
100  }
[313]101#endif
[1289]102
103  m_iPicWidth         = iPicWidth;
104  m_iPicHeight        = iPicHeight;
105  m_chromaFormatIDC   = chromaFormatIDC;
[1305]106  m_iMarginX          = (bUseMargin?uiMaxCUWidth:0) + 16;   // for 16-byte alignment
[1289]107  m_iMarginY          = (bUseMargin?uiMaxCUHeight:0) + 16;  // margin for 8-tap filter and infinite padding
[313]108  m_bIsBorderExtended = false;
[1029]109
110  // assign the picture arrays and set up the ptr to the top left of the original picture
[313]111  {
[1029]112    Int chan=0;
113    for(; chan<getNumberValidComponents(); chan++)
[313]114    {
[1029]115      const ComponentID ch=ComponentID(chan);
116      m_apiPicBuf[chan] = (Pel*)xMalloc( Pel, getStride(ch)       * getTotalHeight(ch));
117      m_piPicOrg[chan]  = m_apiPicBuf[chan] + (m_iMarginY >> getComponentScaleY(ch))   * getStride(ch)       + (m_iMarginX >> getComponentScaleX(ch));
[313]118    }
[1029]119    for(;chan<MAX_NUM_COMPONENT; chan++)
[313]120    {
[1029]121      m_apiPicBuf[chan] = NULL;
122      m_piPicOrg[chan]  = NULL;
[313]123    }
124  }
[1029]125
126
127  const Int numCuInWidth  = m_iPicWidth  / uiMaxCUWidth  + (m_iPicWidth  % uiMaxCUWidth  != 0);
128  const Int numCuInHeight = m_iPicHeight / uiMaxCUHeight + (m_iPicHeight % uiMaxCUHeight != 0);
129  for(Int chan=0; chan<2; chan++)
130  {
131    const ComponentID ch=ComponentID(chan);
132    const Int ctuHeight=uiMaxCUHeight>>getComponentScaleY(ch);
133    const Int ctuWidth=uiMaxCUWidth>>getComponentScaleX(ch);
134    const Int stride = getStride(ch);
135
136    m_ctuOffsetInBuffer[chan] = new Int[numCuInWidth * numCuInHeight];
137
138    for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
[1246]139    {
[1029]140      for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
[1246]141      {
[1029]142        m_ctuOffsetInBuffer[chan][cuRow * numCuInWidth + cuCol] = stride * cuRow * ctuHeight + cuCol * ctuWidth;
[1246]143      }
144    }
[1029]145
146    m_subCuOffsetInBuffer[chan] = new Int[(size_t)1 << (2 * uiMaxCUDepth)];
147
148    const Int numSubBlockPartitions=(1<<uiMaxCUDepth);
149    const Int minSubBlockHeight    =(ctuHeight >> uiMaxCUDepth);
150    const Int minSubBlockWidth     =(ctuWidth  >> uiMaxCUDepth);
151
152    for (Int buRow = 0; buRow < numSubBlockPartitions; buRow++)
[1246]153    {
[1029]154      for (Int buCol = 0; buCol < numSubBlockPartitions; buCol++)
[1246]155      {
[1029]156        m_subCuOffsetInBuffer[chan][(buRow << uiMaxCUDepth) + buCol] = stride  * buRow * minSubBlockHeight + buCol * minSubBlockWidth;
[1246]157      }
158    }
[1029]159  }
[313]160  return;
161}
162
163
164
[1029]165Void TComPicYuv::destroy()
[313]166{
[1029]167  for(Int chan=0; chan<MAX_NUM_COMPONENT; chan++)
[313]168  {
[1029]169    m_piPicOrg[chan] = NULL;
170
[1246]171    if( m_apiPicBuf[chan] )
172    {
173      xFree( m_apiPicBuf[chan] );
174      m_apiPicBuf[chan] = NULL;
175    }
[313]176  }
[1029]177
178  for(UInt chan=0; chan<MAX_NUM_CHANNEL_TYPE; chan++)
[313]179  {
[1246]180    if (m_ctuOffsetInBuffer[chan])
181    {
182      delete[] m_ctuOffsetInBuffer[chan];
183      m_ctuOffsetInBuffer[chan] = NULL;
184    }
185    if (m_subCuOffsetInBuffer[chan])
186    {
187      delete[] m_subCuOffsetInBuffer[chan];
188      m_subCuOffsetInBuffer[chan] = NULL;
189    }
[313]190  }
191}
192
193
194
[1029]195Void  TComPicYuv::copyToPic (TComPicYuv*  pcPicYuvDst) const
[313]196{
[1029]197  assert( m_iPicWidth  == pcPicYuvDst->getWidth(COMPONENT_Y)  );
198  assert( m_iPicHeight == pcPicYuvDst->getHeight(COMPONENT_Y) );
199  assert( m_chromaFormatIDC == pcPicYuvDst->getChromaFormat() );
[313]200
[1029]201  for(Int chan=0; chan<getNumberValidComponents(); chan++)
202  {
203    const ComponentID ch=ComponentID(chan);
204    ::memcpy ( pcPicYuvDst->getBuf(ch), m_apiPicBuf[ch], sizeof (Pel) * getStride(ch) * getTotalHeight(ch));
205  }
[313]206  return;
207}
208
209
210Void TComPicYuv::extendPicBorder ()
211{
[1246]212  if ( m_bIsBorderExtended )
213  {
214    return;
215  }
[313]216
[1029]217  for(Int chan=0; chan<getNumberValidComponents(); chan++)
[313]218  {
[1029]219    const ComponentID ch=ComponentID(chan);
220    Pel *piTxt=getAddr(ch); // piTxt = point to (0,0) of image within bigger picture.
221    const Int iStride=getStride(ch);
222    const Int iWidth=getWidth(ch);
223    const Int iHeight=getHeight(ch);
224    const Int iMarginX=getMarginX(ch);
225    const Int iMarginY=getMarginY(ch);
226
227    Pel*  pi = piTxt;
228    // do left and right margins
229    for (Int y = 0; y < iHeight; y++)
[313]230    {
[1029]231      for (Int x = 0; x < iMarginX; x++ )
232      {
233        pi[ -iMarginX + x ] = pi[0];
234        pi[    iWidth + x ] = pi[iWidth-1];
235      }
236      pi += iStride;
[313]237    }
[1029]238
239    // pi is now the (0,height) (bottom left of image within bigger picture
240    pi -= (iStride + iMarginX);
241    // pi is now the (-marginX, height-1)
242    for (Int y = 0; y < iMarginY; y++ )
243    {
244      ::memcpy( pi + (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
245    }
246
247    // pi is still (-marginX, height-1)
248    pi -= ((iHeight-1) * iStride);
249    // pi is now (-marginX, 0)
250    for (Int y = 0; y < iMarginY; y++ )
251    {
252      ::memcpy( pi - (y+1)*iStride, pi, sizeof(Pel)*(iWidth + (iMarginX<<1)) );
253    }
[313]254  }
[1029]255
256  m_bIsBorderExtended = true;
[313]257}
258
259
[1029]260
261// NOTE: This function is never called, but may be useful for developers.
[1287]262Void TComPicYuv::dump (const Char* pFileName, const BitDepths &bitDepths, Bool bAdd) const
[313]263{
264  FILE* pFile;
265  if (!bAdd)
266  {
267    pFile = fopen (pFileName, "wb");
268  }
269  else
270  {
271    pFile = fopen (pFileName, "ab");
272  }
[1029]273
274
275  for(Int chan = 0; chan < getNumberValidComponents(); chan++)
[313]276  {
[1029]277    const ComponentID  ch     = ComponentID(chan);
[1287]278    const Int          shift  = bitDepths.recon[toChannelType(ch)] - 8;
[1029]279    const Int          offset = (shift>0)?(1<<(shift-1)):0;
280    const Pel         *pi     = getAddr(ch);
281    const Int          stride = getStride(ch);
282    const Int          height = getHeight(ch);
283    const Int          width  = getWidth(ch);
284
285    for (Int y = 0; y < height; y++ )
[313]286    {
[1029]287      for (Int x = 0; x < width; x++ )
288      {
289        UChar uc = (UChar)Clip3<Pel>(0, 255, (pi[x]+offset)>>shift);
290        fwrite( &uc, sizeof(UChar), 1, pFile );
291      }
292      pi += stride;
[313]293    }
294  }
295
296  fclose(pFile);
297}
298
[815]299Void TComPicYuv::dump( Char* pFileName, Bool bAdd, Int bitDepth )
300{
301  FILE* pFile;
302  if (!bAdd)
303  {
304    pFile = fopen (pFileName, "wb");
305  }
306  else
307  {
308    pFile = fopen (pFileName, "ab");
309  }
[313]310
[815]311  if( bitDepth == 8 )
312  {
[1287]313    dump( pFileName, bitDepth, bAdd );
[815]314    return;
315  }
[1029]316
317  for(Int chan = 0; chan < getNumberValidComponents(); chan++)
[815]318  {
[1029]319    const ComponentID  ch     = ComponentID(chan);
320    const Pel         *pi     = getAddr(ch);
321    const Int          stride = getStride(ch);
322    const Int          height = getHeight(ch);
323    const Int          width  = getWidth(ch);
324
325    for (Int y = 0; y < height; y++ )
[815]326    {
[1029]327      for (Int x = 0; x < width; x++ )
328      {
[1089]329        Pel pix = pi[x];
[1029]330
331        UChar uc = pix & 0xff;     
332        fwrite( &uc, sizeof(UChar), 1, pFile );
333        uc = (pix >> 8) & 0xff;     
334        fwrite( &uc, sizeof(UChar), 1, pFile );
335      }
336      pi += stride;
[815]337    }
338  }
339 
[1029]340  fclose(pFile);
341}
342
343#if AUXILIARY_PICTURES
[1287]344Void TComPicYuv::convertToMonochrome(Int bitDepthChroma)
[1029]345{
[1287]346  Pel grayVal = (1 << (bitDepthChroma - 1));
[1029]347
[1031]348  for( UInt comp = 1; comp < getNumberValidComponents(); comp++ )
[815]349  {
[1031]350    const ComponentID ch=ComponentID(comp);
351    for( UInt i = 0; i < getStride(ch) * getTotalHeight(ch); i++ )
352    {
353      m_apiPicBuf[ch][i] = grayVal;
354    }
[815]355  }
356}
[1029]357#endif
[815]358
[313]359//! \}
Note: See TracBrowser for help on using the repository browser.