source: SHVCSoftware/branches/SHM-upgrade/source/Lib/TLibCommon/TComPicYuv.cpp @ 1465

Last change on this file since 1465 was 916, checked in by seregin, 10 years ago

initial porting

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