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

Last change on this file since 1550 was 1549, checked in by seregin, 9 years ago

port rev 4732, update copyright notice to include 2016

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