source: 3DVCSoftware/branches/0.3-nokia/source/Lib/TLibCommon/TComWedgelet.cpp @ 122

Last change on this file since 122 was 5, checked in by hhi, 13 years ago

Clean version with cfg-files

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