Ignore:
Timestamp:
6 Jun 2013, 11:46:05 (11 years ago)
Author:
hhi
Message:

Integation of depth intra methods in macro H_3D_DIM, including:

  • DMM coding modes in H_3D_DIM_DMM.
  • RBC coding mode in H_3D_DIM_RBC.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HTM-DEV-0.3-dev1/source/Lib/TLibEncoder/TEncSearch.cpp

    r446 r459  
    10471047    pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
    10481048    //===== get prediction signal =====
     1049#if H_3D_DIM
     1050    if( isDimMode( uiLumaPredMode ) )
     1051    {
     1052      predIntraLumaDepth( pcCU, uiAbsPartIdx, uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, true );
     1053    }
     1054    else
     1055    {
     1056#endif
    10491057    predIntraLumaAng( pcCU->getPattern(), uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail );
     1058#if H_3D_DIM
     1059    }
     1060#endif
     1061
    10501062    // save prediction
    10511063    if(default0Save1Load2 == 1)
     
    12241236  {
    12251237    uiChromaPredMode          = pcCU->getLumaIntraDir( 0 );
     1238#if H_3D_DIM
     1239    mapDepthModeToIntraDir( uiChromaPredMode );
     1240#endif
    12261241  }
    12271242 
     
    14311446#endif
    14321447#endif
     1448#if H_3D_DIM
     1449  if( isDimMode( pcCU->getLumaIntraDir( uiAbsPartIdx ) ) )
     1450  {
     1451    bCheckSplit = false;
     1452  }
     1453#endif
     1454
    14331455  Double  dSingleCost   = MAX_DOUBLE;
    14341456#if H_3D_VSO
     
    26242646    }
    26252647   
     2648#if H_3D_DIM
     2649    //===== determine set of depth intra modes to be tested =====
     2650    if( m_pcEncCfg->getIsDepth() && uiWidth >= DIM_MIN_SIZE && uiWidth <= DIM_MAX_SIZE && uiWidth == uiHeight )
     2651    {
     2652#if H_3D_DIM_DMM
     2653      if( m_pcEncCfg->getUseDMM() )
     2654      {
     2655        for( UInt dmmType = 0; dmmType < DMM_NUM_TYPE; dmmType++ )
     2656        {
     2657          UInt uiTabIdx = 0;
     2658          TComWedgelet* biSegmentation = NULL;
     2659          Pel deltaDC1 = 0; Pel deltaDC2 = 0;
     2660          switch( dmmType )
     2661          {
     2662          case( DMM1_IDX ):
     2663            {
     2664              xSearchDmm1Wedge( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight, uiTabIdx );
     2665              pcCU->setDmmWedgeTabIdxSubParts( uiTabIdx, dmmType,  uiPartOffset, uiDepth + uiInitTrDepth );
     2666              biSegmentation = &(g_dmmWedgeLists[(g_aucConvertToBit[uiWidth])][uiTabIdx]);
     2667            } break;
     2668          case( DMM2_IDX ):
     2669            {
     2670              if( uiWidth > 4 )
     2671              {
     2672                Int dmm2DeltaEnd = 0;
     2673                xSearchDmm2Wedge( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight, uiTabIdx, dmm2DeltaEnd );
     2674                pcCU->setDmmWedgeTabIdxSubParts( uiTabIdx, dmmType, uiPartOffset, uiDepth + uiInitTrDepth );
     2675                pcCU->setDmm2DeltaEndSubParts( dmm2DeltaEnd, uiPartOffset, uiDepth + uiInitTrDepth );
     2676                biSegmentation = &(g_dmmWedgeLists[(g_aucConvertToBit[uiWidth])][uiTabIdx]);
     2677              }
     2678            } break;
     2679          case( DMM3_IDX ):
     2680            {
     2681              UInt uiIntraTabIdx = 0;
     2682              xSearchDmm3Wedge( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight, uiTabIdx, uiIntraTabIdx );
     2683              pcCU->setDmmWedgeTabIdxSubParts( uiTabIdx, dmmType, uiPartOffset, uiDepth + uiInitTrDepth );
     2684              pcCU->setDmm3IntraTabIdxSubParts( uiIntraTabIdx, uiPartOffset, uiDepth + uiInitTrDepth );
     2685              biSegmentation = &(g_dmmWedgeLists[(g_aucConvertToBit[uiWidth])][uiTabIdx]);
     2686            } break;
     2687          case( DMM4_IDX ):
     2688            {
     2689              if( uiWidth > 4 )
     2690              {
     2691                biSegmentation = new TComWedgelet( uiWidth, uiHeight );
     2692                xPredContourFromTex( pcCU, uiPartOffset, uiWidth, uiHeight, biSegmentation );
     2693              }
     2694            } break;
     2695          default: assert(0);
     2696          }
     2697
     2698          if( biSegmentation )
     2699          {
     2700            xSearchDmmDeltaDCs( pcCU, uiPartOffset, piOrg, piPred, uiStride, biSegmentation->getPattern(), biSegmentation->getStride(), uiWidth, uiHeight, deltaDC1, deltaDC2 );
     2701            pcCU->setDimDeltaDC( dmmType, 0, uiPartOffset, deltaDC1 );
     2702            pcCU->setDimDeltaDC( dmmType, 1, uiPartOffset, deltaDC2 );
     2703
     2704            uiRdModeList[ numModesForFullRD++ ] = (2*dmmType  +DIM_OFFSET);
     2705            uiRdModeList[ numModesForFullRD++ ] = (2*dmmType+1+DIM_OFFSET);
     2706
     2707            if( DMM4_IDX == dmmType ) { biSegmentation->destroy(); delete biSegmentation; }
     2708          }
     2709        }
     2710      }
     2711#endif
     2712#if H_3D_DIM_RBC
     2713      if( m_pcEncCfg->getUseRBC() )
     2714      {
     2715        if( xSearchRbcEdge( pcCU, uiPartOffset, piOrg, uiStride, uiWidth, uiHeight ) )
     2716        {
     2717          Pel deltaDC1 = 0; Pel deltaDC2 = 0;
     2718          xSearchRbcDeltaDCs( pcCU, uiPartOffset, piOrg, piPred, uiStride, pcCU->getEdgePartition( uiPartOffset ), uiWidth, uiWidth, uiHeight, deltaDC1, deltaDC2 );
     2719          pcCU->setDimDeltaDC( RBC_IDX, 0, uiPartOffset, deltaDC1 );
     2720          pcCU->setDimDeltaDC( RBC_IDX, 1, uiPartOffset, deltaDC2 );
     2721
     2722          uiRdModeList[ numModesForFullRD++ ] = (2*RBC_IDX  +DIM_OFFSET);
     2723          uiRdModeList[ numModesForFullRD++ ] = (2*RBC_IDX+1+DIM_OFFSET);
     2724        }
     2725      }
     2726#endif
     2727    }
     2728#endif
     2729
    26262730    //===== check modes (using r-d costs) =====
    26272731#if HHI_RQT_INTRA_SPEEDUP_MOD
     
    60916195    // Reload only contexts required for coding intra mode information
    60926196    m_pcRDGoOnSbacCoder->loadIntraDirModeLuma( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
     6197#if H_3D_DIM
     6198    m_pcRDGoOnSbacCoder->loadIntraDepthMode( m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST] );
     6199#endif
    60936200  }
    60946201 
     
    64076514}
    64086515
     6516  // -------------------------------------------------------------------------------------------------------------------
     6517  // Depth intra search
     6518  // -------------------------------------------------------------------------------------------------------------------
     6519#if H_3D_DIM
     6520Void TEncSearch::xCalcBiSegDCs( Pel* ptrSrc, UInt srcStride, Bool* biSegPattern, Int patternStride, Pel& valDC1, Pel& valDC2 )
     6521{
     6522  valDC1 = ( 1<<( g_bitDepthY - 1) );
     6523  valDC2 = ( 1<<( g_bitDepthY - 1) );
     6524
     6525  UInt uiDC1 = 0;
     6526  UInt uiDC2 = 0;
     6527  UInt uiNumPixDC1 = 0, uiNumPixDC2 = 0;
     6528  if( srcStride == patternStride )
     6529  {
     6530    for( UInt k = 0; k < (patternStride * patternStride); k++ )
     6531    {
     6532      if( true == biSegPattern[k] )
     6533      {
     6534        uiDC2 += ptrSrc[k];
     6535        uiNumPixDC2++;
     6536      }
     6537      else
     6538      {
     6539        uiDC1 += ptrSrc[k];
     6540        uiNumPixDC1++;
     6541      }
     6542    }
     6543  }
     6544  else
     6545  {
     6546    Pel* piTemp = ptrSrc;
     6547    for( UInt uiY = 0; uiY < patternStride; uiY++ )
     6548    {
     6549      for( UInt uiX = 0; uiX < patternStride; uiX++ )
     6550      {
     6551        if( true == biSegPattern[uiX] )
     6552        {
     6553          uiDC2 += piTemp[uiX];
     6554          uiNumPixDC2++;
     6555        }
     6556        else
     6557        {
     6558          uiDC1 += piTemp[uiX];
     6559          uiNumPixDC1++;
     6560        }
     6561      }
     6562      piTemp       += srcStride;
     6563      biSegPattern += patternStride;
     6564    }
     6565  }
     6566
     6567  if( uiNumPixDC1 > 0 ) { valDC1 = uiDC1 / uiNumPixDC1; }
     6568  if( uiNumPixDC2 > 0 ) { valDC2 = uiDC2 / uiNumPixDC2; }
     6569}
     6570
     6571#if H_3D_DIM_DMM
     6572Void TEncSearch::xSearchDmmDeltaDCs( TComDataCU* pcCU, UInt uiAbsPtIdx, Pel* piOrig, Pel* piPredic, UInt uiStride, Bool* biSegPattern, Int patternStride, UInt uiWidth, UInt uiHeight, Pel& rDeltaDC1, Pel& rDeltaDC2 )
     6573{
     6574  assert( biSegPattern );
     6575  Pel origDC1 = 0; Pel origDC2 = 0;
     6576  xCalcBiSegDCs  ( piOrig,   uiStride, biSegPattern, patternStride, origDC1, origDC2 );
     6577  xAssignBiSegDCs( piPredic, uiStride, biSegPattern, patternStride, origDC1, origDC2 );
     6578
     6579  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt ); // no filtering for DMM
     6580  Int  maskStride = 2*uiWidth + 1;
     6581  Int* ptrSrc = piMask+maskStride+1;
     6582  Pel  predDC1 = 0; Pel predDC2 = 0;
     6583  xPredBiSegDCs( ptrSrc, maskStride, biSegPattern, patternStride, predDC1, predDC2 );
     6584
     6585  rDeltaDC1 = origDC1 - predDC1;
     6586  rDeltaDC2 = origDC2 - predDC2;
     6587
     6588#if H_3D_VSO
     6589  if( m_pcRdCost->getUseVSO() )
     6590  {
     6591    Pel fullDeltaDC1 = rDeltaDC1;
     6592    Pel fullDeltaDC2 = rDeltaDC2;
     6593
     6594    Dist uiBestDist      = RDO_DIST_MAX;
     6595    UInt  uiBestQStepDC1 = 0;
     6596    UInt  uiBestQStepDC2 = 0;
     6597
     6598    UInt uiDeltaDC1Max = abs(fullDeltaDC1);
     6599    UInt uiDeltaDC2Max = abs(fullDeltaDC2);
     6600
     6601    //VSO Level delta DC check range extension
     6602    uiDeltaDC1Max += (uiDeltaDC1Max>>1);
     6603    uiDeltaDC2Max += (uiDeltaDC2Max>>1);
     6604
     6605    // limit search range to [0, IBDI_MAX]
     6606    if( fullDeltaDC1 <  0 && uiDeltaDC1Max >                          abs(predDC1) ) { uiDeltaDC1Max =                          abs(predDC1); }
     6607    if( fullDeltaDC1 >= 0 && uiDeltaDC1Max > ((1 << g_bitDepthY)-1) - abs(predDC1) ) { uiDeltaDC1Max = ((1 << g_bitDepthY)-1) - abs(predDC1); }
     6608
     6609    if( fullDeltaDC2 <  0 && uiDeltaDC2Max >                          abs(predDC2) ) { uiDeltaDC2Max =                          abs(predDC2); }
     6610    if( fullDeltaDC2 >= 0 && uiDeltaDC2Max > ((1 << g_bitDepthY)-1) - abs(predDC2) ) { uiDeltaDC2Max = ((1 << g_bitDepthY)-1) - abs(predDC2); }
     6611
     6612    // init dist with original segment DCs
     6613    xAssignBiSegDCs( piPredic, uiStride, biSegPattern, patternStride, origDC1, origDC2 );
     6614
     6615    Dist uiOrgDist = RDO_DIST_MAX;
     6616    if( m_pcRdCost->getUseEstimatedVSD() )
     6617    {
     6618      uiOrgDist = m_pcRdCost->getDistPartVSD( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6619    }
     6620    else
     6621    {
     6622      uiOrgDist = m_pcRdCost->getDistPartVSO( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6623    }
     6624
     6625    uiBestDist     = uiOrgDist;
     6626    uiBestQStepDC1 = abs(fullDeltaDC1);
     6627    uiBestQStepDC2 = abs(fullDeltaDC2);
     6628
     6629    // coarse search with step size 4
     6630    for( UInt uiQStepDC1 = 0; uiQStepDC1 < uiDeltaDC1Max; uiQStepDC1 += 4 )
     6631    {
     6632      Pel testDC1 = ClipY( predDC1 + ((Int)(uiQStepDC1) * (( fullDeltaDC1 < 0 ) ? -1 : 1)) );
     6633      for( UInt uiQStepDC2 = 0; uiQStepDC2 < uiDeltaDC2Max; uiQStepDC2 += 4 )
     6634      {
     6635        Pel testDC2 = ClipY( predDC2 + ((Int)(uiQStepDC2) * (( fullDeltaDC2 < 0 ) ? -1 : 1)) );
     6636
     6637        xAssignBiSegDCs( piPredic, uiStride, biSegPattern, patternStride, testDC1, testDC2 );
     6638
     6639        Dist uiAct4Dist = RDO_DIST_MAX;
     6640        if( m_pcRdCost->getUseEstimatedVSD() )
     6641        {
     6642          uiAct4Dist = m_pcRdCost->getDistPartVSD( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6643        }
     6644        else
     6645        {
     6646          uiAct4Dist = m_pcRdCost->getDistPartVSO( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6647        }
     6648
     6649        if( uiAct4Dist < uiBestDist || uiBestDist == RDO_DIST_MAX )
     6650        {
     6651          uiBestDist     = uiAct4Dist;
     6652          uiBestQStepDC1 = uiQStepDC1;
     6653          uiBestQStepDC2 = uiQStepDC2;
     6654        }
     6655      }
     6656    }
     6657
     6658    // refinement +-3
     6659    for( UInt uiQStepDC1 = (UInt)max(0, ((Int)uiBestQStepDC1-3)); uiQStepDC1 <= (uiBestQStepDC1+3); uiQStepDC1++ )
     6660    {
     6661      Pel testDC1 = ClipY( predDC1 + ((Int)(uiQStepDC1) * (( fullDeltaDC1 < 0 ) ? -1 : 1)) );
     6662      for( UInt uiQStepDC2 = (UInt)max(0, ((Int)uiBestQStepDC2-3)); uiQStepDC2 <= (uiBestQStepDC2+3); uiQStepDC2++ )
     6663      {
     6664        Pel testDC2 = ClipY( predDC2 + ((Int)(uiQStepDC2) * (( fullDeltaDC2 < 0 ) ? -1 : 1)) );
     6665
     6666        xAssignBiSegDCs( piPredic, uiStride, biSegPattern, patternStride, testDC1, testDC2 );
     6667
     6668        Dist uiActDist = RDO_DIST_MAX;
     6669        if( m_pcRdCost->getUseEstimatedVSD() )
     6670        {
     6671          uiActDist = m_pcRdCost->getDistPartVSD( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6672        }
     6673        else
     6674        {
     6675          uiActDist = m_pcRdCost->getDistPartVSO( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6676        }
     6677
     6678        if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
     6679        {
     6680          uiBestDist     = uiActDist;
     6681          uiBestQStepDC1 = uiQStepDC1;
     6682          uiBestQStepDC2 = uiQStepDC2;
     6683        }
     6684      }
     6685    }
     6686    rDeltaDC1 = (Int)(uiBestQStepDC1) * (Int)(( fullDeltaDC1 < 0 ) ? -1 : 1);
     6687    rDeltaDC2 = (Int)(uiBestQStepDC2) * (Int)(( fullDeltaDC2 < 0 ) ? -1 : 1);
     6688  }
     6689#endif
     6690
     6691#if H_3D_DIM_DLT
     6692  rDeltaDC1 = (Int)GetDepthValue2Idx( ClipY(predDC1 + rDeltaDC1) ) - (Int)GetDepthValue2Idx( predDC1 );
     6693  rDeltaDC2 = (Int)GetDepthValue2Idx( ClipY(predDC2 + rDeltaDC2) ) - (Int)GetDepthValue2Idx( predDC2 );
     6694#endif
     6695}
     6696
     6697Void TEncSearch::xSearchDmm1Wedge( TComDataCU* pcCU, UInt uiAbsPtIdx, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx )
     6698{
     6699  ruiTabIdx = 0;
     6700
     6701  // local pred buffer
     6702  TComYuv cPredYuv;
     6703  cPredYuv.create( uiWidth, uiHeight );
     6704  cPredYuv.clear();
     6705
     6706  UInt uiPredStride = cPredYuv.getStride();
     6707  Pel* piPred       = cPredYuv.getLumaAddr();
     6708
     6709  Pel refDC1 = 0; Pel refDC2 = 0;
     6710  WedgeList*     pacWedgeList     = &g_dmmWedgeLists    [(g_aucConvertToBit[uiWidth])];
     6711  WedgeNodeList* pacWedgeNodeList = &g_dmmWedgeNodeLists[(g_aucConvertToBit[uiWidth])];
     6712
     6713  // coarse wedge search
     6714  Dist uiBestDist   = RDO_DIST_MAX;
     6715  UInt uiBestNodeId = 0;
     6716  for( UInt uiNodeId = 0; uiNodeId < pacWedgeNodeList->size(); uiNodeId++ )
     6717  {
     6718    TComWedgelet* pcWedgelet = &(pacWedgeList->at(pacWedgeNodeList->at(uiNodeId).getPatternIdx()));
     6719    xCalcBiSegDCs  ( piRef,  uiRefStride,  pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6720    xAssignBiSegDCs( piPred, uiPredStride, pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6721
     6722    Dist uiActDist = RDO_DIST_MAX;
     6723#if H_3D_VSO
     6724    if( m_pcRdCost->getUseVSO() )
     6725    {
     6726      if( m_pcRdCost->getUseEstimatedVSD() )
     6727      {
     6728        uiActDist = m_pcRdCost->getDistPartVSD( pcCU, uiAbsPtIdx, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false );
     6729      }
     6730      else
     6731      {
     6732        uiActDist = m_pcRdCost->getDistPartVSO( pcCU, uiAbsPtIdx, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false );
     6733      }
     6734    }
     6735    else
     6736#endif
     6737    {
     6738      uiActDist = m_pcRdCost->getDistPart( g_bitDepthY, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, TEXT_LUMA, DF_SAD );
     6739    }
     6740
     6741    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
     6742    {
     6743      uiBestDist   = uiActDist;
     6744      uiBestNodeId = uiNodeId;
     6745    }
     6746  }
     6747
     6748  // refinement
     6749  Dist uiBestDistRef = uiBestDist;
     6750  UInt uiBestTabIdxRef  = pacWedgeNodeList->at(uiBestNodeId).getPatternIdx();
     6751  for( UInt uiRefId = 0; uiRefId < DMM_NUM_WEDGE_REFINES; uiRefId++ )
     6752  {
     6753    if( pacWedgeNodeList->at(uiBestNodeId).getRefineIdx( uiRefId ) != DMM_NO_WEDGEINDEX )
     6754    {
     6755      TComWedgelet* pcWedgelet = &(pacWedgeList->at(pacWedgeNodeList->at(uiBestNodeId).getRefineIdx( uiRefId )));
     6756      xCalcBiSegDCs  ( piRef,  uiRefStride,  pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6757      xAssignBiSegDCs( piPred, uiPredStride, pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6758
     6759      Dist uiActDist = RDO_DIST_MAX;
     6760#if H_3D_VSO
     6761      if( m_pcRdCost->getUseVSO() )
     6762      {
     6763        if( m_pcRdCost->getUseEstimatedVSD() )
     6764        {
     6765          uiActDist = m_pcRdCost->getDistPartVSD( pcCU, uiAbsPtIdx, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false );
     6766        }
     6767        else
     6768        {
     6769          uiActDist = m_pcRdCost->getDistPartVSO( pcCU, uiAbsPtIdx, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false );
     6770        }
     6771      }
     6772      else
     6773#endif
     6774      {
     6775        uiActDist = m_pcRdCost->getDistPart( g_bitDepthY, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, TEXT_LUMA, DF_SAD );
     6776      }
     6777
     6778      if( uiActDist < uiBestDistRef || uiBestDistRef == RDO_DIST_MAX )
     6779      {
     6780        uiBestDistRef   = uiActDist;
     6781        uiBestTabIdxRef = pacWedgeNodeList->at(uiBestNodeId).getRefineIdx( uiRefId );
     6782      }
     6783    }
     6784  }
     6785
     6786  ruiTabIdx = uiBestTabIdxRef;
     6787
     6788  cPredYuv.destroy();
     6789  return;
     6790}
     6791
     6792Void TEncSearch::xSearchDmm2Wedge( TComDataCU* pcCU, UInt uiAbsPtIdx, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx, Int& riWedgeDeltaEnd )
     6793{
     6794  ruiTabIdx       = 0;
     6795  riWedgeDeltaEnd = 0;
     6796
     6797  // local pred buffer
     6798  TComYuv cPredYuv;
     6799  cPredYuv.create( uiWidth, uiHeight );
     6800  cPredYuv.clear();
     6801
     6802  UInt uiPredStride = cPredYuv.getStride();
     6803  Pel* piPred       = cPredYuv.getLumaAddr();
     6804
     6805
     6806  // regular wedge search
     6807  Dist uiBestDist    = RDO_DIST_MAX;
     6808  UInt uiBestTabIdx  = 0;
     6809  Int  iBestDeltaEnd = 0;
     6810
     6811  UInt uiIdx = 0;
     6812  Pel refDC1 = 0; Pel refDC2 = 0;
     6813  for( Int iTestDeltaEnd = -DMM2_DELTAEND_MAX; iTestDeltaEnd <= DMM2_DELTAEND_MAX; iTestDeltaEnd++ )
     6814  {
     6815    uiIdx = xPredWedgeFromIntra( pcCU, uiAbsPtIdx, uiWidth, uiHeight, iTestDeltaEnd );
     6816    TComWedgelet* pcWedgelet = &(g_dmmWedgeLists[(g_aucConvertToBit[uiWidth])][uiIdx]);
     6817    xCalcBiSegDCs  ( piRef,  uiRefStride,  pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6818    xAssignBiSegDCs( piPred, uiPredStride, pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6819
     6820    Dist uiActDist = RDO_DIST_MAX;
     6821#if H_3D_VSO
     6822    if( m_pcRdCost->getUseVSO() )
     6823    {
     6824      if( m_pcRdCost->getUseEstimatedVSD() )
     6825      {
     6826        uiActDist = m_pcRdCost->getDistPartVSD( pcCU, uiAbsPtIdx, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false );
     6827      }
     6828      else
     6829      {
     6830        uiActDist = m_pcRdCost->getDistPartVSO( pcCU, uiAbsPtIdx, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, false );
     6831      }
     6832    }
     6833    else
     6834#endif
     6835    {
     6836      uiActDist = m_pcRdCost->getDistPart( g_bitDepthY, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, TEXT_LUMA, DF_SAD );
     6837    }
     6838
     6839    if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
     6840    {
     6841      uiBestDist    = uiActDist;
     6842      uiBestTabIdx  = uiIdx;
     6843      iBestDeltaEnd = iTestDeltaEnd;
     6844    }
     6845    else if( uiIdx == uiBestTabIdx && abs(iTestDeltaEnd) < abs(iBestDeltaEnd) )
     6846    {
     6847      iBestDeltaEnd = iTestDeltaEnd;
     6848    }
     6849  }
     6850
     6851  ruiTabIdx       = uiBestTabIdx;
     6852  riWedgeDeltaEnd = iBestDeltaEnd;
     6853
     6854  cPredYuv.destroy();
     6855  return;
     6856}
     6857
     6858Void TEncSearch::xSearchDmm3Wedge( TComDataCU* pcCU, UInt uiAbsPtIdx, Pel* piRef, UInt uiRefStride, UInt uiWidth, UInt uiHeight, UInt& ruiTabIdx, UInt& ruiIntraTabIdx )
     6859{
     6860  ruiTabIdx       = 0;
     6861  ruiIntraTabIdx  = 0;
     6862
     6863  // local pred buffer
     6864  TComYuv cPredYuv;
     6865  cPredYuv.create( uiWidth, uiHeight );
     6866  cPredYuv.clear();
     6867  Pel* piPred = cPredYuv.getLumaAddr();
     6868  UInt uiPredStride = cPredYuv.getStride();
     6869
     6870  // wedge search
     6871  UInt uiBestDist = MAX_UINT;
     6872  WedgeList* pacWedgeList = &g_dmmWedgeLists[(g_aucConvertToBit[uiWidth])];
     6873  Pel refDC1 = 0; Pel refDC2 = 0;
     6874
     6875  TComPic*      pcPicTex = pcCU->getSlice()->getPicLists()->getPic( pcCU->getSlice()->getViewIndex(), false, pcCU->getSlice()->getPOC() );
     6876  assert( pcPicTex != NULL );
     6877  TComDataCU* pcColTexCU = pcPicTex->getCU(pcCU->getAddr());
     6878  UInt      uiTexPartIdx = pcCU->getZorderIdxInCU() + uiAbsPtIdx;
     6879  Int   uiColTexIntraDir = pcColTexCU->isIntra( uiTexPartIdx ) ? pcColTexCU->getLumaIntraDir( uiTexPartIdx ) : 255;
     6880
     6881  std::vector< std::vector<UInt> > pauiWdgLstSz = g_aauiWdgLstM3[g_aucConvertToBit[uiWidth]];
     6882  if( uiColTexIntraDir > DC_IDX && uiColTexIntraDir < 35 )
     6883  {
     6884    std::vector<UInt>* pauiWdgLst = &pauiWdgLstSz[uiColTexIntraDir-2];
     6885    for( UInt uiIdxW = 0; uiIdxW < pauiWdgLst->size(); uiIdxW++ )
     6886    {
     6887      UInt uiIdx     =   pauiWdgLst->at(uiIdxW);
     6888      TComWedgelet* pcWedgelet = &(pacWedgeList->at(uiIdx));
     6889      xCalcBiSegDCs  ( piRef,  uiRefStride,  pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6890      xAssignBiSegDCs( piPred, uiPredStride, pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6891
     6892      UInt uiActDist = m_pcRdCost->getDistPart( g_bitDepthY, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, TEXT_LUMA, DF_SAD );
     6893      if( uiActDist < uiBestDist || uiBestDist == MAX_UINT )
     6894      {
     6895        uiBestDist     = uiActDist;
     6896        ruiTabIdx      = uiIdx;
     6897        ruiIntraTabIdx = uiIdxW;
     6898      }
     6899    }
     6900  }
     6901  else
     6902  {
     6903    WedgeNodeList* pacWedgeNodeList = &g_dmmWedgeNodeLists[(g_aucConvertToBit[uiWidth])];
     6904    UInt uiBestNodeDist = MAX_UINT;
     6905    UInt uiBestNodeId   = 0;
     6906    for( UInt uiNodeId = 0; uiNodeId < pacWedgeNodeList->size(); uiNodeId++ )
     6907    {
     6908      TComWedgelet* pcWedgelet = &(pacWedgeList->at(pacWedgeNodeList->at(uiNodeId).getPatternIdx()));
     6909      xCalcBiSegDCs  ( piRef,  uiRefStride,  pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6910      xAssignBiSegDCs( piPred, uiPredStride, pcWedgelet->getPattern(), pcWedgelet->getStride(), refDC1, refDC2 );
     6911
     6912      UInt uiActDist = m_pcRdCost->getDistPart( g_bitDepthY, piPred, uiPredStride, piRef, uiRefStride, uiWidth, uiHeight, TEXT_LUMA, DF_SAD );
     6913      if( uiActDist < uiBestNodeDist || uiBestNodeDist == MAX_UINT )
     6914      {
     6915        uiBestNodeDist = uiActDist;
     6916        uiBestNodeId   = uiNodeId;
     6917        ruiIntraTabIdx = uiNodeId;
     6918      }
     6919    }
     6920    ruiTabIdx = pacWedgeNodeList->at(uiBestNodeId).getPatternIdx();
     6921  }
     6922
     6923  cPredYuv.destroy();
     6924}
     6925#endif
     6926#if H_3D_DIM_RBC
     6927Void TEncSearch::xSearchRbcDeltaDCs( TComDataCU* pcCU, UInt uiAbsPtIdx, Pel* piOrig, Pel* piPredic, UInt uiStride, Bool* biSegPattern, Int patternStride, UInt uiWidth, UInt uiHeight, Pel& rDeltaDC1, Pel& rDeltaDC2 )
     6928{
     6929  assert( biSegPattern );
     6930  Pel origDC1 = 0; Pel origDC2 = 0;
     6931  xCalcBiSegDCs  ( piOrig,   uiStride, biSegPattern, patternStride, origDC1, origDC2 );
     6932  xAssignBiSegDCs( piPredic, uiStride, biSegPattern, patternStride, origDC1, origDC2 );
     6933
     6934  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt ); // no filtering for DMM
     6935  Int  maskStride = 2*uiWidth + 1;
     6936  Int* ptrSrc = piMask+maskStride+1;
     6937  Pel  predDC1 = 0; Pel predDC2 = 0;
     6938  xPredBiSegDCs( ptrSrc, maskStride, biSegPattern, patternStride, predDC1, predDC2 );
     6939
     6940  rDeltaDC1 = origDC1 - predDC1;
     6941  rDeltaDC2 = origDC2 - predDC2;
     6942
     6943#if H_3D_VSO
     6944  if( m_pcRdCost->getUseVSO() )
     6945  {
     6946    Pel fullDeltaDC1 = rDeltaDC1;
     6947    Pel fullDeltaDC2 = rDeltaDC2;
     6948
     6949    xDeltaDCQuantScaleDown( pcCU, fullDeltaDC1 );
     6950    xDeltaDCQuantScaleDown( pcCU, fullDeltaDC2 );
     6951
     6952    Dist uiBestDist     = RDO_DIST_MAX;
     6953    UInt uiBestQStepDC1 = 0;
     6954    UInt uiBestQStepDC2 = 0;
     6955
     6956    UInt uiDeltaDC1Max = abs(fullDeltaDC1);
     6957    UInt uiDeltaDC2Max = abs(fullDeltaDC2);
     6958
     6959    //VSO Level delta DC check range extension
     6960    uiDeltaDC1Max += (uiDeltaDC1Max>>1);
     6961    uiDeltaDC2Max += (uiDeltaDC2Max>>1);
     6962
     6963    for( UInt uiQStepDC1 = 1; uiQStepDC1 <= uiDeltaDC1Max; uiQStepDC1++  )
     6964    {
     6965      Pel iLevelDeltaDC1 = (Pel)(uiQStepDC1) * (Pel)(( fullDeltaDC1 < 0 ) ? -1 : 1);
     6966      xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC1 );
     6967      Pel testDC1 = ClipY( predDC1 + iLevelDeltaDC1 );
     6968
     6969      for( UInt uiQStepDC2 = 1; uiQStepDC2 <= uiDeltaDC2Max; uiQStepDC2++  )
     6970      {
     6971        Pel iLevelDeltaDC2 = (Pel)(uiQStepDC2) * (Pel)(( fullDeltaDC2 < 0 ) ? -1 : 1);
     6972        xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC2 );
     6973        Pel testDC2 = ClipY( predDC2 + iLevelDeltaDC2 );
     6974
     6975        xAssignBiSegDCs( piPredic, uiStride, biSegPattern, patternStride, testDC1, testDC2 );
     6976
     6977        Dist uiActDist = RDO_DIST_MAX;
     6978        if( m_pcRdCost->getUseEstimatedVSD() )
     6979        {
     6980          uiActDist = m_pcRdCost->getDistPartVSD( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6981        }
     6982        else
     6983        {
     6984          uiActDist = m_pcRdCost->getDistPartVSO( pcCU, uiAbsPtIdx, piPredic, uiStride, piOrig, uiStride, uiWidth, uiHeight, false );
     6985        }
     6986
     6987        if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
     6988        {
     6989          uiBestDist     = uiActDist;
     6990          uiBestQStepDC1 = uiQStepDC1;
     6991          uiBestQStepDC2 = uiQStepDC2;
     6992        }
     6993      }
     6994    }
     6995
     6996    fullDeltaDC1 = (Int)(uiBestQStepDC1) * (Int)(( fullDeltaDC1 < 0 ) ? -1 : 1);
     6997    fullDeltaDC2 = (Int)(uiBestQStepDC2) * (Int)(( fullDeltaDC2 < 0 ) ? -1 : 1);
     6998    xDeltaDCQuantScaleUp( pcCU, fullDeltaDC1 );
     6999    xDeltaDCQuantScaleUp( pcCU, fullDeltaDC2 );
     7000    rDeltaDC1 = fullDeltaDC1;
     7001    rDeltaDC2 = fullDeltaDC2;
     7002  }
     7003#endif
     7004
     7005  xDeltaDCQuantScaleDown( pcCU, rDeltaDC1 );
     7006  xDeltaDCQuantScaleDown( pcCU, rDeltaDC2 );
     7007}
     7008
     7009Bool TEncSearch::xSearchRbcEdge( TComDataCU* pcCU, UInt uiAbsPtIdx, Pel* piRef, UInt uiRefStride, Int iWidth, Int iHeight )
     7010{
     7011  Bool* pbEdge  = (Bool*) xMalloc( Bool, iWidth * iHeight * 4 );
     7012
     7013  Short* psDiffX = new Short[ iWidth * iHeight ];
     7014  Short* psDiffY = new Short[ iWidth * iHeight ];
     7015  Bool*  pbEdgeX = new Bool [ iWidth * iHeight ];
     7016  Bool*  pbEdgeY = new Bool [ iWidth * iHeight ];
     7017
     7018  // Find Horizontal Gradient & Edge Detection ((x+1, y) - (x,y))
     7019  for( Int y=0; y<iHeight; y++ )
     7020  {
     7021    Short* psDiffXPtr = &psDiffX[ y * iHeight ];
     7022    Bool*  pbEdgeXPtr = &pbEdgeX[ y * iHeight ];
     7023    for(Int x=0; x<iWidth-1; x++ )
     7024    {
     7025      *psDiffXPtr = piRef[ x+1 + y*uiRefStride ] - piRef[ x + y*uiRefStride ];
     7026      if(*psDiffXPtr >= RBC_THRESHOLD || *psDiffXPtr <= (-1)*RBC_THRESHOLD)
     7027      {
     7028        *pbEdgeXPtr = true;
     7029      }
     7030      else
     7031      {
     7032        *pbEdgeXPtr = false;
     7033      }
     7034
     7035      psDiffXPtr++;
     7036      pbEdgeXPtr++;
     7037    }
     7038  }
     7039
     7040  // Find Vertical Gradient & Edge Detection((x,y+1) - (x,y))
     7041  for( Int y=0; y<iHeight-1; y++ )
     7042  {
     7043    Short* psDiffYPtr = &psDiffY[ y * iHeight ];
     7044    Bool*  pbEdgeYPtr = &pbEdgeY[ y * iHeight ];
     7045    for(Int x=0; x<iWidth; x++ )
     7046    {
     7047      *psDiffYPtr = piRef[ x + (y+1)*uiRefStride ] - piRef[ x + y*uiRefStride ];
     7048      if(*psDiffYPtr >= RBC_THRESHOLD || *psDiffYPtr <= (-1)*RBC_THRESHOLD)
     7049      {
     7050        *pbEdgeYPtr = true;
     7051      }
     7052      else
     7053      {
     7054        *pbEdgeYPtr = false;
     7055      }
     7056
     7057      psDiffYPtr++;
     7058      pbEdgeYPtr++;
     7059    }
     7060  }
     7061
     7062  // Eliminate local maximum
     7063  for( Int y=0; y<iHeight; y++ )
     7064  {
     7065    Short* psDiffXPtr = &psDiffX[ y * iHeight ];
     7066    Bool*  pbEdgeXPtr = &pbEdgeX[ y * iHeight ];
     7067    for( Int x=0; x<iWidth-1; x++ )
     7068    {
     7069      UShort usAbs0=0, usAbs1=0, usAbs2=0;  // 0 : left, 1 : current, 2 : right
     7070
     7071      if( x > 0 && *(pbEdgeXPtr-1) == true )
     7072      {
     7073        if( *(psDiffXPtr-1) >= 0)
     7074        {
     7075          usAbs0 = *(psDiffXPtr-1);
     7076
     7077        }
     7078        else
     7079        {
     7080          usAbs0 = (-1) * *(psDiffXPtr-1);
     7081        }
     7082      }
     7083      if( *pbEdgeXPtr == true )
     7084      {
     7085        if( *(psDiffXPtr) >= 0)
     7086        {
     7087          usAbs1 = *(psDiffXPtr);
     7088        }
     7089        else
     7090        {
     7091          usAbs1 = (-1) * *(psDiffXPtr);
     7092        }
     7093      }
     7094      if( x < iWidth-2 && *(pbEdgeXPtr+1) == true )
     7095      {
     7096        if( *(psDiffXPtr+1) >= 0)
     7097        {
     7098          usAbs2 = *(psDiffXPtr+1);
     7099          //bSign2 = true;
     7100        }
     7101        else
     7102        {
     7103          usAbs2 = (-1) * *(psDiffXPtr+1);
     7104        }
     7105      }
     7106
     7107      if( x == 0 )
     7108      {
     7109        if( usAbs1 < usAbs2 )
     7110        {
     7111          *pbEdgeXPtr = false;
     7112        }
     7113      }
     7114      else if( x == iWidth-2 )
     7115      {
     7116        if( usAbs1 <= usAbs0 )
     7117          *pbEdgeXPtr = false;
     7118      }
     7119      else
     7120      {
     7121        if( usAbs2 > usAbs0 )
     7122        {
     7123          if( usAbs1 < usAbs2 )
     7124            *pbEdgeXPtr = false;
     7125        }
     7126        else
     7127        {
     7128          if( usAbs1 <= usAbs0 )
     7129            *pbEdgeXPtr = false;
     7130        }
     7131      }
     7132
     7133      psDiffXPtr++;
     7134      pbEdgeXPtr++;
     7135    }
     7136  }
     7137
     7138  for( Int y=0; y<iHeight-1; y++ )
     7139  {
     7140    Short* psDiffYPtr = &psDiffY[ y * iWidth ];
     7141    Bool*  pbEdgeYPtr = &pbEdgeY[ y * iWidth ];
     7142    for( Int x=0; x<iWidth; x++ )
     7143    {
     7144      UShort usAbs0=0, usAbs1=0, usAbs2=0;  // 0 : upper, 1 : current, 2 : bottom
     7145      if( y > 0 && *(pbEdgeYPtr-iWidth) == true )
     7146      {
     7147        if( *(psDiffYPtr-iWidth) >= 0)
     7148        {
     7149          usAbs0 = *(psDiffYPtr-iWidth);
     7150        }
     7151        else
     7152        {
     7153          usAbs0 = (-1) * *(psDiffYPtr-iWidth);         
     7154        }
     7155      }
     7156      if( *pbEdgeYPtr == true )
     7157      {
     7158        if( *(psDiffYPtr) >= 0)
     7159        {
     7160          usAbs1 = *(psDiffYPtr);
     7161        }
     7162        else
     7163        {
     7164          usAbs1 = (-1) * *(psDiffYPtr);
     7165        }
     7166      }
     7167      if( y < iHeight-2 && *(pbEdgeYPtr+iWidth) == true )
     7168      {
     7169        if( *(psDiffYPtr+iWidth) >= 0)
     7170        {
     7171          usAbs2 = *(psDiffYPtr+iWidth);         
     7172        }
     7173        else
     7174        {
     7175          usAbs2 = (-1) * *(psDiffYPtr+iWidth);
     7176        }
     7177      }
     7178
     7179      if( y == 0 )
     7180      {
     7181        if( usAbs1 < usAbs2 )
     7182          *pbEdgeYPtr = false;
     7183      }
     7184      else if( y == iHeight-2 )
     7185      {
     7186        if( usAbs1 <= usAbs0 )
     7187          *pbEdgeYPtr = false;
     7188      }
     7189      else
     7190      {
     7191        if( usAbs2 > usAbs0 )
     7192        {
     7193          if( usAbs1 < usAbs2 )
     7194            *pbEdgeYPtr = false;
     7195        }
     7196        else
     7197        {
     7198          if( usAbs1 <= usAbs0 )
     7199            *pbEdgeYPtr = false;
     7200        }
     7201      }
     7202
     7203      psDiffYPtr++;
     7204      pbEdgeYPtr++;
     7205    }
     7206  }
     7207
     7208  // Edge Merging
     7209  for( Int i=0; i< 4 * iWidth * iHeight; i++ )
     7210    pbEdge[ i ] = false;
     7211  /// Even Line (0,2,4,6,...) => Vertical Edge
     7212  for( Int i=0; i<iHeight; i++)
     7213  {
     7214    for( Int j=0; j<iWidth-1; j++)
     7215    {
     7216      pbEdge[ (2 * j + 1) + (2 * i) * 2 * iWidth ] = pbEdgeX[ j + i * iHeight ];
     7217    }
     7218  }
     7219  /// Odd Line (1,3,5,7,...) => Horizontal Edge
     7220  for( Int i=0; i<iHeight-1; i++)
     7221  {
     7222    for( Int j=0; j<iWidth; j++)
     7223    {
     7224      pbEdge[ (2 * j) + (2 * i + 1) * 2 * iWidth ] = pbEdgeY[ j + i * iHeight ];
     7225    }
     7226  }
     7227
     7228  // Intersection Filling
     7229  /// Vertical Edge between Horizontal Edges
     7230  for( Int i = 1; i < 2 * iHeight - 3; i += 2)
     7231  {
     7232    for( Int j = 0; j < 2 * iWidth - 1; j += 2)
     7233    {
     7234      if( pbEdge[ j + i * 2 * iWidth ] )
     7235      {
     7236        if( j != 0 && pbEdge[ (j - 2) + ((i + 2) * 2 * iWidth) ] )
     7237        {
     7238          if( !pbEdge[ (j - 1) + ((i - 1) * 2 * iWidth) ] && !pbEdge[ (j - 1) + ((i + 3) * 2 * iWidth) ] )
     7239            pbEdge[ (j - 1) + ((i + 1) * 2 * iWidth) ] = true;
     7240        }
     7241        if( j != 2 * iWidth - 2 && pbEdge[ (j + 2) + ((i + 2) * 2 * iWidth) ] )
     7242        {
     7243          if( !pbEdge[ (j + 1) + ((i - 1) * 2 * iWidth) ] && !pbEdge[ (j + 1) + ((i + 3) * 2 * iWidth) ] )
     7244            pbEdge[ (j + 1) + ((i + 1) * 2 * iWidth) ] = true;
     7245        }
     7246      }
     7247    }
     7248  }
     7249  /// Horizontal Edge between Vertical Edges
     7250  for( Int j = 1; j < 2 * iWidth - 3; j += 2)
     7251  {
     7252    for( Int i = 0; i < 2 * iHeight - 1; i += 2)
     7253    {
     7254      if( pbEdge[ j + i * 2 * iWidth ] )
     7255      {
     7256        if( i != 0 && pbEdge[ (j + 2) + ((i - 2) * 2 * iWidth) ] )
     7257        {
     7258          if( !pbEdge[ (j - 1) + ((i - 1) * 2 * iWidth) ] && !pbEdge[ (j + 3) + ((i - 1) * 2 * iWidth) ] )
     7259            pbEdge[ (j + 1) + ((i - 1) * 2 * iWidth) ] = true;
     7260        }
     7261        if( i != 2 * iHeight - 2 && pbEdge[ (j + 2) + ((i + 2) * 2 * iWidth) ] )
     7262        {
     7263          if( !pbEdge[ (j - 1) + ((i + 1) * 2 * iWidth) ] && !pbEdge[ (j + 3) + ((i + 1) * 2 * iWidth) ] )
     7264            pbEdge[ (j + 1) + ((i + 1) * 2 * iWidth) ] = true;
     7265        }
     7266      }
     7267    }
     7268  }
     7269
     7270  // Static Pruning Unnecessary Edges
     7271  /// Step1. Stack push the unconnected edges
     7272  UShort* pusUnconnectedEdgeStack = new UShort[ 4 * iWidth * iHeight ]; // approximate size calculation
     7273  Int iUnconnectedEdgeStackPtr = 0;
     7274  //// Vertical Edges
     7275  for( Int i = 0; i < 2 * iHeight - 1; i += 2 )
     7276  {
     7277    for( Int j = 1; j < 2 * iWidth - 2; j += 2 )
     7278    {
     7279      if( pbEdge[ j + i * 2 * iWidth ] )
     7280      {
     7281        if( !xCheckTerminatedEdge( pbEdge, j, i, iWidth, iHeight ) )
     7282        {
     7283          pusUnconnectedEdgeStack[iUnconnectedEdgeStackPtr] = (i << 8) | (j);
     7284          iUnconnectedEdgeStackPtr++;
     7285        }
     7286      }
     7287    }
     7288  }
     7289
     7290  //// Horizontal Edges
     7291  for( Int i = 1; i < 2 * iHeight - 2; i += 2 )
     7292  {
     7293    for( Int j = 0; j < 2 * iWidth - 1; j += 2 )
     7294    {
     7295      if( pbEdge[ j + i * 2 * iWidth ] )
     7296      {
     7297        if( !xCheckTerminatedEdge( pbEdge, j, i, iWidth, iHeight ) )
     7298        {
     7299          pusUnconnectedEdgeStack[iUnconnectedEdgeStackPtr] = (i << 8) | (j);
     7300          iUnconnectedEdgeStackPtr++;
     7301        }
     7302      }
     7303    }
     7304  }
     7305
     7306  /// Step2. Remove the edges from the stack and push the new unconnected edges
     7307  //// (This step may contain duplicated edges already in the stack)
     7308  //// (But it doesn't cause any functional problems)
     7309  while( iUnconnectedEdgeStackPtr != 0 )
     7310  {
     7311    iUnconnectedEdgeStackPtr--;
     7312    Int iX = pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] & 0xff;
     7313    Int iY = pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] >> 8;
     7314
     7315    pbEdge[ iX + iY * 2 * iWidth ] = false;
     7316
     7317    if( iY % 2 == 1 && iX > 0 && pbEdge[ iX - 2 + iY * 2 * iWidth ] &&
     7318      !xCheckTerminatedEdge( pbEdge, iX - 2, iY, iWidth, iHeight ) ) // left
     7319    {
     7320      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 0) << 8) | (iX - 2);
     7321      iUnconnectedEdgeStackPtr++;
     7322    }
     7323    if( iY % 2 == 1 && iX < 2 * iWidth - 2 && pbEdge[ iX + 2 + iY * 2 * iWidth ] &&
     7324      !xCheckTerminatedEdge( pbEdge, iX + 2, iY, iWidth, iHeight ) ) // right
     7325    {
     7326      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 0) << 8) | (iX + 2);
     7327      iUnconnectedEdgeStackPtr++;
     7328    }
     7329    if( iY % 2 == 0 && iY > 0 && pbEdge[ iX + (iY - 2) * 2 * iWidth ] &&
     7330      !xCheckTerminatedEdge( pbEdge, iX, iY - 2, iWidth, iHeight ) ) // top
     7331    {
     7332      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY - 2) << 8) | (iX + 0);
     7333      iUnconnectedEdgeStackPtr++;
     7334    }
     7335    if( iY % 2 == 0 && iY < 2 * iHeight - 2 && pbEdge[ iX + (iY + 2) * 2 * iWidth ] &&
     7336      !xCheckTerminatedEdge( pbEdge, iX, iY + 2, iWidth, iHeight ) ) // bottom
     7337    {
     7338      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 2) << 8) | (iX + 0);
     7339      iUnconnectedEdgeStackPtr++;
     7340    }
     7341    if( iX > 0 && iY > 0 && pbEdge[ iX - 1 + (iY - 1) * 2 * iWidth ] &&
     7342      !xCheckTerminatedEdge( pbEdge, iX - 1, iY - 1, iWidth, iHeight ) ) // left-top
     7343    {
     7344      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY - 1) << 8) | (iX - 1);
     7345      iUnconnectedEdgeStackPtr++;
     7346    }
     7347    if( iX < 2 * iWidth - 1 && iY > 0 && pbEdge[ iX + 1 + (iY - 1) * 2 * iWidth ] &&
     7348      !xCheckTerminatedEdge( pbEdge, iX + 1, iY - 1, iWidth, iHeight ) ) // right-top
     7349    {
     7350      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY - 1) << 8) | (iX + 1);
     7351      iUnconnectedEdgeStackPtr++;
     7352    }
     7353    if( iX > 0 && iY < 2 * iHeight - 1 && pbEdge[ iX - 1 + (iY + 1) * 2 * iWidth ] &&
     7354      !xCheckTerminatedEdge( pbEdge, iX - 1, iY + 1, iWidth, iHeight ) ) // left-bottom
     7355    {
     7356      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 1) << 8) | (iX - 1);
     7357      iUnconnectedEdgeStackPtr++;
     7358    }
     7359    if( iX < 2 * iWidth - 1 && iY < 2 * iHeight - 1 && pbEdge[ iX + 1 + (iY + 1) * 2 * iWidth ] &&
     7360      !xCheckTerminatedEdge( pbEdge, iX + 1, iY + 1, iWidth, iHeight ) ) // right-bottom
     7361    {
     7362      pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 1) << 8) | (iX + 1);
     7363      iUnconnectedEdgeStackPtr++;
     7364    }
     7365  }
     7366
     7367
     7368  // Region Generation ( edge -> region )
     7369  Bool* pbRegion = pcCU->getEdgePartition( uiAbsPtIdx );
     7370  Bool* pbVisit  = new Bool[ iWidth * iHeight ];
     7371
     7372  for( UInt ui = 0; ui < iWidth * iHeight; ui++ )
     7373  {
     7374    pbRegion[ ui ] = true; // fill it as region 1 (we'll discover region 0 next)
     7375    pbVisit [ ui ] = false;
     7376  }
     7377
     7378  Int* piStack = new Int[ iWidth * iHeight ];
     7379
     7380  Int iPtr = 0;
     7381
     7382  piStack[iPtr++] = (0 << 8) | (0);
     7383  pbRegion[ 0 ] = false;
     7384
     7385  while(iPtr > 0)
     7386  {
     7387    Int iTmp = piStack[--iPtr];
     7388    Int iX1, iY1;
     7389    iX1 = iTmp & 0xff;
     7390    iY1 = (iTmp >> 8) & 0xff;
     7391
     7392    pbVisit[ iX1 + iY1 * iWidth ] = true;
     7393
     7394    assert( iX1 >= 0 && iX1 < iWidth );
     7395    assert( iY1 >= 0 && iY1 < iHeight );
     7396
     7397    if( iX1 > 0 && !pbEdge[ 2 * iX1 - 1 + 4 * iY1 * iWidth ] && !pbVisit[ iX1 - 1 + iY1 * iWidth ] )
     7398    {
     7399      piStack[iPtr++] = (iY1 << 8) | (iX1 - 1);
     7400      pbRegion[ iX1 - 1 + iY1 * iWidth ] = false;
     7401    }
     7402    if( iX1 < iWidth - 1 && !pbEdge[ 2 * iX1 + 1 + 4 * iY1 * iWidth ] && !pbVisit[ iX1 + 1 + iY1 * iWidth ] )
     7403    {
     7404      piStack[iPtr++] = (iY1 << 8) | (iX1 + 1);
     7405      pbRegion[ iX1 + 1 + iY1 * iWidth ] = false;
     7406    }
     7407    if( iY1 > 0 && !pbEdge[ 2 * iX1 + 2 * (2 * iY1 - 1) * iWidth ] && !pbVisit[ iX1 + (iY1 - 1) * iWidth ] )
     7408    {
     7409      piStack[iPtr++] = ((iY1 - 1) << 8) | iX1;
     7410      pbRegion[ iX1 + (iY1 - 1) * iWidth ] = false;
     7411    }
     7412    if( iY1 < iHeight - 1 && !pbEdge[ 2 * iX1 + 2 * (2 * iY1 + 1) * iWidth ] && !pbVisit[ iX1 + (iY1 + 1) * iWidth ] )
     7413    {
     7414      piStack[iPtr++] = ((iY1 + 1) << 8) | iX1;
     7415      pbRegion[ iX1 + (iY1 + 1) * iWidth ] = false;
     7416    }
     7417  }
     7418
     7419  ///////////
     7420  iPtr = 0;
     7421  for( Int i = 0; i < iWidth * iHeight; i++ )
     7422    pbVisit[ i ] = false;
     7423  piStack[ iPtr++ ] = (0 << 8) | (0); // initial seed
     7424  while( iPtr > 0 && iPtr < iWidth * iHeight )
     7425  {
     7426    Int iX;
     7427    Int iY;
     7428    iPtr--;
     7429    iX = piStack[ iPtr ] & 0xff;
     7430    iY = piStack[ iPtr ] >> 8;
     7431    pbVisit[ iY * iWidth + iX ] = true;
     7432
     7433    if( iY > 0 && !pbVisit[ (iY - 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY - 1) * iWidth + iX ] )
     7434    {
     7435      piStack[ iPtr++ ] = ((iY - 1) << 8) | iX;
     7436    }
     7437    if( iY < iHeight - 1 && !pbVisit[ (iY + 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY + 1) * iWidth + iX ] )
     7438    {
     7439      piStack[ iPtr++ ] = ((iY + 1) << 8) | iX;
     7440    }
     7441    if( iX > 0 && !pbVisit[ iY * iWidth + (iX - 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX - 1) ] )
     7442    {
     7443      piStack[ iPtr++ ] = (iY << 8) | (iX - 1);
     7444    }
     7445    if( iX < iWidth - 1 && !pbVisit[ iY * iWidth + (iX + 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX + 1) ] )
     7446    {
     7447      piStack[ iPtr++ ] = (iY << 8) | (iX + 1);
     7448    }
     7449  }
     7450  assert( iPtr == 0 || iPtr == iWidth * iHeight );
     7451
     7452  Bool bBipartition;
     7453  if( iPtr == iWidth * iHeight )
     7454  {
     7455    bBipartition = false; // single partition
     7456  }
     7457  else
     7458  {
     7459    for( Int i = 0; i < iWidth * iHeight; i++ )
     7460    {
     7461      if( !pbVisit[ i ] )
     7462      {
     7463        piStack[ iPtr++ ] = (( i / iWidth ) << 8) | ( i % iWidth );
     7464        pbVisit[ i ] = true;
     7465        break;
     7466      }
     7467    }
     7468    while( iPtr > 0 )
     7469    {
     7470      Int iX;
     7471      Int iY;
     7472      iPtr--;
     7473      iX = piStack[ iPtr ] & 0xff;
     7474      iY = piStack[ iPtr ] >> 8;
     7475      pbVisit[ iY * iWidth + iX ] = true;
     7476
     7477      if( iY > 0 && !pbVisit[ (iY - 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY - 1) * iWidth + iX ] )
     7478      {
     7479        piStack[ iPtr++ ] = ((iY - 1) << 8) | iX;
     7480      }
     7481      if( iY < iHeight - 1 && !pbVisit[ (iY + 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY + 1) * iWidth + iX ] )
     7482      {
     7483        piStack[ iPtr++ ] = ((iY + 1) << 8) | iX;
     7484      }
     7485      if( iX > 0 && !pbVisit[ iY * iWidth + (iX - 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX - 1) ] )
     7486      {
     7487        piStack[ iPtr++ ] = (iY << 8) | (iX - 1);
     7488      }
     7489      if( iX < iWidth - 1 && !pbVisit[ iY * iWidth + (iX + 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX + 1) ] )
     7490      {
     7491        piStack[ iPtr++ ] = (iY << 8) | (iX + 1);
     7492      }
     7493    }
     7494    bBipartition = true;
     7495    for( Int i = 0; i < iWidth * iHeight; i++ )
     7496    {
     7497      if( !pbVisit[ i ] )
     7498      {
     7499        bBipartition = false;
     7500        break;
     7501      }
     7502    }
     7503  }
     7504
     7505  xFree( pbEdge );
     7506  delete[] pbEdgeX; pbEdgeX = NULL;
     7507  delete[] pbEdgeY; pbEdgeY = NULL;
     7508  delete[] psDiffX; psDiffX = NULL;
     7509  delete[] psDiffY; psDiffY = NULL;
     7510  delete[] pusUnconnectedEdgeStack; pusUnconnectedEdgeStack = NULL;
     7511  delete[] pbVisit; pbVisit = NULL;
     7512  delete[] piStack; piStack = NULL;
     7513
     7514  if( bBipartition )
     7515  {
     7516    return xConstructChainCode( pcCU, uiAbsPtIdx, (UInt)iWidth, (UInt)iHeight );
     7517  }
     7518  else
     7519  {
     7520    return false;
     7521  }
     7522}
     7523
     7524Bool TEncSearch::xCheckTerminatedEdge( Bool* pbEdge, Int iX, Int iY, Int iWidth, Int iHeight )
     7525{
     7526  if( (iY % 2) == 0 ) // vertical edge
     7527  {
     7528    Bool bTopConnected = false;
     7529    Bool bBottomConnected = false;
     7530
     7531    if( iY != 0 )
     7532    {
     7533      if( pbEdge[ iX + (iY - 2) * 2 * iWidth ] )
     7534        bTopConnected = true;
     7535      if( pbEdge[ (iX - 1) + (iY - 1) * 2 * iWidth ] )
     7536        bTopConnected = true;
     7537      if( pbEdge[ (iX + 1) + (iY - 1) * 2 * iWidth ] )
     7538        bTopConnected = true;
     7539    }
     7540    else
     7541    {
     7542      bTopConnected = true;
     7543    }
     7544
     7545
     7546    if( iY != 2 * iHeight - 2 )
     7547    {
     7548      if( pbEdge[ iX + (iY + 2) * 2 * iWidth ] )
     7549        bBottomConnected = true;
     7550      if( pbEdge[ (iX - 1) + (iY + 1) * 2 * iWidth ] )
     7551        bBottomConnected = true;
     7552      if( pbEdge[ (iX + 1) + (iY + 1) * 2 * iWidth ] )
     7553        bBottomConnected = true;
     7554    }
     7555    else
     7556    {
     7557      bBottomConnected = true;
     7558    }
     7559
     7560
     7561    if( bTopConnected && bBottomConnected )
     7562    {
     7563      return true;
     7564    }
     7565    else
     7566    {
     7567      return false;
     7568    }
     7569  }
     7570  else
     7571  {
     7572    Bool bLeftConnected = false;
     7573    Bool bRightConnected = false;
     7574
     7575    if( iX != 0 )
     7576    {
     7577      if( pbEdge[ (iX - 2) + iY * 2 * iWidth ] )
     7578        bLeftConnected = true;
     7579      if( pbEdge[ (iX - 1) + (iY - 1) * 2 * iWidth ] )
     7580        bLeftConnected = true;
     7581      if( pbEdge[ (iX - 1) + (iY + 1) * 2 * iWidth ] )
     7582        bLeftConnected = true;
     7583    }
     7584    else
     7585    {
     7586      bLeftConnected = true;
     7587    }
     7588
     7589    if( iX != 2 * iWidth - 2 )
     7590    {
     7591      if( pbEdge[ (iX + 2) + iY * 2 * iWidth ] )
     7592        bRightConnected = true;
     7593      if( pbEdge[ (iX + 1) + (iY - 1) * 2 * iWidth ] )
     7594        bRightConnected = true;
     7595      if( pbEdge[ (iX + 1) + (iY + 1) * 2 * iWidth ] )
     7596        bRightConnected = true;
     7597    }
     7598    else
     7599    {
     7600      bRightConnected = true;
     7601    }
     7602
     7603
     7604    if( bLeftConnected && bRightConnected )
     7605    {
     7606      return true;
     7607    }
     7608    else
     7609    {
     7610      return false;
     7611    }
     7612  }
     7613}
     7614Bool TEncSearch::xConstructChainCode( TComDataCU* pcCU, UInt uiAbsPtIdx, UInt uiWidth, UInt uiHeight )
     7615{
     7616  //UInt   uiWidth    = pcCU->getWidth( uiPartIdx ) >> (bPU4x4 ? 1 : 0);
     7617  //UInt   uiHeight   = pcCU->getHeight( uiPartIdx ) >> (bPU4x4 ? 1 : 0);
     7618  Bool*  pbEdge     = (Bool*) xMalloc( Bool, uiWidth * uiHeight * 4 );
     7619  Bool*  pbVisit    = (Bool*) xMalloc( Bool, uiWidth * uiHeight * 4 );
     7620  UInt   uiMaxEdge  = uiWidth * (RBC_MAX_EDGE_NUM_PER_4x4 / 4);
     7621  Bool*  pbRegion   = pcCU->getEdgePartition( uiAbsPtIdx );
     7622  UChar* piEdgeCode = pcCU->getEdgeCode( uiAbsPtIdx );
     7623  Bool   bStartLeft = false;
     7624  Bool   bPossible  = false;
     7625  Bool   bFinish    = false;
     7626  Int    iStartPosition = -1;
     7627  Int    iPtr = 0;
     7628  Int    iDir = -1, iNextDir = -1;
     7629  Int    iArrow = -1, iNextArrow = -1;
     7630  Int    iX = -1, iY = -1;
     7631  Int    iDiffX = 0, iDiffY = 0;
     7632  UChar  iCode = 255;
     7633  UInt   uiWidth2 = uiWidth * 2;
     7634
     7635  for( Int i = 0; i < uiWidth * uiHeight * 4; i++ )
     7636    pbEdge[ i ] = false;
     7637
     7638  for( Int i = 0; i < uiHeight; i++ )
     7639  {
     7640    for( Int j = 0; j < uiWidth - 1; j++ )
     7641    {
     7642      if( pbRegion[ i * uiWidth + j ] != pbRegion[ i * uiWidth + j + 1 ] )
     7643        pbEdge[ i * uiWidth * 4 + j * 2 + 1 ] = true;
     7644    }
     7645  }
     7646
     7647  for( Int i = 0; i < uiHeight - 1; i++ )
     7648  {
     7649    for( Int j = 0; j < uiWidth; j++ )
     7650    {
     7651      if( pbRegion[ (i + 0) * uiWidth + j ] != pbRegion[ (i + 1) * uiWidth + j ] )
     7652        pbEdge[ (2 * i + 1) * 2 * uiWidth + j * 2 ] = true;
     7653    }
     7654  }
     7655
     7656  for( Int i = 1; i < uiWidth2 - 2; i+=2 )
     7657  {
     7658    if(pbEdge[ i ])
     7659    {
     7660      bPossible  = true;
     7661      bStartLeft = false;
     7662      iStartPosition = iX = i;
     7663      iY = 0;
     7664      iDir = 3;
     7665      iArrow = 3;
     7666      break;
     7667    }
     7668  }
     7669
     7670  if( !bPossible )
     7671  {
     7672    for( Int i = 1; i < uiWidth2 - 2; i+=2 )
     7673    {
     7674      if(pbEdge[ i * uiWidth2 ])
     7675      {
     7676        bPossible  = true;
     7677        bStartLeft = true;
     7678        iX = 0;
     7679        iStartPosition = iY = i;
     7680        iDir = 1;
     7681        iArrow = 1;
     7682        break;
     7683      }
     7684    }
     7685  }
     7686
     7687  if( bPossible )
     7688  {
     7689    for( Int i = 0; i < 4 * uiWidth * uiHeight; i++ )
     7690      pbVisit[ i ] = false;
     7691
     7692    while( !bFinish )
     7693    {
     7694      Bool bArrowSkip = false;
     7695      pbVisit[ iX + iY * uiWidth2 ] = true;
     7696
     7697      switch( iDir )
     7698      {
     7699      case 0: // left
     7700        if( iX > 0 && !pbVisit[ (iX - 2) + iY * uiWidth2 ] && pbEdge[ (iX - 2) + iY * uiWidth2 ] ) // left
     7701        {
     7702          iDiffX = -2;
     7703          iDiffY =  0;
     7704          iNextDir = 0;
     7705          iNextArrow = 0;
     7706        }
     7707        else if( iX > 0 && !pbVisit[ (iX - 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY - 1) * uiWidth2 ] ) // top
     7708        {
     7709          iDiffX = -1;
     7710          iDiffY = -1;
     7711          iNextDir = 2;
     7712          iNextArrow = 4;
     7713        }
     7714        else if( iX > 0 && !pbVisit[ (iX - 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY + 1) * uiWidth2 ] ) // bottom
     7715        {
     7716          iDiffX = -1;
     7717          iDiffY = +1;
     7718          iNextDir = 3;
     7719          iNextArrow = iArrow;
     7720          if( !(iPtr == 0 && iX == uiWidth2 - 2 && iY == uiHeight * 2 - 3) )
     7721            bArrowSkip = true;
     7722          else
     7723            iNextArrow = 3;
     7724        }
     7725        else if( iX == 0 )
     7726        {
     7727          iDiffX = 0;
     7728          iDiffY = 0;
     7729          iNextDir = iDir;
     7730          iNextArrow = iArrow;
     7731          bFinish = true;
     7732          continue;
     7733        }
     7734        else
     7735        {
     7736          iPtr = 0; // edge loop or unwanted case
     7737          bFinish = true;
     7738          //continue;
     7739          assert(false);
     7740        }
     7741        break;
     7742      case 1: // right
     7743        if( iX < uiWidth2 - 2 && !pbVisit[ (iX + 2) + iY * uiWidth2 ] && pbEdge[ (iX + 2) + iY * uiWidth2 ] ) // right
     7744        {
     7745          iDiffX = +2;
     7746          iDiffY =  0;
     7747          iNextDir = 1;
     7748          iNextArrow = 1;
     7749        }
     7750        else if( iX < uiWidth2 - 2 && !pbVisit[ (iX + 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY - 1) * uiWidth2 ] ) // top
     7751        {
     7752          iDiffX = +1;
     7753          iDiffY = -1;
     7754          iNextDir = 2;
     7755          iNextArrow = iArrow;
     7756          if( !(iPtr == 0 && iX == 0 && iY == 1) )
     7757            bArrowSkip = true;
     7758          else
     7759            iNextArrow = 2;
     7760        }
     7761        else if( iX < uiWidth2 - 2 && !pbVisit[ (iX + 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY + 1) * uiWidth2 ] ) // bottom
     7762        {
     7763          iDiffX = +1;
     7764          iDiffY = +1;
     7765          iNextDir = 3;
     7766          iNextArrow = 7;
     7767        }
     7768        else if( iX == uiWidth2 - 2 )
     7769        {
     7770          iDiffX = 0;
     7771          iDiffY = 0;
     7772          iNextDir = iDir;
     7773          iNextArrow = iArrow;
     7774          bFinish = true;
     7775          continue;
     7776        }
     7777        else
     7778        {
     7779          iPtr = 0; // edge loop or unwanted case
     7780          bFinish = true;
     7781          //continue;
     7782          assert(false);
     7783        }
     7784        break;
     7785      case 2: // top
     7786        if( iY > 0 && !pbVisit[ (iX - 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY - 1) * uiWidth2 ] ) // left
     7787        {
     7788          iDiffX = -1;
     7789          iDiffY = -1;
     7790          iNextDir = 0;
     7791          iNextArrow = iArrow;
     7792          if( !(iPtr == 0 && iX == 1 && iY == uiHeight * 2 - 2) )
     7793            bArrowSkip = true;
     7794          else
     7795            iNextArrow = 0;
     7796        }
     7797        else if( iY > 0 && !pbVisit[ (iX + 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY - 1) * uiWidth2 ] ) // right
     7798        {
     7799          iDiffX = +1;
     7800          iDiffY = -1;
     7801          iNextDir = 1;
     7802          iNextArrow = 5;
     7803        }
     7804        else if( iY > 0 && !pbVisit[ iX + (iY - 2) * uiWidth2 ] && pbEdge[ iX + (iY - 2) * uiWidth2 ] ) // top
     7805        {
     7806          iDiffX =  0;
     7807          iDiffY = -2;
     7808          iNextDir = 2;
     7809          iNextArrow = 2;
     7810        }
     7811        else if( iY == 0 )
     7812        {
     7813          iDiffX = 0;
     7814          iDiffY = 0;
     7815          iNextDir = iDir;
     7816          iNextArrow = iArrow;
     7817          bFinish = true;
     7818          continue;
     7819        }
     7820        else
     7821        {
     7822          iPtr = 0; // edge loop or unwanted case
     7823          bFinish = true;
     7824          //continue;
     7825          assert(false);
     7826        }
     7827        break;
     7828      case 3: // bottom
     7829        if( iY < uiWidth2 - 2 && !pbVisit[ (iX - 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY + 1) * uiWidth2 ] ) // left
     7830        {
     7831          iDiffX = -1;
     7832          iDiffY = +1;
     7833          iNextDir = 0;
     7834          iNextArrow = 6;
     7835        }
     7836        else if( iY < uiWidth2 - 2 && !pbVisit[ (iX + 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY + 1) * uiWidth2 ] ) // right
     7837        {
     7838          iDiffX = +1;
     7839          iDiffY = +1;
     7840          iNextDir = 1;
     7841          iNextArrow = iArrow;
     7842          if( !(iPtr == 0 && iX == uiWidth * 2 - 3 && iY == 0) )
     7843            bArrowSkip = true;
     7844          else
     7845            iNextArrow = 1;
     7846        }
     7847        else if( iY < uiWidth2 - 2 && !pbVisit[ iX + (iY + 2) * uiWidth2 ] && pbEdge[ iX + (iY + 2) * uiWidth2 ] ) // bottom
     7848        {
     7849          iDiffX =  0;
     7850          iDiffY = +2;
     7851          iNextDir = 3;
     7852          iNextArrow = 3;
     7853        }
     7854        else if( iY == uiWidth2 - 2 )
     7855        {
     7856          iDiffX = 0;
     7857          iDiffY = 0;
     7858          iNextDir = iDir;
     7859          iNextArrow = iArrow;
     7860          bFinish = true;
     7861          continue;
     7862        }
     7863        else
     7864        {
     7865          iPtr = 0; // edge loop or unwanted case
     7866          bFinish = true;
     7867          //continue;
     7868          assert(false);
     7869        }
     7870        break;
     7871      }
     7872
     7873      const UChar tableCode[8][8] = { { 0, -1, 4, 3, 2, 6, 1, 5 }, // iArrow(current direction), iNextArrow(next direction)
     7874      { -1, 0, 3, 4, 5, 1, 6, 2 },
     7875      { 3, 4, 0, -1, 1, 2, 5, 6 },
     7876      { 4, 3, -1, 0, 6, 5, 2, 1 },
     7877      { 1, 6, 2, 5, 0, 4, 3, -1 },
     7878      { 5, 2, 1, 6, 3, 0, -1, 4 },
     7879      { 2, 5, 6, 1, 4, -1, 0, 3 },
     7880      { 6, 1, 5, 2, -1, 3, 4, 0 } };
     7881
     7882      iCode = tableCode[iArrow][iNextArrow];
     7883
     7884      if(iPtr >= uiMaxEdge)
     7885      {
     7886        iPtr = 0; // over the maximum number of edge
     7887        bPossible = false;
     7888        break;
     7889      }
     7890
     7891      if( !bArrowSkip )
     7892      {
     7893        piEdgeCode[iPtr++] = iCode; // first edge coding
     7894        //printf("xEdgeCoding: (%d,%d)->(%d,%d) code %d\n",iX,iY, iX+iDiffX, iY+iDiffY, iCode);
     7895      }
     7896
     7897      iX += iDiffX;
     7898      iY += iDiffY;
     7899      iDir = iNextDir;
     7900      iArrow = iNextArrow;
     7901    }
     7902  }
     7903
     7904  pcCU->setEdgeLeftFirst( uiAbsPtIdx, bStartLeft );
     7905  pcCU->setEdgeStartPos ( uiAbsPtIdx, bStartLeft ? (iStartPosition - 1) >> 1 : (iStartPosition + 1) >> 1);
     7906  pcCU->setEdgeNumber   ( uiAbsPtIdx, iPtr );
     7907
     7908  xFree( pbEdge );
     7909  xFree( pbVisit );
     7910
     7911  return (iPtr != 0);
     7912}
     7913#endif
     7914#endif
    64097915//! \}
Note: See TracChangeset for help on using the changeset viewer.