source: 3DVCSoftware/branches/0.1-poznan-univ/source/Lib/TLibCommon/TComWedgelet.cpp @ 1417

Last change on this file since 1417 was 2, checked in by hhi, 13 years ago

inital import

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