source: 3DVCSoftware/branches/HTM-16.1-dev/source/Lib/TLibCommon/TComPicYuv.cpp @ 1401

Last change on this file since 1401 was 1401, checked in by tech, 8 years ago

Exchange copy right dates.

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