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

Last change on this file since 638 was 622, checked in by tech, 11 years ago

Merged 8.0-dev0@621 (MV-HEVC 5 HLS).

  • Property svn:eol-style set to native
File size: 25.4 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-2011, 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{
71  ::memcpy( m_pbPattern, rcWedge.m_pbPattern, sizeof(Bool) * (m_uiWidth * m_uiHeight));
72}
73
74TComWedgelet::~TComWedgelet(void)
75{
76  destroy();
77}
78
79Void TComWedgelet::create( UInt uiWidth, UInt uiHeight )
80{
81  assert( uiWidth > 0 && uiHeight > 0 );
82
83  m_uiWidth   = uiWidth;
84  m_uiHeight  = uiHeight;
85
86  m_pbPattern = (Bool*)xMalloc( Bool, (m_uiWidth * m_uiHeight) );
87}
88
89Void TComWedgelet::destroy()
90{
91  if( m_pbPattern ) { xFree( m_pbPattern ); m_pbPattern = NULL; }
92}
93
94Void TComWedgelet::clear()
95{
96  ::memset( m_pbPattern, 0, (m_uiWidth * m_uiHeight) * sizeof(Bool) );
97}
98
99Void TComWedgelet::findClosestAngle()
100{
101  UInt uiAng=0,uiOptAng=0;
102  UInt uiMinD=MAX_UINT;
103  UInt uiTmpD=0;
104  Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
105 
106  UChar uhXs = m_uhXs;
107  UChar uhYs = m_uhYs;
108  UChar uhXe = m_uhXe;
109  UChar uhYe = m_uhYe;
110
111  for(uiAng=2; uiAng<=34; uiAng++)
112  {
113    Int iSign    = (uiAng<VER_IDX && uiAng>HOR_IDX ) ? -1 : 1;
114    Int iVer     = uiAng>17 ? 32 : angTable[(uiAng>10) ? (uiAng-10) : (10-uiAng)];
115    Int iHor     = uiAng<19 ? 32 : angTable[(uiAng>26) ? (uiAng-26) : (26-uiAng)];
116
117    uiTmpD  = abs(iVer*iSign*(uhXs-uhXe) - iHor*(uhYe-uhYs));
118   
119    if( uiTmpD < uiMinD )
120    {
121      uiMinD = uiTmpD;
122      uiOptAng = uiAng;
123    }
124  }
125  m_uiAng = uiOptAng;
126}
127
128Void TComWedgelet::setWedgelet( UChar uhXs, UChar uhYs, UChar uhXe, UChar uhYe, UChar uhOri, WedgeResolution eWedgeRes, Bool bIsCoarse )
129{
130  m_uhXs      = uhXs;
131  m_uhYs      = uhYs;
132  m_uhXe      = uhXe;
133  m_uhYe      = uhYe;
134  m_uhOri     = uhOri;
135  m_eWedgeRes = eWedgeRes;
136  m_bIsCoarse = bIsCoarse;
137
138  xGenerateWedgePattern();
139}
140
141Bool TComWedgelet::checkNotPlain()
142{
143  for( UInt k = 1; k < (m_uiWidth * m_uiHeight); k++ )
144  {
145    if( m_pbPattern[0] != m_pbPattern[k] )
146    {
147      return true;
148    }
149  }
150  return false;
151}
152
153Bool TComWedgelet::checkIdentical( Bool* pbRefPattern )
154{
155  for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ )
156  {
157    if( m_pbPattern[k] != pbRefPattern[k] )
158    {
159      return false;
160    }
161  }
162  return true;
163}
164
165Bool TComWedgelet::checkInvIdentical( Bool* pbRefPattern )
166{
167  for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ )
168  {
169    if( m_pbPattern[k] == pbRefPattern[k] )
170    {
171      return false;
172    }
173  }
174  return true;
175}
176
177#if !SEC_DMM2_E0146_HHIFIX
178Bool TComWedgelet::checkPredDirAbovePossible( UInt uiPredDirBlockSize, UInt uiPredDirBlockOffset )
179{
180  WedgeResolution eContDWedgeRes = g_dmmWedgeResolution[(UInt)g_aucConvertToBit[uiPredDirBlockSize]];
181  UInt uiContDStartEndMax = 0;
182  UInt uiContDStartEndOffset = 0;
183  switch( eContDWedgeRes )
184  {
185  case( DOUBLE_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize>>1); uiContDStartEndOffset = (uiPredDirBlockOffset>>1); break; }
186  case(   FULL_PEL ): { uiContDStartEndMax =  uiPredDirBlockSize;     uiContDStartEndOffset =  uiPredDirBlockOffset;     break; }
187  case(   HALF_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize<<1); uiContDStartEndOffset = (uiPredDirBlockOffset<<1); break; }
188  }
189
190  if( m_uhOri == 2 || m_uhOri == 3 || m_uhOri == 4 )
191  {
192    UInt uiThisStartEndMax = 0;
193    switch( m_eWedgeRes )
194    {
195    case( DOUBLE_PEL ): { uiThisStartEndMax = (m_uiWidth>>1); break; }
196    case(   FULL_PEL ): { uiThisStartEndMax =  m_uiWidth;     break; }
197    case(   HALF_PEL ): { uiThisStartEndMax = (m_uiWidth<<1); break; }
198    }
199
200    UChar uhStartX = m_uhXs;
201    UChar uhStartY = m_uhYs;
202    UChar uhEndX   = m_uhXe;
203    UChar uhEndY   = m_uhYe;
204
205    if( 2 == m_uhOri )
206    {
207      std::swap( uhStartX, uhEndX );
208      std::swap( uhStartY, uhEndY );
209    }
210
211    UInt uiScaledEndX = (UInt)uhEndX;
212    Int iDeltaRes = (Int)eContDWedgeRes - (Int)m_eWedgeRes;
213    if( iDeltaRes > 0 ) { uiScaledEndX <<=  iDeltaRes; }
214    if( iDeltaRes < 0 ) { uiScaledEndX >>= -iDeltaRes; }
215
216    if( ((UInt)uhEndY == (uiThisStartEndMax-1)) && ((uiScaledEndX-uiContDStartEndOffset) > 0 && (uiScaledEndX-uiContDStartEndOffset) < (uiContDStartEndMax-1)) )
217    {
218      return true;
219    }
220  }
221
222  return false;
223}
224
225Bool TComWedgelet::checkPredDirLeftPossible( UInt uiPredDirBlockSize, UInt uiPredDirBlockOffset )
226{
227  WedgeResolution eContDWedgeRes = g_dmmWedgeResolution[(UInt)g_aucConvertToBit[uiPredDirBlockSize]];
228  UInt uiContDStartEndMax = 0;
229  UInt uiContDStartEndOffset = 0;
230  switch( eContDWedgeRes )
231  {
232  case( DOUBLE_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize>>1); uiContDStartEndOffset = (uiPredDirBlockOffset>>1); break; }
233  case(   FULL_PEL ): { uiContDStartEndMax =  uiPredDirBlockSize;     uiContDStartEndOffset =  uiPredDirBlockOffset;     break; }
234  case(   HALF_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize<<1); uiContDStartEndOffset = (uiPredDirBlockOffset<<1); break; }
235  }
236
237  if( m_uhOri == 1 || m_uhOri == 2 || m_uhOri == 5 )
238  {
239    UInt uiThisStartEndMax = 0;
240    switch( m_eWedgeRes )
241    {
242    case( DOUBLE_PEL ): { uiThisStartEndMax = (m_uiHeight>>1); break; }
243    case(   FULL_PEL ): { uiThisStartEndMax =  m_uiHeight;     break; }
244    case(   HALF_PEL ): { uiThisStartEndMax = (m_uiHeight<<1); break; }
245    }
246
247    UChar uhStartX = m_uhXs;
248    UChar uhStartY = m_uhYs;
249    UChar uhEndX   = m_uhXe;
250    UChar uhEndY   = m_uhYe;
251
252    if( 1 == m_uhOri || 5 == m_uhOri )
253    {
254      std::swap( uhStartX, uhEndX );
255      std::swap( uhStartY, uhEndY );
256    }
257
258    UInt uiScaledEndY = (UInt)uhEndY;
259    Int iDeltaRes = (Int)eContDWedgeRes - (Int)m_eWedgeRes;
260    if( iDeltaRes > 0 ) { uiScaledEndY <<=  iDeltaRes; }
261    if( iDeltaRes < 0 ) { uiScaledEndY >>= -iDeltaRes; }
262
263    if( ((UInt)uhEndX == (uiThisStartEndMax-1)) && ((uiScaledEndY-uiContDStartEndOffset) > 0 && (uiScaledEndY-uiContDStartEndOffset) < (uiContDStartEndMax-1)) )
264    {
265      return true;
266    }
267  }
268
269  return false;
270}
271
272Void TComWedgelet::getPredDirStartEndAbove( UChar& ruhXs, UChar& ruhYs, UChar& ruhXe, UChar& ruhYe, UInt uiPredDirBlockSize, UInt uiPredDirBlockOffset, Int iDeltaEnd )
273{
274  ruhXs = 0;
275  ruhYs = 0;
276  ruhXe = 0;
277  ruhYe = 0;
278
279  // get start/end of reference (=this) wedgelet
280  UInt uiRefStartX = (UInt)getStartX();
281  UInt uiRefStartY = (UInt)getStartY();
282  UInt uiRefEndX   = (UInt)getEndX();
283  UInt uiRefEndY   = (UInt)getEndY();
284
285  WedgeResolution eContDWedgeRes = g_dmmWedgeResolution[(UInt)g_aucConvertToBit[uiPredDirBlockSize]];
286  UInt uiContDStartEndMax = 0;
287  UInt uiContDStartEndOffset = 0;
288  switch( eContDWedgeRes )
289  {
290  case( DOUBLE_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize>>1); uiContDStartEndOffset = (uiPredDirBlockOffset>>1); break; }
291  case(   FULL_PEL ): { uiContDStartEndMax =  uiPredDirBlockSize;     uiContDStartEndOffset =  uiPredDirBlockOffset;     break; }
292  case(   HALF_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize<<1); uiContDStartEndOffset = (uiPredDirBlockOffset<<1); break; }
293  }
294  Int iContDMaxPos = (Int)uiContDStartEndMax - 1;
295
296  // swap if start/end if line orientation is not from top to bottom
297  if( 2 == (UInt)getOri() )
298  {
299    std::swap( uiRefStartX, uiRefEndX );
300    std::swap( uiRefStartY, uiRefEndY );
301  }
302
303  // calc slopes
304  Int iA_DeltaX = (Int)uiRefEndX - (Int)uiRefStartX;
305  Int iA_DeltaY = (Int)uiRefEndY - (Int)uiRefStartY;
306
307  // get aligned end x value of ref wedge
308  UInt uiScaledRefEndX = uiRefEndX;
309  Int iDeltaRes = (Int)eContDWedgeRes - (Int)m_eWedgeRes;
310  if( iDeltaRes > 0 ) { uiScaledRefEndX <<=  iDeltaRes; }
311  if( iDeltaRes < 0 ) { uiScaledRefEndX >>= -iDeltaRes; }
312
313  assert( uiScaledRefEndX >= uiContDStartEndOffset );
314  Int iAlignedRefEndX = (Int)uiScaledRefEndX - (Int)uiContDStartEndOffset;
315
316  // special for straight vertical wedge
317  if( iA_DeltaX == 0 )
318  {
319    ruhXs = (UChar)iAlignedRefEndX;
320    ruhYs = 0;
321
322    Int iXe = iAlignedRefEndX + iDeltaEnd;
323    if( iXe < 0 )
324    {
325      ruhXe = 0;
326      ruhYe = (UChar)min( max( (iContDMaxPos + iXe), 0 ), iContDMaxPos );
327
328      return;
329    }
330    else if( iXe > iContDMaxPos )
331    {
332      ruhXe = (UChar)iContDMaxPos;
333      ruhYe = (UChar)min( max( (iContDMaxPos - (iXe - iContDMaxPos)), 0 ), iContDMaxPos );
334
335      std::swap( ruhXs, ruhXe );
336      std::swap( ruhYs, ruhYe );
337      return;
338    }
339    else
340    {
341      ruhXe = (UChar)iXe;
342      ruhYe = (UChar)iContDMaxPos;
343
344      return;
345    }
346  }
347
348  // special for straight horizontal short bottom line
349  if( iA_DeltaY == 0 )
350  {
351    switch( (UInt)getOri() )
352    {
353    case( 2 ):
354      {
355        ruhXs = (UChar)(iAlignedRefEndX-1);
356        ruhYs = 0;
357        ruhXe = 0;
358        ruhYe = (UChar)min( max( iDeltaEnd, 0 ), iContDMaxPos );
359
360        return;
361      }
362    case( 3 ):
363      {
364        ruhXs = (UChar)(iAlignedRefEndX+1);
365        ruhYs = 0;
366        ruhXe = (UChar)iContDMaxPos;
367        ruhYe = (UChar)min( max( -iDeltaEnd, 0 ), iContDMaxPos );
368
369        std::swap( ruhXs, ruhXe );
370        std::swap( ruhYs, ruhYe );
371        return;
372      }
373    default:
374      {
375        assert( 0 );
376        return;
377      }
378    }
379  }
380
381  // set start point depending on slope
382  if( abs( iA_DeltaX ) >= abs( iA_DeltaY ) ) { if( iA_DeltaX < 0 ) { ruhXs = (UChar)(iAlignedRefEndX-1); ruhYs = 0; }
383                                                if( iA_DeltaX > 0 ) { ruhXs = (UChar)(iAlignedRefEndX+1); ruhYs = 0; } }
384  else                                                             { ruhXs = (UChar)(iAlignedRefEndX);   ruhYs = 0;   }
385
386  // calc end point and determine orientation
387  Int iVirtualEndX = (Int)ruhXs + roftoi( (Double)iContDMaxPos * ((Double)iA_DeltaX / (Double)iA_DeltaY) );
388
389  if( iVirtualEndX < 0 )
390  {
391    Int iYe = roftoi( (Double)(0 - (Int)ruhXs) * ((Double)iA_DeltaY / (Double)iA_DeltaX) ) + iDeltaEnd;
392    if( iYe < (Int)uiContDStartEndMax )
393    {
394      ruhXe = 0;
395      ruhYe = (UChar)max( iYe, 0 );
396
397      return;
398    }
399    else
400    {
401      ruhXe = (UChar)min( (iYe - iContDMaxPos), iContDMaxPos );
402      ruhYe = (UChar)iContDMaxPos;
403
404      return;
405    }
406  }
407  else if( iVirtualEndX > iContDMaxPos )
408  {
409    Int iYe = roftoi( (Double)(iContDMaxPos - (Int)ruhXs) * ((Double)iA_DeltaY / (Double)iA_DeltaX) ) - iDeltaEnd;
410    if( iYe < (Int)uiContDStartEndMax )
411    {
412      ruhXe = (UChar)iContDMaxPos;
413      ruhYe = (UChar)max( iYe, 0 );
414
415      std::swap( ruhXs, ruhXe );
416      std::swap( ruhYs, ruhYe );
417      return;
418    }
419    else
420    {
421      ruhXe = (UChar)max( (iContDMaxPos - (iYe - iContDMaxPos)), 0 );
422      ruhYe = (UChar)iContDMaxPos;
423
424      return;
425    }
426  }
427  else
428  {
429    Int iXe = iVirtualEndX + iDeltaEnd;
430    if( iXe < 0 )
431    {
432      ruhXe = 0;
433      ruhYe = (UChar)max( (iContDMaxPos + iXe), 0 );
434
435      return;
436    }
437    else if( iXe > iContDMaxPos )
438    {
439      ruhXe = (UChar)iContDMaxPos;
440      ruhYe = (UChar)max( (iContDMaxPos - (iXe - iContDMaxPos)), 0 );
441
442      std::swap( ruhXs, ruhXe );
443      std::swap( ruhYs, ruhYe );
444      return;
445    }
446    else
447    {
448      ruhXe = (UChar)iXe;
449      ruhYe = (UChar)iContDMaxPos;
450
451      return;
452    }
453  }
454}
455
456Void TComWedgelet::getPredDirStartEndLeft( UChar& ruhXs, UChar& ruhYs, UChar& ruhXe, UChar& ruhYe, UInt uiPredDirBlockSize, UInt uiPredDirBlockOffset, Int iDeltaEnd )
457{
458  ruhXs = 0;
459  ruhYs = 0;
460  ruhXe = 0;
461  ruhYe = 0;
462
463  // get start/end of reference (=this) wedgelet
464  UInt uiRefStartX = (UInt)getStartX();
465  UInt uiRefStartY = (UInt)getStartY();
466  UInt uiRefEndX   = (UInt)getEndX();
467  UInt uiRefEndY   = (UInt)getEndY();
468
469  WedgeResolution eContDWedgeRes = g_dmmWedgeResolution[(UInt)g_aucConvertToBit[uiPredDirBlockSize]];
470  UInt uiContDStartEndMax = 0;
471  UInt uiContDStartEndOffset = 0;
472  switch( eContDWedgeRes )
473  {
474  case( DOUBLE_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize>>1); uiContDStartEndOffset = (uiPredDirBlockOffset>>1); break; }
475  case(   FULL_PEL ): { uiContDStartEndMax =  uiPredDirBlockSize;     uiContDStartEndOffset =  uiPredDirBlockOffset;     break; }
476  case(   HALF_PEL ): { uiContDStartEndMax = (uiPredDirBlockSize<<1); uiContDStartEndOffset = (uiPredDirBlockOffset<<1); break; }
477  }
478  Int iContDMaxPos = (Int)uiContDStartEndMax - 1;
479
480  // swap if start/end if line orientation is not from left to right
481  if( 1 == (UInt)getOri() || 5 == (UInt)getOri() )
482  {
483    std::swap( uiRefStartX, uiRefEndX );
484    std::swap( uiRefStartY, uiRefEndY );
485  }
486
487  Int iL_DeltaX = (Int)uiRefEndX - (Int)uiRefStartX;
488  Int iL_DeltaY = (Int)uiRefEndY - (Int)uiRefStartY;
489
490  UInt uiScaledRefEndY = uiRefEndY;
491  Int iDeltaRes = (Int)eContDWedgeRes - (Int)m_eWedgeRes;
492  if( iDeltaRes > 0 ) { uiScaledRefEndY <<=  iDeltaRes; }
493  if( iDeltaRes < 0 ) { uiScaledRefEndY >>= -iDeltaRes; }
494
495  assert( uiScaledRefEndY >= uiContDStartEndOffset );
496  Int iAlignedRefEndY = (Int)uiScaledRefEndY - (Int)uiContDStartEndOffset;
497
498  // special for straight horizontal wedge
499  if( iL_DeltaY == 0 )
500  {
501    ruhXs = 0;
502    ruhYs = (UChar)iAlignedRefEndY;
503
504    Int iYe = iAlignedRefEndY - iDeltaEnd;
505    if( iYe < 0 )
506    {
507      ruhXe = (UChar)min( max( (iContDMaxPos + iYe), 0 ), iContDMaxPos );
508      ruhYe = 0;
509
510      std::swap( ruhXs, ruhXe );
511      std::swap( ruhYs, ruhYe );
512      return;
513    }
514    else if( iYe > iContDMaxPos )
515    {
516      ruhXe = (UChar)min( max( (iContDMaxPos - (iYe - iContDMaxPos)), 0 ), iContDMaxPos );
517      ruhYe = (UChar)iContDMaxPos;
518
519      return;
520    }
521    else
522    {
523      ruhXe = (UChar)iContDMaxPos;
524      ruhYe = (UChar)iYe;
525
526      std::swap( ruhXs, ruhXe );
527      std::swap( ruhYs, ruhYe );
528      return;
529    }
530  }
531
532  // special for straight vertical short right line
533  if( iL_DeltaX == 0 )
534  {
535    switch( (UInt)getOri() )
536    {
537    case( 1 ):
538      {
539        ruhXs = 0;
540        ruhYs = (UChar)(iAlignedRefEndY+1);
541        ruhXe = (UChar)min( max( iDeltaEnd, 0 ), iContDMaxPos );
542        ruhYe = (UChar)iContDMaxPos;
543
544        return;
545      }
546    case( 2 ):
547      {
548        ruhXs = 0;
549        ruhYs = (UChar)(iAlignedRefEndY-1);
550        ruhXe = (UChar)min( max( -iDeltaEnd, 0 ), iContDMaxPos );
551        ruhYe = 0;
552
553        std::swap( ruhXs, ruhXe );
554        std::swap( ruhYs, ruhYe );
555        return;
556      }
557    default:
558      {
559        assert( 0 );
560        return;
561      }
562    }
563  }
564
565  // set start point depending on slope
566  if( abs( iL_DeltaY ) >= abs( iL_DeltaX ) ) { if( iL_DeltaY < 0 ) { ruhYs = (UChar)(iAlignedRefEndY-1); ruhXs = 0; }
567                                               if( iL_DeltaY > 0 ) { ruhYs = (UChar)(iAlignedRefEndY+1); ruhXs = 0; } }
568  else                                       {                       ruhYs = (UChar)(iAlignedRefEndY);   ruhXs = 0;   }
569
570  // calc end point and determine orientation
571  Int iVirtualEndY = (Int)ruhYs + roftoi( (Double)iContDMaxPos * ((Double)iL_DeltaY / (Double)iL_DeltaX) );
572
573  if( iVirtualEndY < 0 )
574  {
575    Int iXe = roftoi( (Double)(0 - (Int)ruhYs ) * ((Double)iL_DeltaX / (Double)iL_DeltaY) ) - iDeltaEnd;
576    if( iXe < (Int)uiContDStartEndMax )
577    {
578      ruhXe = (UChar)max( iXe, 0 );
579      ruhYe = 0;
580
581      std::swap( ruhXs, ruhXe );
582      std::swap( ruhYs, ruhYe );
583      return;
584    }
585    else
586    {
587      ruhXe = (UChar)iContDMaxPos;
588      ruhYe = (UChar)min( (iXe - iContDMaxPos), iContDMaxPos );
589
590      std::swap( ruhXs, ruhXe );
591      std::swap( ruhYs, ruhYe );
592      return;
593    }
594  }
595  else if( iVirtualEndY > iContDMaxPos )
596  {
597    Int iXe = roftoi( (Double)(iContDMaxPos - (Int)ruhYs ) * ((Double)iL_DeltaX / (Double)iL_DeltaY) ) + iDeltaEnd;
598    if( iXe < (Int)uiContDStartEndMax )
599    {
600      ruhXe = (UChar)max( iXe, 0 );
601      ruhYe = (UChar)iContDMaxPos;
602
603      return;
604    }
605    else
606    {
607      ruhXe = (UChar)iContDMaxPos;
608      ruhYe = (UChar)max( (iContDMaxPos - (iXe - iContDMaxPos)), 0 );
609
610      std::swap( ruhXs, ruhXe );
611      std::swap( ruhYs, ruhYe );
612      return;
613    }
614  }
615  else
616  {
617    Int iYe = iVirtualEndY - iDeltaEnd;
618    if( iYe < 0 )
619    {
620      ruhXe = (UChar)max( (iContDMaxPos + iYe), 0 );
621      ruhYe = 0;
622
623      std::swap( ruhXs, ruhXe );
624      std::swap( ruhYs, ruhYe );
625      return;
626    }
627    else if( iYe > iContDMaxPos )
628    {
629      ruhXe = (UChar)max( (iContDMaxPos - (iYe - iContDMaxPos)), 0 );
630      ruhYe = (UChar)iContDMaxPos;
631
632      return;
633    }
634    else
635    {
636      ruhXe = (UChar)iContDMaxPos;
637      ruhYe = (UChar)iYe;
638
639      std::swap( ruhXs, ruhXe );
640      std::swap( ruhYs, ruhYe );
641      return;
642    }
643  }
644}
645#endif
646
647Void TComWedgelet::xGenerateWedgePattern()
648{
649  UInt uiTempBlockSize = 0;
650  UChar uhXs = 0, uhYs = 0, uhXe = 0, uhYe = 0;
651  switch( m_eWedgeRes )
652  {
653  case( DOUBLE_PEL ): { uiTempBlockSize =  m_uiWidth;     uhXs = (m_uhXs<<1); uhYs = (m_uhYs<<1); uhXe = (m_uhXe<<1); uhYe = (m_uhYe<<1); } break;
654  case(   FULL_PEL ): { uiTempBlockSize =  m_uiWidth;     uhXs =  m_uhXs;     uhYs =  m_uhYs;     uhXe =  m_uhXe;     uhYe =  m_uhYe;     } break;
655  case(   HALF_PEL ): { uiTempBlockSize = (m_uiWidth<<1); uhXs =  m_uhXs;     uhYs =  m_uhYs;     uhXe =  m_uhXe;     uhYe =  m_uhYe;     } break;
656  }
657
658  if( m_eWedgeRes == DOUBLE_PEL) // adjust line-end for DOUBLE_PEL resolution
659  {
660    if( m_uhOri == 1 ) { uhXs = uiTempBlockSize-1; }
661    if( m_uhOri == 2 ) { uhXe = uiTempBlockSize-1; uhYs = uiTempBlockSize-1; }
662    if( m_uhOri == 3 ) { uhYe = uiTempBlockSize-1; }
663    if( m_uhOri == 4 ) { uhYe = uiTempBlockSize-1; }
664    if( m_uhOri == 5 ) { uhXs = uiTempBlockSize-1; }
665  }
666
667  Bool* pbTempPattern = new Bool[ (uiTempBlockSize * uiTempBlockSize) ];
668  ::memset( pbTempPattern, 0, (uiTempBlockSize * uiTempBlockSize) * sizeof(Bool) );
669  Int iTempStride = uiTempBlockSize;
670
671  xDrawEdgeLine( uhXs, uhYs, uhXe, uhYe, pbTempPattern, iTempStride );
672
673  switch( m_uhOri )
674  {
675  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;
676  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;
677  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;
678  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;
679  case( 4 ): 
680    { 
681      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++; } } }
682      else                                { for( UInt iY = 0; iY < uiTempBlockSize; iY++ ) { UInt iX = uiTempBlockSize-1; while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iX--; } } }
683    }
684    break;
685  case( 5 ): 
686    { 
687      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++; } } }
688      else                                { for( UInt iX = 0; iX < uiTempBlockSize; iX++ ) { UInt iY = uiTempBlockSize-1; while( pbTempPattern[(iY * iTempStride) + iX] == false ) { pbTempPattern[(iY * iTempStride) + iX] = true; iY--; } } }
689    }
690  }
691
692  clear();
693  switch( m_eWedgeRes )
694  {
695  case( DOUBLE_PEL ): { for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ ) { m_pbPattern[k] = pbTempPattern[k]; }; } break;
696  case(   FULL_PEL ): { for( UInt k = 0; k < (m_uiWidth * m_uiHeight); k++ ) { m_pbPattern[k] = pbTempPattern[k]; }; } break;
697  case(   HALF_PEL ): // sub-sampling by factor 2
698    {
699      Int iStride = getStride();
700
701      UInt uiOffX, uiOffY;
702      switch( m_uhOri )
703      {
704      case( 0 ): { uiOffX = 0; uiOffY = 0; } break;
705      case( 1 ): { uiOffX = 1; uiOffY = 0; } break;
706      case( 2 ): { uiOffX = 1; uiOffY = 1; } break;
707      case( 3 ): { uiOffX = 0; uiOffY = 1; } break;
708      case( 4 ): 
709        { 
710          if( (uhXs+uhXe) < uiTempBlockSize ) { uiOffX = 0; uiOffY = 0; }
711          else                                { uiOffX = 1; uiOffY = 0; }
712        } 
713        break;
714      case( 5 ): 
715        { 
716          if( (uhYs+uhYe) < uiTempBlockSize ) { uiOffX = 0; uiOffY = 0; }
717          else                                { uiOffX = 0; uiOffY = 1; }
718        } 
719        break;
720      default:   { uiOffX = 0; uiOffY = 0; } break;
721      }
722
723      for(Int iY = 0; iY < m_uiHeight; iY++)
724      {
725        for(Int iX = 0; iX < m_uiWidth; iX++)
726        {
727          m_pbPattern[(iY * iStride) + iX] = pbTempPattern[(((iY<<1)+uiOffY) * iTempStride) + ((iX<<1)+uiOffX)];
728        }
729      }
730    }
731    break;
732  }
733
734  if( pbTempPattern )
735  {
736    delete [] pbTempPattern;
737    pbTempPattern = NULL;
738  }
739}
740
741Void TComWedgelet::xDrawEdgeLine( UChar uhXs, UChar uhYs, UChar uhXe, UChar uhYe, Bool* pbPattern, Int iPatternStride )
742{
743  Int x0 = (Int)uhXs;
744  Int y0 = (Int)uhYs;
745  Int x1 = (Int)uhXe;
746  Int y1 = (Int)uhYe;
747
748  // direction independent Bresenham line
749  bool steep = (abs(y1 - y0) > abs(x1 - x0));
750  if( steep )
751  {
752    std::swap( x0, y0 );
753    std::swap( x1, y1 );
754  }
755
756  bool backward = ( x0 > x1 );
757  if( backward )
758  {
759    std::swap( x0, x1 );
760    std::swap( y0, y1 );
761  }
762
763  Int deltax = x1 - x0;
764  Int deltay = abs(y1 - y0);
765  Int error = 0;
766  Int deltaerr = (deltay<<1);
767
768  Int ystep;
769  Int y = y0;
770  if( y0 < y1 ) ystep =  1;
771  else          ystep = -1;
772
773  for( Int x = x0; x <= x1; x++ )
774  {
775    if( steep ) { pbPattern[(x * iPatternStride) + y] = true; }
776    else        { pbPattern[(y * iPatternStride) + x] = true; }
777
778    error += deltaerr;
779    if( error >= deltax )
780    {
781      y += ystep;
782      error = error - (deltax<<1);
783    }
784  }
785}
786
787TComWedgeNode::TComWedgeNode()
788{
789  m_uiPatternIdx = DMM_NO_WEDGEINDEX;
790  for( UInt uiPos = 0; uiPos < DMM_NUM_WEDGE_REFINES; uiPos++ )
791  {
792    m_uiRefineIdx[uiPos] = DMM_NO_WEDGEINDEX;
793  }
794}
795
796UInt TComWedgeNode::getPatternIdx()
797{
798  return m_uiPatternIdx;
799}
800UInt TComWedgeNode::getRefineIdx( UInt uiPos )
801{
802  assert( uiPos < DMM_NUM_WEDGE_REFINES );
803  return m_uiRefineIdx[uiPos];
804}
805Void TComWedgeNode::setPatternIdx( UInt uiIdx )
806{
807  m_uiPatternIdx = uiIdx;
808}
809Void TComWedgeNode::setRefineIdx( UInt uiIdx, UInt uiPos )
810{
811  assert( uiPos < DMM_NUM_WEDGE_REFINES );
812  m_uiRefineIdx[uiPos] = uiIdx; 
813}
814#endif //H_3D_DIM_DMM
Note: See TracBrowser for help on using the repository browser.