source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComWedgelet.cpp @ 1179

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

Merged branch 13.1-dev0@1178.

  • Property svn:eol-style set to native
File size: 13.6 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-2015, 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 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
35
36
37// Include files
38#include "CommonDef.h"
39#include "TComYuv.h"
40#include "TComWedgelet.h"
41
42#include <stdlib.h>
43#include <memory.h>
44
45using namespace std;
46
47#if H_3D_DIM_DMM
48TComWedgelet::TComWedgelet( UInt uiWidth, UInt uiHeight ) : m_uhXs     ( 0 ),
49                                                            m_uhYs     ( 0 ),
50                                                            m_uhXe     ( 0 ),
51                                                            m_uhYe     ( 0 ),
52                                                            m_uhOri    ( 0 ),
53                                                            m_eWedgeRes( FULL_PEL ),
54                                                            m_bIsCoarse( false )
55{
56  create( uiWidth, uiHeight );
57}
58
59TComWedgelet::TComWedgelet( const TComWedgelet &rcWedge ) : m_uhXs     ( rcWedge.m_uhXs      ),
60                                                            m_uhYs     ( rcWedge.m_uhYs      ),
61                                                            m_uhXe     ( rcWedge.m_uhXe      ),
62                                                            m_uhYe     ( rcWedge.m_uhYe      ),
63                                                            m_uhOri    ( rcWedge.m_uhOri     ),
64                                                            m_eWedgeRes( rcWedge.m_eWedgeRes ),
65                                                            m_bIsCoarse( rcWedge.m_bIsCoarse ),
66                                                            m_uiAng    ( rcWedge.m_uiAng     ),
67                                                            m_uiWidth  ( rcWedge.m_uiWidth   ),
68                                                            m_uiHeight ( rcWedge.m_uiHeight  ),
69                                                            m_pbPattern( (Bool*)xMalloc( Bool, (m_uiWidth * m_uiHeight) ) )
70                                                            ,m_pbScaledPattern( g_wedgePattern )
71{
72  ::memcpy( m_pbPattern, rcWedge.m_pbPattern, sizeof(Bool) * (m_uiWidth * m_uiHeight));
73}
74
75TComWedgelet::~TComWedgelet(void)
76{
77  destroy();
78}
79
80Void TComWedgelet::create( UInt uiWidth, UInt uiHeight )
81{
82  assert( uiWidth > 0 && uiHeight > 0 );
83
84  m_uiWidth   = uiWidth;
85  m_uiHeight  = uiHeight;
86
87  m_pbPattern = (Bool*)xMalloc( Bool, (m_uiWidth * m_uiHeight) );
88  m_pbScaledPattern = g_wedgePattern;
89}
90
91Void TComWedgelet::destroy()
92{
93  if( m_pbPattern ) { xFree( m_pbPattern ); m_pbPattern = NULL; }
94}
95
96Void TComWedgelet::clear()
97{
98  ::memset( m_pbPattern, 0, (m_uiWidth * m_uiHeight) * sizeof(Bool) );
99}
100
101Void TComWedgelet::findClosestAngle()
102{
103  UInt uiAng=0,uiOptAng=0;
104  UInt uiMinD=MAX_UINT;
105  UInt uiTmpD=0;
106  Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
107 
108  UChar uhXs = m_uhXs;
109  UChar uhYs = m_uhYs;
110  UChar uhXe = m_uhXe;
111  UChar uhYe = m_uhYe;
112
113  for(uiAng=2; uiAng<=34; uiAng++)
114  {
115    Int iSign    = (uiAng<VER_IDX && uiAng>HOR_IDX ) ? -1 : 1;
116    Int iVer     = uiAng>17 ? 32 : angTable[(uiAng>10) ? (uiAng-10) : (10-uiAng)];
117    Int iHor     = uiAng<19 ? 32 : angTable[(uiAng>26) ? (uiAng-26) : (26-uiAng)];
118
119    uiTmpD  = abs(iVer*iSign*(uhXs-uhXe) - iHor*(uhYe-uhYs));
120   
121    if( uiTmpD < uiMinD )
122    {
123      uiMinD = uiTmpD;
124      uiOptAng = uiAng;
125    }
126  }
127  m_uiAng = uiOptAng;
128}
129
130Void TComWedgelet::setWedgelet( UChar uhXs, UChar uhYs, UChar uhXe, UChar uhYe, UChar uhOri, WedgeResolution eWedgeRes, Bool bIsCoarse )
131{
132  m_uhXs      = uhXs;
133  m_uhYs      = uhYs;
134  m_uhXe      = uhXe;
135  m_uhYe      = uhYe;
136  m_uhOri     = uhOri;
137  m_eWedgeRes = eWedgeRes;
138  m_bIsCoarse = bIsCoarse;
139
140  xGenerateWedgePattern();
141}
142
143Bool TComWedgelet::checkNotPlain()
144{
145  for( UInt k = 1; k < (m_uiWidth * m_uiHeight); k++ )
146  {
147    if( m_pbPattern[0] != m_pbPattern[k] )
148    {
149      return true;
150    }
151  }
152  return false;
153}
154
155Bool TComWedgelet::checkIdentical( Bool* pbRefPattern )
156{
157  for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ )
158  {
159    if( m_pbPattern[k] != pbRefPattern[k] )
160    {
161      return false;
162    }
163  }
164  return true;
165}
166
167Bool TComWedgelet::checkInvIdentical( Bool* pbRefPattern )
168{
169  for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ )
170  {
171    if( m_pbPattern[k] == pbRefPattern[k] )
172    {
173      return false;
174    }
175  }
176  return true;
177}
178
179#if SHARP_DMM_CLEAN_K0042
180Void TComWedgelet::generateWedgePatternByRotate(const TComWedgelet &rcWedge, Int rotate)
181{
182  Int stride = m_uiWidth;
183  Int sinc, offsetI, offsetJ;
184 
185  sinc = 1;
186  offsetI = ( sinc) < 0 ? stride-1 : 0; // 0
187  offsetJ = (-sinc) < 0 ? stride-1 : 0; // stride - 1
188
189  for (Int y = 0; y < stride; y++)
190  {
191    for (Int x = 0; x < stride; x++)
192    {
193      Int i = offsetI + sinc * y; // y
194      Int j = offsetJ - sinc * x; // stride - 1 - x
195      m_pbPattern[(y * stride) + x] = !rcWedge.m_pbPattern[(j * stride) + i];
196    }
197  }
198  Int blocksize = rcWedge.m_uiWidth * (rcWedge.m_eWedgeRes == HALF_PEL ? 2 : 1);
199  Int offsetX = (-sinc) < 0 ? blocksize - 1 : 0;
200  Int offsetY = ( sinc) < 0 ? blocksize - 1 : 0;
201  m_uhXs = offsetX - sinc * rcWedge.m_uhYs;
202  m_uhYs = offsetY + sinc * rcWedge.m_uhXs;
203  m_uhXe = offsetX - sinc * rcWedge.m_uhYe;
204  m_uhYe = offsetY + sinc * rcWedge.m_uhXe;
205  m_uhOri = rotate;
206  m_eWedgeRes = rcWedge.m_eWedgeRes;
207  m_bIsCoarse = rcWedge.m_bIsCoarse;
208  m_uiAng = rcWedge.m_uiAng;
209  m_uiWidth  = rcWedge.m_uiWidth;
210  m_uiHeight = rcWedge.m_uiHeight;
211}
212#endif
213
214Void TComWedgelet::xGenerateWedgePattern()
215{
216  UInt uiTempBlockSize = 0;
217  UChar uhXs = 0, uhYs = 0, uhXe = 0, uhYe = 0;
218  switch( m_eWedgeRes )
219  {
220  case(   FULL_PEL ): { uiTempBlockSize =  m_uiWidth;     uhXs =  m_uhXs;     uhYs =  m_uhYs;     uhXe =  m_uhXe;     uhYe =  m_uhYe;     } break;
221  case(   HALF_PEL ): { uiTempBlockSize = (m_uiWidth<<1); uhXs =  m_uhXs;     uhYs =  m_uhYs;     uhXe =  m_uhXe;     uhYe =  m_uhYe;     } break;
222  }
223
224  Bool* pbTempPattern = new Bool[ (uiTempBlockSize * uiTempBlockSize) ];
225  ::memset( pbTempPattern, 0, (uiTempBlockSize * uiTempBlockSize) * sizeof(Bool) );
226  Int iTempStride = uiTempBlockSize;
227
228  xDrawEdgeLine( uhXs, uhYs, uhXe, uhYe, pbTempPattern, iTempStride );
229
230#if SHARP_DMM_CLEAN_K0042
231  Int shift = (m_eWedgeRes == HALF_PEL) ? 1 : 0;
232  Int endPos = uhYe>>shift;
233  for (Int y = 0; y <= endPos; y++)
234  {
235    for (Int x = 0; x < m_uiWidth && pbTempPattern[(y * m_uiWidth) + x] == 0; x++)
236    {
237      pbTempPattern[(y * m_uiWidth) + x] = true;
238    }
239  }
240  for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ )
241  {
242    m_pbPattern[k] = pbTempPattern[k];
243  };
244#else
245  switch( m_uhOri )
246  {
247  case( 0 ): { for( UInt iX = 0;                 iX < uhXs;            iX++ ) { UInt iY = 0;                 while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iY++; } } } break;
248  case( 1 ): { for( UInt iY = 0;                 iY < uhYs;            iY++ ) { UInt iX = uiTempBlockSize-1; while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iX--; } } } break;
249  case( 2 ): { for( UInt iX = uiTempBlockSize-1; iX > uhXs;            iX-- ) { UInt iY = uiTempBlockSize-1; while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iY--; } } } break;
250  case( 3 ): { for( UInt iY = uiTempBlockSize-1; iY > uhYs;            iY-- ) { UInt iX = 0;                 while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iX++; } } } break;
251  case( 4 ): 
252    { 
253      if( (uhXs+uhXe) < uiTempBlockSize ) { for( UInt iY = 0; iY < uiTempBlockSize; iY++ ) { UInt iX = 0;                 while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iX++; } } }
254      else                                { for( UInt iY = 0; iY < uiTempBlockSize; iY++ ) { UInt iX = uiTempBlockSize-1; while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iX--; } } }
255    }
256    break;
257  case( 5 ): 
258    { 
259      if( (uhYs+uhYe) < uiTempBlockSize ) { for( UInt iX = 0; iX < uiTempBlockSize; iX++ ) { UInt iY = 0;                 while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iY++; } } }
260      else                                { for( UInt iX = 0; iX < uiTempBlockSize; iX++ ) { UInt iY = uiTempBlockSize-1; while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iY--; } } }
261    }
262  }
263
264  clear();
265  switch( m_eWedgeRes )
266  {
267  case(   FULL_PEL ): { for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ ) { m_pbPattern[k] = pbTempPattern[k]; }; } break;
268  case(   HALF_PEL ): // sub-sampling by factor 2
269    {
270      Int iStride = getStride();
271
272      UInt uiOffX, uiOffY;
273      switch( m_uhOri )
274      {
275      case( 0 ): { uiOffX = 0; uiOffY = 0; } break;
276      case( 1 ): { uiOffX = 1; uiOffY = 0; } break;
277      case( 2 ): { uiOffX = 1; uiOffY = 1; } break;
278      case( 3 ): { uiOffX = 0; uiOffY = 1; } break;
279      case( 4 ): 
280        { 
281          if( (uhXs+uhXe) < uiTempBlockSize ) { uiOffX = 0; uiOffY = 0; }
282          else                                { uiOffX = 1; uiOffY = 0; }
283        } 
284        break;
285      case( 5 ): 
286        { 
287          if( (uhYs+uhYe) < uiTempBlockSize ) { uiOffX = 0; uiOffY = 0; }
288          else                                { uiOffX = 0; uiOffY = 1; }
289        } 
290        break;
291      default:   { uiOffX = 0; uiOffY = 0; } break;
292      }
293
294      for(Int iY = 0; iY < m_uiHeight; iY++)
295      {
296        for(Int iX = 0; iX < m_uiWidth; iX++)
297        {
298          m_pbPattern[(iY * iStride) + iX] = pbTempPattern[(((iY<<1)+uiOffY) * iTempStride) + ((iX<<1)+uiOffX)];
299        }
300      }
301    }
302    break;
303  }
304#endif
305
306  if( pbTempPattern )
307  {
308    delete [] pbTempPattern;
309    pbTempPattern = NULL;
310  }
311}
312
313Void TComWedgelet::xDrawEdgeLine( UChar uhXs, UChar uhYs, UChar uhXe, UChar uhYe, Bool* pbPattern, Int iPatternStride )
314{
315  Int x0 = (Int)uhXs;
316  Int y0 = (Int)uhYs;
317  Int x1 = (Int)uhXe;
318  Int y1 = (Int)uhYe;
319
320  // direction independent Bresenham line
321  bool steep = (abs(y1 - y0) > abs(x1 - x0));
322  if( steep )
323  {
324    std::swap( x0, y0 );
325    std::swap( x1, y1 );
326  }
327
328  bool backward = ( x0 > x1 );
329  if( backward )
330  {
331    std::swap( x0, x1 );
332    std::swap( y0, y1 );
333  }
334
335  Int deltax = x1 - x0;
336  Int deltay = abs(y1 - y0);
337  Int error = 0;
338  Int deltaerr = (deltay<<1);
339
340  Int ystep;
341  Int y = y0;
342  if( y0 < y1 ) ystep =  1;
343  else          ystep = -1;
344
345  for( Int x = x0; x <= x1; x++ )
346  {
347#if SHARP_DMM_CLEAN_K0042
348    Int shift = (m_eWedgeRes == HALF_PEL) ? 1 : 0;
349    Int stride = iPatternStride >> shift;
350    if( steep ) { pbPattern[((x>>shift) * stride) + (y>>shift)] = true; }
351    else        { pbPattern[((y>>shift) * stride) + (x>>shift)] = true; }
352#else
353    if( steep ) { pbPattern[(x * iPatternStride) + y] = true; }
354    else        { pbPattern[(y * iPatternStride) + x] = true; }
355#endif
356
357    error += deltaerr;
358    if( error >= deltax )
359    {
360      y += ystep;
361      error = error - (deltax<<1);
362    }
363  }
364}
365
366Bool* TComWedgelet::getScaledPattern(UInt uiDstSize)
367{
368  Bool *pbSrcPat = this->getPattern();
369  UInt uiSrcSize = this->getStride();
370
371  Int scale = (g_aucConvertToBit[uiDstSize] - g_aucConvertToBit[uiSrcSize]);
372  assert(scale>=0);
373  for (Int y=0; y<uiDstSize; y++)
374  {
375    for (Int x=0; x<uiDstSize; x++)
376    {
377      Int srcX = x>>scale;
378      Int srcY = y>>scale;
379      m_pbScaledPattern[y*uiDstSize + x] = pbSrcPat[ srcY*uiSrcSize + srcX ];
380    }
381  }
382  return m_pbScaledPattern;
383}
384
385TComWedgeNode::TComWedgeNode()
386{
387  m_uiPatternIdx = DMM_NO_WEDGEINDEX;
388  for( UInt uiPos = 0; uiPos < DMM_NUM_WEDGE_REFINES; uiPos++ )
389  {
390    m_uiRefineIdx[uiPos] = DMM_NO_WEDGEINDEX;
391  }
392}
393
394UInt TComWedgeNode::getPatternIdx()
395{
396  return m_uiPatternIdx;
397}
398UInt TComWedgeNode::getRefineIdx( UInt uiPos )
399{
400  assert( uiPos < DMM_NUM_WEDGE_REFINES );
401  return m_uiRefineIdx[uiPos];
402}
403Void TComWedgeNode::setPatternIdx( UInt uiIdx )
404{
405  m_uiPatternIdx = uiIdx;
406}
407Void TComWedgeNode::setRefineIdx( UInt uiIdx, UInt uiPos )
408{
409  assert( uiPos < DMM_NUM_WEDGE_REFINES );
410  m_uiRefineIdx[uiPos] = uiIdx; 
411}
412#endif //H_3D_DIM_DMM
Note: See TracBrowser for help on using the repository browser.