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

Last change on this file since 1443 was 1442, checked in by seregin, 10 years ago

port rev 4590

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