HEVC Test Model (HM)  HM-16.18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TComPicYuv.cpp
Go to the documentation of this file.
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-2017, 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 
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"
50 
53 
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  {
66  }
67 
68  m_bIsBorderExtended = false;
69 }
70 
71 
72 
73 
75 {
76  destroy();
77 }
78 
79 
80 
82  const Int picHeight,
83  const ChromaFormat chromaFormatIDC,
84  const Bool bUseMargin,
85  const UInt maxCUWidth,
86  const UInt maxCUHeight)
87 
88 {
89  destroy();
90 
91  m_picWidth = picWidth;
92  m_picHeight = picHeight;
93  m_chromaFormatIDC = chromaFormatIDC;
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
96  m_bIsBorderExtended = false;
97 
98  // assign the picture arrays and set up the ptr to the top left of the original picture
99  for(UInt comp=0; comp<getNumberValidComponents(); comp++)
100  {
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++)
113  {
114  m_ctuOffsetInBuffer[chan] = NULL;
115  m_subCuOffsetInBuffer[chan] = NULL;
116  }
117 }
118 
119 
120 
121 Void TComPicYuv::create ( const Int picWidth,
122  const Int picHeight,
123  const ChromaFormat chromaFormatIDC,
124  const UInt maxCUWidth,
125  const UInt maxCUHeight,
126  const UInt maxCUDepth,
127  const Bool bUseMargin)
128 
129 {
130  createWithoutCUInfo(picWidth, picHeight, chromaFormatIDC, bUseMargin, maxCUWidth, maxCUHeight);
131 
132 
133  const Int numCuInWidth = m_picWidth / maxCUWidth + (m_picWidth % maxCUWidth != 0);
134  const Int numCuInHeight = m_picHeight / maxCUHeight + (m_picHeight % maxCUHeight != 0);
135  for(Int chan=0; chan<MAX_NUM_CHANNEL_TYPE; chan++)
136  {
137  const ChannelType ch= ChannelType(chan);
138  const Int ctuHeight = maxCUHeight>>getChannelTypeScaleY(ch);
139  const Int ctuWidth = maxCUWidth>>getChannelTypeScaleX(ch);
140  const Int stride = getStride(ch);
141 
142  m_ctuOffsetInBuffer[chan] = new Int[numCuInWidth * numCuInHeight];
143 
144  for (Int cuRow = 0; cuRow < numCuInHeight; cuRow++)
145  {
146  for (Int cuCol = 0; cuCol < numCuInWidth; cuCol++)
147  {
148  m_ctuOffsetInBuffer[chan][cuRow * numCuInWidth + cuCol] = stride * cuRow * ctuHeight + cuCol * ctuWidth;
149  }
150  }
151 
152  m_subCuOffsetInBuffer[chan] = new Int[(size_t)1 << (2 * maxCUDepth)];
153 
154  const Int numSubBlockPartitions=(1<<maxCUDepth);
155  const Int minSubBlockHeight =(ctuHeight >> maxCUDepth);
156  const Int minSubBlockWidth =(ctuWidth >> maxCUDepth);
157 
158  for (Int buRow = 0; buRow < numSubBlockPartitions; buRow++)
159  {
160  for (Int buCol = 0; buCol < numSubBlockPartitions; buCol++)
161  {
162  m_subCuOffsetInBuffer[chan][(buRow << maxCUDepth) + buCol] = stride * buRow * minSubBlockHeight + buCol * minSubBlockWidth;
163  }
164  }
165  }
166 }
167 
169 {
170  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
171  {
172  m_piPicOrg[comp] = NULL;
173 
174  if( m_apiPicBuf[comp] )
175  {
176  xFree( m_apiPicBuf[comp] );
177  m_apiPicBuf[comp] = NULL;
178  }
179  }
180 
181  for(UInt chan=0; chan<MAX_NUM_CHANNEL_TYPE; chan++)
182  {
183  if (m_ctuOffsetInBuffer[chan])
184  {
185  delete[] m_ctuOffsetInBuffer[chan];
186  m_ctuOffsetInBuffer[chan] = NULL;
187  }
188  if (m_subCuOffsetInBuffer[chan])
189  {
190  delete[] m_subCuOffsetInBuffer[chan];
191  m_subCuOffsetInBuffer[chan] = NULL;
192  }
193  }
194 }
195 
196 
197 
199 {
200  assert( m_chromaFormatIDC == pcPicYuvDst->getChromaFormat() );
201 
202  for(Int comp=0; comp<getNumberValidComponents(); comp++)
203  {
204  const ComponentID compId=ComponentID(comp);
205  const Int width = getWidth(compId);
206  const Int height = getHeight(compId);
207  const Int strideSrc = getStride(compId);
208  assert(pcPicYuvDst->getWidth(compId) == width);
209  assert(pcPicYuvDst->getHeight(compId) == height);
210  if (strideSrc==pcPicYuvDst->getStride(compId))
211  {
212  ::memcpy ( pcPicYuvDst->getBuf(compId), getBuf(compId), sizeof(Pel)*strideSrc*getTotalHeight(compId));
213  }
214  else
215  {
216  const Pel *pSrc = getAddr(compId);
217  Pel *pDest = pcPicYuvDst->getAddr(compId);
218  const UInt strideDest = pcPicYuvDst->getStride(compId);
219 
220  for(Int y=0; y<height; y++, pSrc+=strideSrc, pDest+=strideDest)
221  {
222  ::memcpy(pDest, pSrc, width*sizeof(Pel));
223  }
224  }
225  }
226 }
227 
228 
230 {
231  if ( m_bIsBorderExtended )
232  {
233  return;
234  }
235 
236  for(Int comp=0; comp<getNumberValidComponents(); comp++)
237  {
238  const ComponentID compId=ComponentID(comp);
239  Pel *piTxt=getAddr(compId); // piTxt = point to (0,0) of image within bigger picture.
240  const Int stride=getStride(compId);
241  const Int width=getWidth(compId);
242  const Int height=getHeight(compId);
243  const Int marginX=getMarginX(compId);
244  const Int marginY=getMarginY(compId);
245 
246  Pel* pi = piTxt;
247  // do left and right margins
248  for (Int y = 0; y < height; y++)
249  {
250  for (Int x = 0; x < marginX; x++ )
251  {
252  pi[ -marginX + x ] = pi[0];
253  pi[ width + x ] = pi[width-1];
254  }
255  pi += stride;
256  }
257 
258  // pi is now the (0,height) (bottom left of image within bigger picture
259  pi -= (stride + marginX);
260  // pi is now the (-marginX, height-1)
261  for (Int y = 0; y < marginY; y++ )
262  {
263  ::memcpy( pi + (y+1)*stride, pi, sizeof(Pel)*(width + (marginX<<1)) );
264  }
265 
266  // pi is still (-marginX, height-1)
267  pi -= ((height-1) * stride);
268  // pi is now (-marginX, 0)
269  for (Int y = 0; y < marginY; y++ )
270  {
271  ::memcpy( pi - (y+1)*stride, pi, sizeof(Pel)*(width + (marginX<<1)) );
272  }
273  }
274 
275  m_bIsBorderExtended = true;
276 }
277 
278 
279 
280 // NOTE: This function is never called, but may be useful for developers.
281 Void TComPicYuv::dump (const std::string &fileName, const BitDepths &bitDepths, const Bool bAppend, const Bool bForceTo8Bit) const
282 {
283  FILE *pFile = fopen (fileName.c_str(), bAppend?"ab":"wb");
284 
285  Bool is16bit=false;
286  for(Int comp = 0; comp < getNumberValidComponents() && !bForceTo8Bit; comp++)
287  {
288  if (bitDepths.recon[toChannelType(ComponentID(comp))]>8)
289  {
290  is16bit=true;
291  }
292  }
293 
294  for(Int comp = 0; comp < getNumberValidComponents(); comp++)
295  {
296  const ComponentID compId = ComponentID(comp);
297  const Pel *pi = getAddr(compId);
298  const Int stride = getStride(compId);
299  const Int height = getHeight(compId);
300  const Int width = getWidth(compId);
301 
302  if (is16bit)
303  {
304  for (Int y = 0; y < height; y++ )
305  {
306  for (Int x = 0; x < width; x++ )
307  {
308  UChar uc = (UChar)((pi[x]>>0) & 0xff);
309  fwrite( &uc, sizeof(UChar), 1, pFile );
310  uc = (UChar)((pi[x]>>8) & 0xff);
311  fwrite( &uc, sizeof(UChar), 1, pFile );
312  }
313  pi += stride;
314  }
315  }
316  else
317  {
318  const Int shift = bitDepths.recon[toChannelType(compId)] - 8;
319  const Int offset = (shift>0)?(1<<(shift-1)):0;
320  for (Int y = 0; y < height; y++ )
321  {
322  for (Int x = 0; x < width; x++ )
323  {
324  UChar uc = (UChar)Clip3<Pel>(0, 255, (pi[x]+offset)>>shift);
325  fwrite( &uc, sizeof(UChar), 1, pFile );
326  }
327  pi += stride;
328  }
329  }
330  }
331 
332  fclose(pFile);
333 }
334 
Int m_marginX
margin of Luma channel (chroma&#39;s may be smaller, depending on ratio)
Definition: TComPicYuv.h:78
Int m_picHeight
Height of picture in pixels.
Definition: TComPicYuv.h:72
Void extendPicBorder()
Definition: TComPicYuv.cpp:229
picture YUV buffer class
Definition: TComPicYuv.h:55
ChannelType
Definition: TypeDef.h:301
void Void
Definition: TypeDef.h:203
Int getStride(const ComponentID id) const
Definition: TComPicYuv.h:121
#define NULL
Definition: CommonDef.h:107
Void createWithoutCUInfo(const Int picWidth, const Int picHeight, const ChromaFormat chromaFormatIDC, const Bool bUseMargin=false, const UInt maxCUWidth=0, const UInt maxCUHeight=0)
used for margin only
Definition: TComPicYuv.cpp:81
Int getHeight(const ComponentID id) const
Definition: TComPicYuv.h:117
unsigned int UInt
Definition: TypeDef.h:212
Pel * m_apiPicBuf[MAX_NUM_COMPONENT]
Buffer (including margin)
Definition: TComPicYuv.h:63
Short Pel
pixel type
Definition: TypeDef.h:249
Int recon[MAX_NUM_CHANNEL_TYPE]
the bit depth as indicated in the SPS
Definition: TypeDef.h:793
UInt getChannelTypeScaleY(const ChannelType id) const
Definition: TComPicYuv.h:154
YUV file I/O class (header)
Int * m_ctuOffsetInBuffer[MAX_NUM_CHANNEL_TYPE]
Gives an offset in the buffer for a given CTU (and channel)
Definition: TComPicYuv.h:75
Int getWidth(const ComponentID id) const
Definition: TComPicYuv.h:116
UInt getComponentScaleY(const ComponentID id) const
Definition: TComPicYuv.h:151
UInt getComponentScaleX(const ComponentID id) const
Definition: TComPicYuv.h:150
bool Bool
Definition: TypeDef.h:204
Void copyToPic(TComPicYuv *pcPicYuvDst) const
Definition: TComPicYuv.cpp:198
static ChannelType toChannelType(const ComponentID id)
virtual ~TComPicYuv()
Definition: TComPicYuv.cpp:74
Pel * m_piPicOrg[MAX_NUM_COMPONENT]
m_apiPicBufY + m_iMarginLuma*getStride() + m_iMarginLuma
Definition: TComPicYuv.h:65
Int getTotalHeight(const ComponentID id) const
Definition: TComPicYuv.h:125
ChromaFormat
chroma formats (according to semantics of chroma_format_idc)
Definition: TypeDef.h:292
#define xFree(ptr)
Definition: CommonDef.h:271
unsigned char UChar
Definition: TypeDef.h:208
Int m_marginY
margin of Luma channel (chroma&#39;s may be smaller, depending on ratio)
Definition: TComPicYuv.h:79
picture YUV buffer class (header)
UInt getNumberValidComponents() const
Definition: TComPicYuv.h:119
Int * m_subCuOffsetInBuffer[MAX_NUM_CHANNEL_TYPE]
Gives an offset in the buffer for a given sub-CU (and channel), relative to start of CTU...
Definition: TComPicYuv.h:76
#define xMalloc(type, len)
Definition: CommonDef.h:270
Int getMarginX(const ComponentID id) const
Definition: TComPicYuv.h:127
UInt getChannelTypeScaleX(const ChannelType id) const
Definition: TComPicYuv.h:153
Void dump(const std::string &fileName, const BitDepths &bitDepths, const Bool bAppend=false, const Bool bForceTo8Bit=false) const
Definition: TComPicYuv.cpp:281
Pel * getAddr(const ComponentID ch)
Definition: TComPicYuv.h:139
Void create(const Int picWidth, const Int picHeight, const ChromaFormat chromaFormatIDC, const UInt maxCUWidth, const UInt maxCUHeight, const UInt maxCUDepth, const Bool bUseMargin)
if true, then a margin of uiMaxCUWidth+16 and uiMaxCUHeight+16 is created around the image...
Definition: TComPicYuv.cpp:121
int Int
Definition: TypeDef.h:211
ComponentID
Definition: TypeDef.h:308
Int getMarginY(const ComponentID id) const
Definition: TComPicYuv.h:128
Int m_picWidth
Width of picture in pixels.
Definition: TComPicYuv.h:71
Pel * getBuf(const ComponentID ch)
Definition: TComPicYuv.h:135
ChromaFormat m_chromaFormatIDC
Chroma Format.
Definition: TComPicYuv.h:73
Void destroy()
Definition: TComPicYuv.cpp:168
Bool m_bIsBorderExtended
Definition: TComPicYuv.h:81
ChromaFormat getChromaFormat() const
Definition: TComPicYuv.h:118