source: 3DVCSoftware/branches/HTM-DEV-2.0-dev2-Sharp/source/Lib/TLibCommon/TComWedgelet.cpp

Last change on this file was 539, checked in by orange, 11 years ago

Integrated QTLPC and added new line mark at the end of TComWedgelet.cpp for MERL

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