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

Last change on this file since 1302 was 1289, checked in by seregin, 9 years ago

port rev 4323 (g_uiMaxCUWidth, g_uiMaxCUHeight)

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