source: 3DVCSoftware/branches/HTM-16.0-MV-draft-5/source/Lib/TLibCommon/TComPicYuv.cpp @ 1390

Last change on this file since 1390 was 1390, checked in by tech, 9 years ago

Removed 3D.

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