Coverage Report

Created: 2026-06-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvdec/source/Lib/CommonLib/Buffer.h
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or 
4
other Intellectual Property Rights other than the copyrights concerning 
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
43
/** \file     Buffer.h
44
 *  \brief    Low-overhead class describing 2D memory layout
45
 */
46
47
#pragma once
48
49
#include "Common.h"
50
#include "CommonDef.h"
51
#include "ChromaFormat.h"
52
#include "MotionInfo.h"
53
54
#include <string.h>
55
#include <type_traits>
56
#include <utility>
57
58
namespace vvdec
59
{
60
61
struct CodingUnit;
62
63
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_X86)
64
using namespace x86_simd;
65
#endif
66
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_ARM)
67
using namespace arm_simd;
68
#endif
69
70
struct PelBufferOps
71
{
72
  PelBufferOps();
73
74
#if defined( TARGET_SIMD_X86 ) && ENABLE_SIMD_OPT_BUFFER
75
  void initPelBufOpsX86();
76
  template<X86_VEXT vext>
77
  void _initPelBufOpsX86();
78
#endif
79
80
#if defined( TARGET_SIMD_ARM ) && ENABLE_SIMD_OPT_BUFFER
81
  void initPelBufOpsARM();
82
  template<ARM_VEXT vext>
83
  void _initPelBufOpsARM();
84
#endif
85
86
  void ( *addAvg4 )       ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,            int shift, int offset,      const ClpRng& clpRng );
87
  void ( *addAvg8 )       ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,            int shift, int offset,      const ClpRng& clpRng );
88
  void ( *addAvg16 )      ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,            int shift, int offset,      const ClpRng& clpRng );
89
  void ( *reco4 )         ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,                                        const ClpRng& clpRng );
90
  void ( *reco8 )         ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,                                        const ClpRng& clpRng );
91
  void ( *linTf4 )        ( const Pel* src0, ptrdiff_t src0Stride,                                        Pel *dst, ptrdiff_t dstStride, int width, int height, int scale, int shift, int offset,      const ClpRng& clpRng, bool bClip );
92
  void ( *linTf8 )        ( const Pel* src0, ptrdiff_t src0Stride,                                        Pel *dst, ptrdiff_t dstStride, int width, int height, int scale, int shift, int offset,      const ClpRng& clpRng, bool bClip );
93
  void ( *wghtAvg4 )      ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height, int shift, int offset, int w0, int w1, const ClpRng& clpRng );
94
  void ( *wghtAvg8 )      ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height, int shift, int offset, int w0, int w1, const ClpRng& clpRng );
95
  void ( *copyBuffer  )    ( const char*src,  ptrdiff_t srcStride,        char* dst, ptrdiff_t  dstStride,                                int width, int height );
96
  void ( *transpose4x4 )  ( const Pel* src,  ptrdiff_t srcStride, Pel* dst, ptrdiff_t dstStride );
97
  void ( *transpose8x8 )  ( const Pel* src,  ptrdiff_t srcStride, Pel* dst, ptrdiff_t dstStride );
98
  void ( *applyLut )      (       Pel* ptr,  ptrdiff_t ptrStride, int width, int height, const Pel* lut );
99
  void ( *rspFwd )        (       Pel* ptr,  ptrdiff_t ptrStride, int width, int height, const int bd,                   const Pel OrgCW,  const Pel* LmcsPivot, const Pel* ScaleCoeff, const Pel* InputPivot );
100
  void ( *rspBcw )        (       Pel* ptr,  ptrdiff_t ptrStride, int width, int height, const int bd, const int minBin, const int maxBin, const Pel* LmcsPivot, const Pel* InvScCoeff, const Pel* InputPivot );
101
  void ( *fillN_CU )      (       CodingUnit** ptr, ptrdiff_t ptrStride, int width, int height, CodingUnit* cuPtr );
102
103
  void (*sampleRateConv)  ( const std::pair<int, int> scalingRatio, const std::pair<int, int> compScale,
104
                            const Pel* orgSrc, const ptrdiff_t orgStride, const int orgWidth, const int orgHeight,
105
                            const int beforeScaleLeftOffset, const int beforeScaleTopOffset,
106
                            Pel* scaledSrc, const ptrdiff_t scaledStride, const int scaledWidth, const int scaledHeight,
107
                            const int afterScaleLeftOffset, const int afterScaleTopOffset,
108
                            const int bitDepth, const bool useLumaFilter, const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag );
109
};
110
111
extern PelBufferOps g_pelBufOP;
112
113
void sampleRateConvCore( const std::pair<int, int> scalingRatio, const std::pair<int, int> compScale,
114
                         const Pel* orgSrc, const ptrdiff_t orgStride, const int orgWidth, const int orgHeight,
115
                         const int beforeScaleLeftOffset, const int beforeScaleTopOffset,
116
                         Pel* scaledSrc, const ptrdiff_t scaledStride, const int scaledWidth, const int scaledHeight,
117
                         const int afterScaleLeftOffset, const int afterScaleTopOffset,
118
                         const int bitDepth, const bool useLumaFilter,
119
                         const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag );
120
121
381k
#define INCX( ptr, stride ) { ptr++; }
122
46.6k
#define INCY( ptr, stride ) { ptr += ( stride ); }
123
0
#define OFFSETX( ptr, stride, x ) { ptr += ( x ); }
124
13.8k
#define OFFSETY( ptr, stride, y ) { ptr += ( y ) * ( stride ); }
125
1.27M
#define OFFSET( ptr, stride, x, y ) { ptr += ( x ) + ( y ) * ( stride ); }
126
0
#define GET_OFFSETX( ptr, stride, x ) ( ( ptr ) + ( x ) )
127
0
#define GET_OFFSETY( ptr, stride, y ) ( ( ptr ) + ( y ) * ( stride ) )
128
814k
#define GET_OFFSET( ptr, stride, x, y ) ( ( ptr ) + ( x ) + ( y ) * ( stride ) )
129
130
class Window;
131
struct BitDepths;
132
133
template<typename T>
134
struct AreaBuf : public Size
135
{
136
  T*        buf;
137
  ptrdiff_t stride;
138
139
850k
  AreaBuf()                                                                                     : Size(),                  buf( NULL ), stride( 0 )          { }
vvdec::AreaBuf<short const>::AreaBuf()
Line
Count
Source
139
2.26k
  AreaBuf()                                                                                     : Size(),                  buf( NULL ), stride( 0 )          { }
vvdec::AreaBuf<short>::AreaBuf()
Line
Count
Source
139
847k
  AreaBuf()                                                                                     : Size(),                  buf( NULL ), stride( 0 )          { }
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo>::AreaBuf()
140
0
  AreaBuf( T *_buf, const Size &size )                                                          : Size( size ),            buf( _buf ), stride( size.width ) { }
141
840k
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const Size &size )                                : Size( size ),            buf( _buf ), stride( _stride )    { }
Unexecuted instantiation: vvdec::AreaBuf<short const>::AreaBuf(short const*, long const&, vvdec::Size const&)
vvdec::AreaBuf<short>::AreaBuf(short*, long const&, vvdec::Size const&)
Line
Count
Source
141
840k
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const Size &size )                                : Size( size ),            buf( _buf ), stride( _stride )    { }
142
118k
  AreaBuf( T *_buf, const SizeType &_width, const SizeType &_height )                           : Size( _width, _height ), buf( _buf ), stride( _width )     { }
vvdec::AreaBuf<short>::AreaBuf(short*, unsigned int const&, unsigned int const&)
Line
Count
Source
142
35.9k
  AreaBuf( T *_buf, const SizeType &_width, const SizeType &_height )                           : Size( _width, _height ), buf( _buf ), stride( _width )     { }
vvdec::AreaBuf<short const>::AreaBuf(short const*, unsigned int const&, unsigned int const&)
Line
Count
Source
142
2.77k
  AreaBuf( T *_buf, const SizeType &_width, const SizeType &_height )                           : Size( _width, _height ), buf( _buf ), stride( _width )     { }
vvdec::AreaBuf<int>::AreaBuf(int*, unsigned int const&, unsigned int const&)
Line
Count
Source
142
79.6k
  AreaBuf( T *_buf, const SizeType &_width, const SizeType &_height )                           : Size( _width, _height ), buf( _buf ), stride( _width )     { }
143
269k
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const SizeType &_width, const SizeType &_height ) : Size( _width, _height ), buf( _buf ), stride( _stride )    { }
vvdec::AreaBuf<short>::AreaBuf(short*, long const&, unsigned int const&, unsigned int const&)
Line
Count
Source
143
150k
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const SizeType &_width, const SizeType &_height ) : Size( _width, _height ), buf( _buf ), stride( _stride )    { }
vvdec::AreaBuf<vvdec::MotionInfo>::AreaBuf(vvdec::MotionInfo*, long const&, unsigned int const&, unsigned int const&)
Line
Count
Source
143
106k
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const SizeType &_width, const SizeType &_height ) : Size( _width, _height ), buf( _buf ), stride( _stride )    { }
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo const>::AreaBuf(vvdec::MotionInfo const*, long const&, unsigned int const&, unsigned int const&)
vvdec::AreaBuf<short const>::AreaBuf(short const*, long const&, unsigned int const&, unsigned int const&)
Line
Count
Source
143
12.1k
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const SizeType &_width, const SizeType &_height ) : Size( _width, _height ), buf( _buf ), stride( _stride )    { }
144
145
  AreaBuf( const AreaBuf& )  = default;
146
  AreaBuf(       AreaBuf&& ) = default;
147
  AreaBuf& operator=( const AreaBuf& )  = default;
148
  AreaBuf& operator=(       AreaBuf&& ) = default;
149
150
  // conversion from AreaBuf<const T> to AreaBuf<T>
151
  template<bool T_IS_CONST = std::is_const<T>::value>
152
438k
  AreaBuf( const AreaBuf<typename std::remove_const_t<T>>& other, std::enable_if_t<T_IS_CONST>* = 0) : Size( other ), buf( other.buf ), stride( other.stride ) { }
vvdec::AreaBuf<short const>::AreaBuf<true>(vvdec::AreaBuf<short> const&, std::__1::enable_if<true, void>::type*)
Line
Count
Source
152
358k
  AreaBuf( const AreaBuf<typename std::remove_const_t<T>>& other, std::enable_if_t<T_IS_CONST>* = 0) : Size( other ), buf( other.buf ), stride( other.stride ) { }
vvdec::AreaBuf<int const>::AreaBuf<true>(vvdec::AreaBuf<int> const&, std::__1::enable_if<true, void>::type*)
Line
Count
Source
152
79.9k
  AreaBuf( const AreaBuf<typename std::remove_const_t<T>>& other, std::enable_if_t<T_IS_CONST>* = 0) : Size( other ), buf( other.buf ), stride( other.stride ) { }
153
154
  void fill                 ( const T &val );
155
  void memset               ( const int val );
156
157
  void copyFrom             ( const AreaBuf<const T> &other );
158
  
159
  void reconstruct          ( const AreaBuf<const T> &pred, const AreaBuf<const T> &resi, const ClpRng& clpRng);
160
  
161
  void subtract             ( const AreaBuf<const T> &other );
162
  void extendBorderPel      ( unsigned margin );
163
  void extendBorderPel      ( unsigned margin, bool left, bool right, bool top, bool bottom );
164
  void addWeightedAvg       ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng, const int8_t bcwIdx);
165
  void addAvg               ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng );
166
  void padBorderPel         ( unsigned marginX, unsigned marginY, int dir );
167
  
168
  void linearTransform      ( const int scale, const int shift, const int offset, bool bClip, const ClpRng& clpRng );
169
170
  void transposedFrom       ( const AreaBuf<const T> &other );
171
172
  void scaleSignal          ( const int scale, const ClpRng& clpRng );
173
174
1.61M
        T& at( const int &x, const int &y )          { return buf[y * stride + x]; }
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo>::at(int const&, int const&)
vvdec::AreaBuf<short>::at(int const&, int const&)
Line
Count
Source
174
1.61M
        T& at( const int &x, const int &y )          { return buf[y * stride + x]; }
175
1.95M
  const T& at( const int &x, const int &y ) const    { return buf[y * stride + x]; }
vvdec::AreaBuf<short const>::at(int const&, int const&) const
Line
Count
Source
175
1.50M
  const T& at( const int &x, const int &y ) const    { return buf[y * stride + x]; }
vvdec::AreaBuf<int const>::at(int const&, int const&) const
Line
Count
Source
175
450k
  const T& at( const int &x, const int &y ) const    { return buf[y * stride + x]; }
176
177
        T& at( const Position &pos )                 { return buf[pos.y * stride + pos.x]; }
178
  const T& at( const Position &pos ) const           { return buf[pos.y * stride + pos.x]; }
179
180
181
94.8k
        T* bufAt( const int &x, const int &y )       { return GET_OFFSET( buf, stride,     x,     y ); }
vvdec::AreaBuf<short>::bufAt(int const&, int const&)
Line
Count
Source
181
82.4k
        T* bufAt( const int &x, const int &y )       { return GET_OFFSET( buf, stride,     x,     y ); }
vvdec::AreaBuf<short const>::bufAt(int const&, int const&)
Line
Count
Source
181
12.4k
        T* bufAt( const int &x, const int &y )       { return GET_OFFSET( buf, stride,     x,     y ); }
182
0
  const T* bufAt( const int &x, const int &y ) const { return GET_OFFSET( buf, stride,     x,     y ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::bufAt(int const&, int const&) const
Unexecuted instantiation: vvdec::AreaBuf<short const>::bufAt(int const&, int const&) const
183
719k
        T* bufAt( const Position& pos )              { return GET_OFFSET( buf, stride, pos.x, pos.y ); }
vvdec::AreaBuf<short>::bufAt(vvdec::Position const&)
Line
Count
Source
183
719k
        T* bufAt( const Position& pos )              { return GET_OFFSET( buf, stride, pos.x, pos.y ); }
Unexecuted instantiation: vvdec::AreaBuf<short const>::bufAt(vvdec::Position const&)
184
18
  const T* bufAt( const Position& pos ) const        { return GET_OFFSET( buf, stride, pos.x, pos.y ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::bufAt(vvdec::Position const&) const
vvdec::AreaBuf<short const>::bufAt(vvdec::Position const&) const
Line
Count
Source
184
18
  const T* bufAt( const Position& pos ) const        { return GET_OFFSET( buf, stride, pos.x, pos.y ); }
185
186
589k
  AreaBuf<      T> subBuf( const Area &area )                                                         { return subBuf( area.pos(), area.size() ); }
187
0
  AreaBuf<const T> subBuf( const Area &area )                                                   const { return subBuf( area.pos(), area.size() ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::subBuf(vvdec::Area const&) const
Unexecuted instantiation: vvdec::AreaBuf<short const>::subBuf(vvdec::Area const&) const
188
681k
  AreaBuf<      T> subBuf( const Position &pos, const Size &size )                                    { return AreaBuf<      T>( bufAt( pos  ), stride, size   ); }
189
0
  AreaBuf<const T> subBuf( const Position &pos, const Size &size )                              const { return AreaBuf<const T>( bufAt( pos  ), stride, size   ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::subBuf(vvdec::Position const&, vvdec::Size const&) const
Unexecuted instantiation: vvdec::AreaBuf<short const>::subBuf(vvdec::Position const&, vvdec::Size const&) const
190
380
  AreaBuf<      T> subBuf( const int &x, const int &y, const unsigned &_w, const unsigned &_h )       { return AreaBuf<      T>( bufAt( x, y ), stride, _w, _h ); }
191
  AreaBuf<const T> subBuf( const int &x, const int &y, const unsigned &_w, const unsigned &_h ) const { return AreaBuf<const T>( bufAt( x, y ), stride, _w, _h ); }
192
};
193
194
typedef AreaBuf<      Pel>  PelBuf;
195
typedef AreaBuf<const Pel> CPelBuf;
196
197
typedef AreaBuf<      TCoeff>  CoeffBuf;
198
typedef AreaBuf<const TCoeff> CCoeffBuf;
199
200
typedef AreaBuf<TCoeffSig>        CoeffSigBuf;
201
typedef AreaBuf<const TCoeffSig> CCoeffSigBuf;
202
203
typedef AreaBuf<      MotionInfo>  MotionBuf;
204
typedef AreaBuf<const MotionInfo> CMotionBuf;
205
206
typedef AreaBuf<      LoopFilterParam>  LFPBuf;
207
typedef AreaBuf<const LoopFilterParam> CLFPBuf;
208
209
3.16k
#define SIZE_AWARE_PER_EL_OP( OP, INC )                     \
210
3.16k
if( ( width & 7 ) == 0 )                                    \
211
1.69k
{                                                           \
212
47.6k
  for( int y = 0; y < height; y++ )                         \
213
46.0k
  {                                                         \
214
222k
    for( int x = 0; x < width; x += 8 )                     \
215
176k
    {                                                       \
216
176k
      OP( x + 0 );                                          \
217
176k
      OP( x + 1 );                                          \
218
176k
      OP( x + 2 );                                          \
219
176k
      OP( x + 3 );                                          \
220
176k
      OP( x + 4 );                                          \
221
176k
      OP( x + 5 );                                          \
222
176k
      OP( x + 6 );                                          \
223
176k
      OP( x + 7 );                                          \
224
176k
    }                                                       \
225
46.0k
                                                            \
226
46.0k
    INC;                                                    \
227
46.0k
  }                                                         \
228
1.69k
}                                                           \
229
3.16k
else if( ( width & 3 ) == 0 )                               \
230
28
{                                                           \
231
332
  for( int y = 0; y < height; y++ )                         \
232
304
  {                                                         \
233
608
    for( int x = 0; x < width; x += 4 )                     \
234
304
    {                                                       \
235
304
      OP( x + 0 );                                          \
236
304
      OP( x + 1 );                                          \
237
304
      OP( x + 2 );                                          \
238
304
      OP( x + 3 );                                          \
239
304
    }                                                       \
240
304
                                                            \
241
304
    INC;                                                    \
242
304
  }                                                         \
243
28
}                                                           \
244
1.46k
else if( ( width & 1 ) == 0 )                               \
245
1.25k
{                                                           \
246
24.4k
  for( int y = 0; y < height; y++ )                         \
247
23.1k
  {                                                         \
248
46.3k
    for( int x = 0; x < width; x += 2 )                     \
249
23.1k
    {                                                       \
250
23.1k
      OP( x + 0 );                                          \
251
23.1k
      OP( x + 1 );                                          \
252
23.1k
    }                                                       \
253
23.1k
                                                            \
254
23.1k
    INC;                                                    \
255
23.1k
  }                                                         \
256
1.25k
}                                                           \
257
1.44k
else                                                        \
258
182
{                                                           \
259
4.31k
  for( int y = 0; y < height; y++ )                         \
260
4.12k
  {                                                         \
261
8.25k
    for( int x = 0; x < width; x++ )                        \
262
4.12k
    {                                                       \
263
4.12k
      OP( x );                                              \
264
4.12k
    }                                                       \
265
4.12k
                                                            \
266
4.12k
    INC;                                                    \
267
4.12k
  }                                                         \
268
182
}
269
270
271
template<typename TOP, typename TINC>
272
static inline void size_aware_pel_op( TOP op, TINC inc, int width, int height )
273
{
274
  if( ( width & 7 ) == 0 )
275
  {
276
    for( int y = 0; y < height; y++ )
277
    {
278
      for( int x = 0; x < width; x += 8 )
279
      {
280
        op( x + 0 );
281
        op( x + 1 );
282
        op( x + 2 );
283
        op( x + 3 );
284
        op( x + 4 );
285
        op( x + 5 );
286
        op( x + 6 );
287
        op( x + 7 );
288
      }
289
290
      inc();
291
    }
292
  }
293
  else if( ( width & 3 ) == 0 )
294
  {
295
    for( int y = 0; y < height; y++ )
296
    {
297
      for( int x = 0; x < width; x += 4 )
298
      {
299
        op( x + 0 );
300
        op( x + 1 );
301
        op( x + 2 );
302
        op( x + 3 );
303
      }
304
305
      inc();
306
    }
307
  }
308
  else if( ( width & 1 ) == 0 )
309
  {
310
    for( int y = 0; y < height; y++ )
311
    {
312
      for( int x = 0; x < width; x += 2 )
313
      {
314
        op( x + 0 );
315
        op( x + 1 );
316
      }
317
318
      inc();
319
    }
320
  }
321
  else
322
  {
323
    for( int y = 0; y < height; y++ )
324
    {
325
      for( int x = 0; x < width; x++ )
326
      {
327
        op( x );
328
      }
329
330
      inc();
331
    }
332
  }
333
}
334
335
template<>
336
void AreaBuf<MotionInfo>::fill( const MotionInfo& val );
337
338
template<typename T>
339
void AreaBuf<T>::fill(const T &val)
340
19.5k
{
341
19.5k
  if( T( 0 ) == val )
342
888
  {
343
888
    if( width == stride )
344
31
    {
345
31
      ::memset( buf, 0, width * height * sizeof( T ) );
346
31
    }
347
857
    else
348
857
    {
349
857
      T* dest = buf;
350
857
      size_t line = width * sizeof( T );
351
352
51.2k
      for( unsigned y = 0; y < height; y++ )
353
50.4k
      {
354
50.4k
        ::memset( dest, 0, line );
355
356
50.4k
        dest += stride;
357
50.4k
      }
358
857
    }
359
888
  }
360
18.6k
  else
361
18.6k
  {
362
18.6k
    if( width == stride )
363
2.81k
    {
364
2.81k
      std::fill_n( buf, width * height, val );
365
2.81k
    }
366
15.8k
    else
367
15.8k
    {
368
15.8k
      T* dest = buf;
369
370
396k
      for( int y = 0; y < height; y++, dest += stride )
371
380k
      {
372
380k
        std::fill_n( dest, width, val );
373
380k
      }
374
15.8k
    }
375
18.6k
  }
376
19.5k
}
377
378
template<typename T>
379
void AreaBuf<T>::memset( const int val )
380
307k
{
381
307k
  if( width == stride )
382
79.6k
  {
383
79.6k
    ::memset( NO_WARNING_class_memaccess( buf ), val, width * height * sizeof( T ) );
384
79.6k
  }
385
227k
  else
386
227k
  {
387
227k
    T* dest = buf;
388
227k
    size_t line = width * sizeof( T );
389
390
1.24M
    for( int y = 0; y < height; y++ )
391
1.01M
    {
392
1.01M
      ::memset( NO_WARNING_class_memaccess( dest ), val, line );
393
394
1.01M
      dest += stride;
395
1.01M
    }
396
227k
  }
397
307k
}
vvdec::AreaBuf<int>::memset(int)
Line
Count
Source
380
79.6k
{
381
79.6k
  if( width == stride )
382
79.6k
  {
383
79.6k
    ::memset( NO_WARNING_class_memaccess( buf ), val, width * height * sizeof( T ) );
384
79.6k
  }
385
1
  else
386
1
  {
387
1
    T* dest = buf;
388
1
    size_t line = width * sizeof( T );
389
390
1
    for( int y = 0; y < height; y++ )
391
0
    {
392
0
      ::memset( NO_WARNING_class_memaccess( dest ), val, line );
393
394
0
      dest += stride;
395
0
    }
396
1
  }
397
79.6k
}
vvdec::AreaBuf<short>::memset(int)
Line
Count
Source
380
143k
{
381
143k
  if( width == stride )
382
0
  {
383
0
    ::memset( NO_WARNING_class_memaccess( buf ), val, width * height * sizeof( T ) );
384
0
  }
385
143k
  else
386
143k
  {
387
143k
    T* dest = buf;
388
143k
    size_t line = width * sizeof( T );
389
390
937k
    for( int y = 0; y < height; y++ )
391
793k
    {
392
793k
      ::memset( NO_WARNING_class_memaccess( dest ), val, line );
393
394
793k
      dest += stride;
395
793k
    }
396
143k
  }
397
143k
}
vvdec::AreaBuf<vvdec::MotionInfo>::memset(int)
Line
Count
Source
380
83.5k
{
381
83.5k
  if( width == stride )
382
0
  {
383
0
    ::memset( NO_WARNING_class_memaccess( buf ), val, width * height * sizeof( T ) );
384
0
  }
385
83.5k
  else
386
83.5k
  {
387
83.5k
    T* dest = buf;
388
83.5k
    size_t line = width * sizeof( T );
389
390
309k
    for( int y = 0; y < height; y++ )
391
225k
    {
392
225k
      ::memset( NO_WARNING_class_memaccess( dest ), val, line );
393
394
225k
      dest += stride;
395
225k
    }
396
83.5k
  }
397
83.5k
}
398
399
#if ENABLE_SIMD_OPT_BUFFER
400
template<typename T>
401
void AreaBuf<T>::copyFrom( const AreaBuf<const T> &other )
402
87.6k
{
403
#if !defined(__GNUC__) || __GNUC__ > 5
404
  static_assert( std::is_trivially_copyable<T>::value, "Type T is not trivially_copyable" );
405
#endif
406
407
87.6k
  g_pelBufOP.copyBuffer( (const char *) other.buf, sizeof( T ) * other.stride, (char *) buf, sizeof( T ) * stride, sizeof( T ) * width, height );
408
87.6k
}
409
#else
410
template<typename T>
411
void AreaBuf<T>::copyFrom( const AreaBuf<const T> &other )
412
{
413
#if !defined(__GNUC__) || __GNUC__ > 5
414
  static_assert( std::is_trivially_copyable<T>::value, "Type T is not trivially_copyable" );
415
#endif
416
417
  CHECK_FATAL( width  != other.width,  "Incompatible size" );
418
  CHECK_FATAL( height != other.height, "Incompatible size" );
419
420
  if( buf == other.buf )
421
  {
422
    return;
423
  }
424
425
  if( ptrdiff_t( width ) == stride && stride == other.stride )
426
  {
427
    memcpy( buf, other.buf, width * height * sizeof( T ) );
428
  }
429
  else
430
  {
431
          T* dst              =       buf;
432
    const T* src              = other.buf;
433
    const ptrdiff_t srcStride = other.stride;
434
435
    for( unsigned y = 0; y < height; y++ )
436
    {
437
      memcpy( dst, src, width * sizeof( T ) );
438
439
      dst += stride;
440
      src += srcStride;
441
    }
442
  }
443
}
444
#endif
445
446
447
template<typename T>
448
void AreaBuf<T>::subtract( const AreaBuf<const T> &other )
449
{
450
  CHECK( width  != other.width,  "Incompatible size" );
451
  CHECK( height != other.height, "Incompatible size" );
452
453
        T* dest =       buf;
454
  const T* subs = other.buf;
455
456
#define SUBS_INC        \
457
  dest +=       stride; \
458
  subs += other.stride; \
459
460
#define SUBS_OP( ADDR ) dest[ADDR] -= subs[ADDR]
461
462
  SIZE_AWARE_PER_EL_OP( SUBS_OP, SUBS_INC );
463
464
#undef SUBS_OP
465
#undef SUBS_INC
466
}
467
468
template<typename T>
469
void AreaBuf<T>::reconstruct( const AreaBuf<const T> &pred, const AreaBuf<const T> &resi, const ClpRng& clpRng )
470
{
471
  THROW_FATAL( "Type not supported" );
472
}
473
474
template<>
475
void AreaBuf<Pel>::reconstruct( const AreaBuf<const Pel> &pred, const AreaBuf<const Pel> &resi, const ClpRng& clpRng );
476
477
478
template<typename T>
479
void AreaBuf<T>::addAvg( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng )
480
{
481
  THROW_FATAL( "Type not supported" );
482
}
483
484
template<>
485
void AreaBuf<Pel>::addAvg( const AreaBuf<const Pel> &other1, const AreaBuf<const Pel> &other2, const ClpRng& clpRng );
486
487
template<typename T>
488
void AreaBuf<T>::linearTransform( const int scale, const int shift, const int offset, bool bClip, const ClpRng& clpRng )
489
{
490
  THROW_FATAL( "Type not supported" );
491
}
492
493
template<>
494
void AreaBuf<Pel>::linearTransform( const int scale, const int shift, const int offset, bool bClip, const ClpRng& clpRng );
495
496
template<typename T>
497
void AreaBuf<T>::extendBorderPel( unsigned margin )
498
0
{
499
0
  T*        p = buf;
500
0
  int       h = height;
501
0
  int       w = width;
502
0
  ptrdiff_t s = stride;
503
504
0
  CHECK( ( w + 2 * margin ) > s, "Size of buffer too small to extend" );
505
  // do left and right margins
506
0
  for( int y = 0; y < h; y++ )
507
0
  {
508
0
    for( int x = 0; x < margin; x++ )
509
0
    {
510
0
      *( p - margin + x ) = p[0];
511
0
      p[w + x]            = p[w - 1];
512
0
    }
513
0
    p += s;
514
0
  }
515
516
  // p is now the (0,height) (bottom left of image within bigger picture
517
0
  p -= ( s + margin );
518
  // p is now the (-margin, height-1)
519
0
  for( int y = 0; y < margin; y++ )
520
0
  {
521
0
    ::memcpy( p + ( y + 1 ) * s, p, sizeof( T ) * ( w + ( margin << 1 ) ) );
522
0
  }
523
524
  // pi is still (-marginX, height-1)
525
0
  p -= ( ( h - 1 ) * s );
526
  // pi is now (-marginX, 0)
527
0
  for( int y = 0; y < margin; y++ )
528
0
  {
529
0
    ::memcpy( p - ( y + 1 ) * s, p, sizeof( T ) * ( w + ( margin << 1 ) ) );
530
0
  }
531
0
}
532
533
template<typename T>
534
void AreaBuf<T>::extendBorderPel(unsigned margin, bool left, bool right, bool top, bool bottom)
535
54
{
536
54
  CHECK( ( width + left*margin + right*margin) > stride, "Size of buffer too small to extend" );
537
  // do left and right margins
538
539
54
  if( left && right )
540
6
  {
541
6
    T* p = buf;
542
134
    for( int y = 0; y < height; y++ )
543
128
    {
544
640
      for( int x = 0; x < margin; x++ )
545
512
      {
546
512
        p[-(int)margin + x] = p[0];
547
512
        p[width + x]   = p[width - 1];
548
512
      }
549
128
      p += stride;
550
128
    }
551
6
  }
552
553
48
  else if( left )
554
12
  {
555
12
    T* p = buf;
556
1.03k
    for( int y = 0; y < height; y++ )
557
1.02k
    {
558
5.12k
      for( int x = 0; x < margin; x++ )
559
4.09k
      {
560
4.09k
        p[-(int)margin + x] = p[0];
561
4.09k
      }
562
1.02k
      p += stride;
563
1.02k
    }
564
12
  }
565
566
36
  else if( right )
567
12
  {
568
12
    T* p = buf;
569
1.03k
    for( int y = 0; y < height; y++ )
570
1.02k
    {
571
5.12k
      for( int x = 0; x < margin; x++ )
572
4.09k
      {
573
4.09k
        p[width + x] = p[width - 1];
574
4.09k
      }
575
1.02k
      p += stride;
576
1.02k
    }
577
12
  }
578
579
54
  const int copylen = width + ( left ? margin : 0 ) + ( right ? margin : 0 );
580
54
  if( bottom )
581
18
  {
582
18
    T* p = buf + stride * height;
583
18
    if( left )
584
9
      p -= margin;
585
586
    // p is now the (-margin, height)
587
90
    for( int y = 0; y < margin; y++ )
588
72
    {
589
72
      ::memcpy( p + y * stride, p - stride, sizeof( T ) * copylen );
590
72
    }
591
18
  }
592
593
54
  if( top )
594
18
  {
595
18
    T* p = buf;
596
18
    if( left )
597
9
      p -= margin;
598
599
    // pi is now (-marginX, 0)
600
90
    for( int y = -(int)margin; y < 0; y++ )
601
72
    {
602
72
      ::memcpy( p + y * stride, p, sizeof( T ) * copylen );
603
72
    }
604
18
  }
605
54
}
606
607
template<typename T>
608
void AreaBuf<T>::padBorderPel( unsigned marginX, unsigned marginY, int dir )
609
0
{
610
0
  T*   p = buf;
611
0
  auto s = stride;
612
0
  int  h = height;
613
0
  int  w = width;
614
615
0
  CHECK( w  > s, "Size of buffer too small to extend" );
616
617
  // top-left margin
618
0
  if ( dir == 1 )
619
0
  {
620
0
    for( int y = 0; y < marginY; y++ )
621
0
    {
622
0
      for( int x = 0; x < marginX; x++ )
623
0
      {
624
0
        p[x] = p[marginX];
625
0
      }
626
0
      p += s;
627
0
    }
628
0
  }
629
630
  // bottom-right margin
631
0
  if ( dir == 2 )
632
0
  {
633
0
    p = buf + s * ( h - marginY ) + w - marginX;
634
635
0
    for( int y = 0; y < marginY; y++ )
636
0
    {
637
0
      for( int x = 0; x < marginX; x++ )
638
0
      {
639
0
        p[x] = p[-1];
640
0
      }
641
0
      p += s;
642
0
    }
643
0
  }
644
0
}
645
646
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_X86)
647
template<> void AreaBuf<Pel>::transposedFrom( const AreaBuf<const Pel> &other );
648
#endif
649
650
template<typename T>
651
void AreaBuf<T>::transposedFrom( const AreaBuf<const T> &other )
652
{
653
  CHECK( width * height != other.width * other.height, "Incompatible size" );
654
655
        T* dst  =       buf;
656
  const T* src  = other.buf;
657
  width         = other.height;
658
  height        = other.width;
659
  stride        = stride < width ? width : stride;
660
661
  for( unsigned y = 0; y < other.height; y++ )
662
  {
663
    for( unsigned x = 0; x < other.width; x++ )
664
    {
665
      dst[y + x*stride] = src[x + y * other.stride];
666
    }
667
  }
668
}
669
670
#ifndef DONT_UNDEF_SIZE_AWARE_PER_EL_OP
671
#undef SIZE_AWARE_PER_EL_OP
672
#endif // !DONT_UNDEF_SIZE_AWARE_PER_EL_OP
673
674
// ---------------------------------------------------------------------------
675
// UnitBuf struct
676
// ---------------------------------------------------------------------------
677
678
struct UnitArea;
679
680
template<typename T>
681
struct UnitBuf
682
{
683
  typedef static_vector<AreaBuf<T>,       MAX_NUM_COMPONENT> UnitBufBuffers;
684
685
  ChromaFormat chromaFormat;
686
  UnitBufBuffers bufs;
687
688
175k
  UnitBuf() : chromaFormat( NUM_CHROMA_FORMAT ) { }
vvdec::UnitBuf<short>::UnitBuf()
Line
Count
Source
688
175k
  UnitBuf() : chromaFormat( NUM_CHROMA_FORMAT ) { }
Unexecuted instantiation: vvdec::UnitBuf<short const>::UnitBuf()
689
  UnitBuf( const ChromaFormat &_chromaFormat, const UnitBufBuffers&  _bufs ) : chromaFormat( _chromaFormat ), bufs( _bufs ) { }
690
  UnitBuf( const ChromaFormat &_chromaFormat,       UnitBufBuffers&& _bufs ) : chromaFormat( _chromaFormat ), bufs( std::forward<UnitBufBuffers>( _bufs ) ) { }
691
0
  UnitBuf( const ChromaFormat &_chromaFormat, const AreaBuf<T>  &blkY ) : chromaFormat( _chromaFormat ), bufs{ blkY } { }
692
0
  UnitBuf( const ChromaFormat &_chromaFormat,       AreaBuf<T> &&blkY ) : chromaFormat( _chromaFormat ), bufs{ std::forward<AreaBuf<T> >(blkY) } { }
693
0
  UnitBuf( const ChromaFormat &_chromaFormat, const AreaBuf<T>  &blkY, const AreaBuf<T>  &blkCb, const AreaBuf<T>  &blkCr ) : chromaFormat( _chromaFormat ), bufs{ blkY, blkCb, blkCr } { if( chromaFormat == CHROMA_400 ) bufs.resize( 1 ); }
694
0
  UnitBuf( const ChromaFormat &_chromaFormat,       AreaBuf<T> &&blkY,       AreaBuf<T> &&blkCb,       AreaBuf<T> &&blkCr ) : chromaFormat( _chromaFormat ), bufs{ std::forward<AreaBuf<T> >(blkY), std::forward<AreaBuf<T> >(blkCb), std::forward<AreaBuf<T> >(blkCr) } { if( chromaFormat == CHROMA_400 ) bufs.resize( 1 ); }
695
696
  UnitBuf( const UnitBuf& other )  = default;
697
  UnitBuf(       UnitBuf&& other ) = default;
698
  UnitBuf& operator=( const UnitBuf& other )  = default;
699
  UnitBuf& operator=(       UnitBuf&& other ) = default;
700
701
  // conversion from UnitBuf<const T> to UnitBuf<T>
702
  template<bool T_IS_COST = std::is_const<T>::value>
703
755
  UnitBuf( const UnitBuf<typename std::remove_const_t<T>>& other, std::enable_if_t<T_IS_COST>* = 0 ) : chromaFormat( other.chromaFormat ), bufs( other.bufs ) { }
704
705
40.5k
        AreaBuf<T>& get( const ComponentID comp )        { return bufs[comp]; }
706
686
  const AreaBuf<T>& get( const ComponentID comp )  const { return bufs[comp]; }
vvdec::UnitBuf<short>::get(vvdec::ComponentID) const
Line
Count
Source
706
285
  const AreaBuf<T>& get( const ComponentID comp )  const { return bufs[comp]; }
vvdec::UnitBuf<short const>::get(vvdec::ComponentID) const
Line
Count
Source
706
401
  const AreaBuf<T>& get( const ComponentID comp )  const { return bufs[comp]; }
707
708
18.5k
        AreaBuf<T>& Y()        { return bufs[0]; }
709
272
  const AreaBuf<T>& Y()  const { return bufs[0]; }
710
18.6k
        AreaBuf<T>& Cb()       { return bufs[1]; }
711
  const AreaBuf<T>& Cb() const { return bufs[1]; }
712
0
        AreaBuf<T>& Cr()       { return bufs[2]; }
713
  const AreaBuf<T>& Cr() const { return bufs[2]; }
714
715
  void fill                 ( const T &val );
716
  void copyFrom             ( const UnitBuf<const T> &other );
717
  void reconstruct          ( const UnitBuf<const T> &pred, const UnitBuf<const T> &resi, const ClpRngs& clpRngs );
718
  void subtract             ( const UnitBuf<const T> &other );
719
  void addWeightedAvg       ( const UnitBuf<      T> &other1, const UnitBuf<      T> &other2, const ClpRngs& clpRngs, const uint8_t bcwIdx = BCW_DEFAULT, const bool chromaOnly = false, const bool lumaOnly = false);
720
  void addAvg               ( const UnitBuf<      T> &other1, const UnitBuf<      T> &other2, const ClpRngs& clpRngs, const bool chromaOnly = false, const bool lumaOnly = false);
721
  void extendBorderPel      ( unsigned margin );
722
  void extendBorderPel      ( unsigned margin, bool left, bool right, bool top, bool bottom );
723
  void padBorderPel         ( unsigned margin, int dir );
724
725
        UnitBuf<      T> subBuf (const Area& subArea);
726
  const UnitBuf<const T> subBuf (const Area& subArea) const;
727
        UnitBuf<      T> subBuf (const UnitArea& subArea);
728
  const UnitBuf<const T> subBuf (const UnitArea& subArea) const;
729
  void colorSpaceConvert    ( const UnitBuf<T> &other, const ClpRng& clpRng );
730
731
  void writeToFile( std::string filename ) const;   // for debug purposes
732
};
733
734
typedef UnitBuf<      Pel>  PelUnitBuf;
735
typedef UnitBuf<const Pel> CPelUnitBuf;
736
737
typedef UnitBuf<      TCoeff>  CoeffUnitBuf;
738
typedef UnitBuf<const TCoeff> CCoeffUnitBuf;
739
740
}   // namespace vvdec
741
742
#include <Unit.h>
743
744
namespace vvdec
745
{
746
template<typename T>
747
void UnitBuf<T>::fill( const T &val )
748
{
749
  for( unsigned i = 0; i < bufs.size(); i++ )
750
  {
751
    bufs[i].fill( val );
752
  }
753
}
754
755
template<typename T>
756
void UnitBuf<T>::copyFrom( const UnitBuf<const T> &other )
757
3
{
758
3
  CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" );
759
760
12
  for( unsigned i = 0; i < bufs.size(); i++ )
761
9
  {
762
9
    bufs[i].copyFrom( other.bufs[i] );
763
9
  }
764
3
}
765
766
767
768
template<typename T>
769
void UnitBuf<T>::subtract( const UnitBuf<const T> &other )
770
{
771
  CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" );
772
773
  for( unsigned i = 0; i < bufs.size(); i++ )
774
  {
775
    bufs[i].subtract( other.bufs[i] );
776
  }
777
}
778
779
template<typename T>
780
void UnitBuf<T>::reconstruct(const UnitBuf<const T> &pred, const UnitBuf<const T> &resi, const ClpRngs& clpRngs)
781
{
782
  CHECK( chromaFormat != pred.chromaFormat, "Incompatible formats" );
783
  CHECK( chromaFormat != resi.chromaFormat, "Incompatible formats" );
784
785
  for( unsigned i = 0; i < bufs.size(); i++ )
786
  {
787
    bufs[i].reconstruct( pred.bufs[i], resi.bufs[i], clpRngs );
788
  }
789
}
790
791
template<typename T>
792
void UnitBuf<T>::addWeightedAvg(const UnitBuf<T> &other1, const UnitBuf<T> &other2, const ClpRngs& clpRngs, const uint8_t bcwIdx /* = BCW_DEFAULT */, const bool chromaOnly /* = false */, const bool lumaOnly /* = false */)
793
0
{
794
0
  const size_t istart = chromaOnly ? 1 : 0;
795
0
  const size_t iend   = lumaOnly   ? 1 : bufs.size();
796
797
0
  CHECK(lumaOnly && chromaOnly, "should not happen");
798
799
0
  for(size_t i = istart; i < iend; i++)
800
0
  {
801
0
    bufs[i].addWeightedAvg(other1.bufs[i], other2.bufs[i], clpRngs, bcwIdx);
802
0
  }
803
0
}
804
805
template<typename T>
806
void UnitBuf<T>::addAvg(const UnitBuf<T> &other1, const UnitBuf<T> &other2, const ClpRngs& clpRngs, const bool chromaOnly /* = false */, const bool lumaOnly /* = false */)
807
0
{
808
0
  const size_t istart = chromaOnly ? 1 : 0;
809
0
  const size_t iend   = lumaOnly   ? 1 : bufs.size();
810
811
0
  CHECK( lumaOnly && chromaOnly, "should not happen" );
812
813
0
  for( size_t i = istart; i < iend; i++)
814
0
  {
815
0
    bufs[i].addAvg( other1.bufs[i], other2.bufs[i], clpRngs );
816
0
  }
817
0
}
818
819
template<typename T>
820
void UnitBuf<T>::colorSpaceConvert( const UnitBuf<T> &other, const ClpRng& clpRng )
821
{
822
  THROW_FATAL( "Type not supported" );
823
}
824
825
template<>
826
void UnitBuf<Pel>::colorSpaceConvert( const UnitBuf<Pel> &other, const ClpRng& clpRng );
827
828
template<typename T>
829
void UnitBuf<T>::extendBorderPel( unsigned margin )
830
0
{
831
0
  for( unsigned i = 0; i < bufs.size(); i++ )
832
0
  {
833
0
    bufs[i].extendBorderPel( margin );
834
0
  }
835
0
}
836
837
template<typename T>
838
void UnitBuf<T>::extendBorderPel(unsigned margin, bool left, bool right, bool top, bool bottom)
839
18
{
840
72
  for( unsigned i = 0; i < bufs.size(); i++ )
841
54
  {
842
54
    bufs[i].extendBorderPel( margin, left, right, top, bottom );
843
54
  }
844
18
}
845
846
template<typename T>
847
void UnitBuf<T>::padBorderPel( unsigned margin, int dir )
848
0
{
849
0
  for( unsigned i = 0; i < bufs.size(); i++ )
850
0
  {
851
0
    bufs[i].padBorderPel( margin >> getComponentScaleX( ComponentID( i ), chromaFormat ), margin >> getComponentScaleY( ComponentID( i ), chromaFormat ), dir );
852
0
  }
853
0
}
854
855
template<typename T>
856
UnitBuf<T> UnitBuf<T>::subBuf( const UnitArea& subArea )
857
16.1k
{
858
16.1k
  UnitBuf<T> subBuf;
859
16.1k
  subBuf.chromaFormat = chromaFormat;
860
16.1k
  unsigned blockIdx = 0;
861
862
16.1k
  for( auto &subAreaBuf : bufs )
863
48.5k
  {
864
48.5k
    subBuf.bufs.push_back( subAreaBuf.subBuf( subArea.blocks[blockIdx].pos(), subArea.blocks[blockIdx].size() ) );
865
48.5k
    blockIdx++;
866
48.5k
  }
867
868
16.1k
  return subBuf;
869
16.1k
}
870
871
872
template<typename T>
873
const UnitBuf<const T> UnitBuf<T>::subBuf( const UnitArea& subArea ) const
874
0
{
875
0
  UnitBuf<const T> subBuf;
876
0
  subBuf.chromaFormat = chromaFormat;
877
0
  unsigned blockIdx = 0;
878
0
879
0
  for( const auto &subAreaBuf : bufs )
880
0
  {
881
0
    subBuf.bufs.push_back( subAreaBuf.subBuf( subArea.blocks[blockIdx].pos(), subArea.blocks[blockIdx].size() ) );
882
0
    blockIdx++;
883
0
  }
884
0
885
0
  return subBuf;
886
0
}
887
888
template<typename T>
889
UnitBuf<T> UnitBuf<T>::subBuf( const Area & subArea )
890
0
{
891
0
  UnitBuf<T> subBuf;
892
0
  subBuf.chromaFormat = chromaFormat;
893
0
  unsigned blockIdx = 0;
894
895
0
  for( auto &subAreaBuf : bufs )
896
0
  {
897
0
    const int scaleX = getComponentScaleX( ComponentID(blockIdx), chromaFormat);
898
0
    const int scaleY = getComponentScaleY( ComponentID(blockIdx), chromaFormat);
899
0
    const Area scaledArea( subArea.pos().x >> scaleX, subArea.pos().y >> scaleY, subArea.size().width >> scaleX, subArea.size().height >> scaleY );
900
0
    subBuf.bufs.push_back( subAreaBuf.subBuf( scaledArea.pos(), scaledArea.size() ) );
901
0
    blockIdx++;
902
0
  }
903
904
0
  return subBuf;
905
0
}
906
907
template<typename T>
908
const UnitBuf<const T> UnitBuf<T>::subBuf( const Area & subArea ) const
909
0
{
910
0
  UnitBuf<T> subBuf;
911
0
  subBuf.chromaFormat = chromaFormat;
912
0
  unsigned blockIdx = 0;
913
914
0
  for( auto &subAreaBuf : bufs )
915
0
  {
916
0
    const int scaleX = getComponentScaleX( ComponentID(blockIdx), chromaFormat);
917
0
    const int scaleY = getComponentScaleY( ComponentID(blockIdx), chromaFormat);
918
0
    const Area scaledArea( subArea.pos().x >> scaleX, subArea.pos().y >> scaleY, subArea.size().width >> scaleX, subArea.size().height >> scaleY );
919
0
    subBuf.bufs.push_back( subAreaBuf.subBuf( scaledArea.pos(), scaledArea.size() ) );
920
0
    blockIdx++;
921
0
  }
922
923
0
  return subBuf;
924
0
}
925
926
// ---------------------------------------------------------------------------
927
// PelStorage struct (PelUnitBuf which allocates its own memory)
928
// ---------------------------------------------------------------------------
929
930
struct UnitArea;
931
struct CompArea;
932
933
struct PelStorage : public PelUnitBuf
934
{
935
  PelStorage();
936
  ~PelStorage();
937
938
  void swap( PelStorage& other );
939
  void createFromBuf( PelUnitBuf buf );
940
  void create( const UnitArea &_unit );
941
  void create( const ChromaFormat _chromaFormat, const Size& _size, const unsigned _maxCUSize = 0, const unsigned _margin = 0, const unsigned _alignment = 0, const bool _scaleChromaMargin = true, const UserAllocator* userAlloc = nullptr );
942
  void destroy();
943
944
         PelBuf getBuf( const CompArea &blk );
945
  const CPelBuf getBuf( const CompArea &blk ) const;
946
947
         PelBuf getBuf( const ComponentID CompID );
948
  const CPelBuf getBuf( const ComponentID CompID ) const;
949
950
         PelUnitBuf getBuf( const UnitArea &unit );
951
  const CPelUnitBuf getBuf( const UnitArea &unit ) const;
952
0
  Pel *getOrigin( const int id ) const { return m_origin[id]; }
953
0
  PelBuf getOriginBuf( const int id ) { return PelBuf( m_origin[id], m_origSi[id] ); }
954
955
0
  Size  getBufSize( const int id )      const { return  m_origSi[id];     }
956
0
  void *getBufAllocator( const int id ) const { return m_allocator[id];   }
957
0
  bool  isExternAllocator()             const { return m_externAllocator; }
958
959
713
  const UserAllocator* getUserAllocator() const { return m_userAlloc; }
960
961
private:
962
963
  Size    m_origSi[MAX_NUM_COMPONENT];
964
  Pel    *m_origin[MAX_NUM_COMPONENT];
965
  void   *m_allocator[MAX_NUM_COMPONENT];
966
  bool    m_externAllocator = false;
967
  const UserAllocator* m_userAlloc  = nullptr;
968
};
969
970
}   // namespace vvdec