Changeset 459 in 3DVCSoftware for branches/HTM-DEV-0.3-dev1/source/Lib/TLibEncoder/TEncSearch.cpp
- Timestamp:
- 6 Jun 2013, 11:46:05 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HTM-DEV-0.3-dev1/source/Lib/TLibEncoder/TEncSearch.cpp
r446 r459 1047 1047 pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail ); 1048 1048 //===== 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 1049 1057 predIntraLumaAng( pcCU->getPattern(), uiLumaPredMode, piPred, uiStride, uiWidth, uiHeight, bAboveAvail, bLeftAvail ); 1058 #if H_3D_DIM 1059 } 1060 #endif 1061 1050 1062 // save prediction 1051 1063 if(default0Save1Load2 == 1) … … 1224 1236 { 1225 1237 uiChromaPredMode = pcCU->getLumaIntraDir( 0 ); 1238 #if H_3D_DIM 1239 mapDepthModeToIntraDir( uiChromaPredMode ); 1240 #endif 1226 1241 } 1227 1242 … … 1431 1446 #endif 1432 1447 #endif 1448 #if H_3D_DIM 1449 if( isDimMode( pcCU->getLumaIntraDir( uiAbsPartIdx ) ) ) 1450 { 1451 bCheckSplit = false; 1452 } 1453 #endif 1454 1433 1455 Double dSingleCost = MAX_DOUBLE; 1434 1456 #if H_3D_VSO … … 2624 2646 } 2625 2647 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 2626 2730 //===== check modes (using r-d costs) ===== 2627 2731 #if HHI_RQT_INTRA_SPEEDUP_MOD … … 6091 6195 // Reload only contexts required for coding intra mode information 6092 6196 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 6093 6200 } 6094 6201 … … 6407 6514 } 6408 6515 6516 // ------------------------------------------------------------------------------------------------------------------- 6517 // Depth intra search 6518 // ------------------------------------------------------------------------------------------------------------------- 6519 #if H_3D_DIM 6520 Void 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 6572 Void 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 6697 Void 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 6792 Void 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 6858 Void 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 6927 Void 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 7009 Bool 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 7524 Bool 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 } 7614 Bool 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 6409 7915 //! \}
Note: See TracChangeset for help on using the changeset viewer.