Ignore:
Timestamp:
6 Aug 2012, 05:35:11 (12 years ago)
Author:
lg
Message:

Implemented the Region boundary chain coding (A0070) and R/D selection between Non-Zero Residual and All-Zero Residual Intra Coding (A0087) with macro: "LGE_EDGE_INTRA" and "LG_ZEROINTRADEPTHRESI_M26039"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HTM-3.1-LG/source/Lib/TLibEncoder/TEncSearch.cpp

    r81 r97  
    952952Void
    953953TEncSearch::xIntraCodingLumaBlk( TComDataCU* pcCU,
    954                                 UInt        uiTrDepth,
    955                                 UInt        uiAbsPartIdx,
    956                                 TComYuv*    pcOrgYuv,
    957                                 TComYuv*    pcPredYuv,
    958                                 TComYuv*    pcResiYuv,
    959                                 Dist&       ruiDist )
     954                                                                UInt        uiTrDepth,
     955                                                                UInt        uiAbsPartIdx,
     956                                                                TComYuv*    pcOrgYuv,
     957                                                                TComYuv*    pcPredYuv,
     958                                                                TComYuv*    pcResiYuv,
     959                                                                Dist&       ruiDist
     960#if LG_ZEROINTRADEPTHRESI_M26039
     961                                                                ,Bool        bZeroResi
     962#endif
     963                                                                )
    960964{
    961965  UInt    uiLumaPredMode    = pcCU     ->getLumaIntraDir     ( uiAbsPartIdx );
     
    988992  pcCU->getPattern()->initPattern   ( pcCU, uiTrDepth, uiAbsPartIdx );
    989993  pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, m_piYuvExt, m_iYuvExtStride, m_iYuvExtHeight, bAboveAvail, bLeftAvail );
     994
     995#if LGE_EDGE_INTRA
     996  if( uiLumaPredMode >= EDGE_INTRA_IDX )
     997  {
     998#if LGE_EDGE_INTRA_DELTA_DC
     999          if( uiLumaPredMode == EDGE_INTRA_DELTA_IDX )
     1000                  xAssignEdgeIntraDeltaDCs( pcCU, uiAbsPartIdx, piOrg, uiStride, piPred, uiWidth, uiHeight );
     1001#endif
     1002
     1003          predIntraLumaEdge( pcCU, pcCU->getPattern(), uiAbsPartIdx, uiWidth, uiHeight, piPred, uiStride
     1004#if LGE_EDGE_INTRA_DELTA_DC
     1005                  , uiLumaPredMode == EDGE_INTRA_DELTA_IDX
     1006#endif
     1007                  );
     1008  }
     1009  else
     1010#endif
    9901011 
    9911012  //===== get prediction signal =====
     
    10201041    }
    10211042  }
     1043#if LG_ZEROINTRADEPTHRESI_M26039
     1044  if(bZeroResi)
     1045  {
     1046          Pel* pResi = piResi;
     1047
     1048          for( UInt uiY = 0; uiY < uiHeight; uiY++ )
     1049          {
     1050                  memset( pResi, 0, sizeof( Pel ) * uiWidth );
     1051                  pResi += uiStride;
     1052          }
     1053  }
     1054#endif
    10221055 
    10231056  //===== transform and quantization =====
     
    13001333Void
    13011334TEncSearch::xRecurIntraCodingQT( TComDataCU*  pcCU,
    1302                                 UInt         uiTrDepth,
    1303                                 UInt         uiAbsPartIdx,
    1304                                 Bool         bLumaOnly,
    1305                                 TComYuv*     pcOrgYuv,
    1306                                 TComYuv*     pcPredYuv,
    1307                                 TComYuv*     pcResiYuv,
    1308                                 Dist&        ruiDistY,
    1309                                 Dist&        ruiDistC,
     1335                                                                UInt         uiTrDepth,
     1336                                                                UInt         uiAbsPartIdx,
     1337                                                                Bool         bLumaOnly,
     1338                                                                TComYuv*     pcOrgYuv,
     1339                                                                TComYuv*     pcPredYuv,
     1340                                                                TComYuv*     pcResiYuv,
     1341                                                                Dist&        ruiDistY,
     1342                                                                Dist&        ruiDistC,
    13101343#if HHI_RQT_INTRA_SPEEDUP
    1311                                 Bool         bCheckFirst,
    1312 #endif
    1313                                 Double&      dRDCost )
     1344                                                                Bool         bCheckFirst,
     1345#endif
     1346                                                                Double&      dRDCost
     1347#if LG_ZEROINTRADEPTHRESI_M26039
     1348                                                                ,Bool         bZeroResi
     1349#endif
     1350                                                                )
    13141351{
    13151352  UInt    uiFullDepth   = pcCU->getDepth( 0 ) +  uiTrDepth;
     
    13281365  {
    13291366    bCheckSplit = false;
     1367  }
     1368#endif
     1369#if LGE_EDGE_INTRA
     1370  if( pcCU->getLumaIntraDir( uiAbsPartIdx ) >= EDGE_INTRA_IDX )
     1371  {
     1372          bCheckSplit = false;
    13301373  }
    13311374#endif
     
    13461389    //----- code luma block with given intra prediction mode and store Cbf-----
    13471390    dSingleCost   = 0.0;
    1348     xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistY );
     1391#if LG_ZEROINTRADEPTHRESI_M26039
     1392        xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistY, bZeroResi );
     1393#else
     1394        xIntraCodingLumaBlk( pcCU, uiTrDepth, uiAbsPartIdx, pcOrgYuv, pcPredYuv, pcResiYuv, uiSingleDistY );
     1395#endif
    13491396    if( bCheckSplit )
    13501397    {
     
    18071854    UInt uiRdModeList[FAST_UDI_MAX_RDMODE_NUM];
    18081855    Int numModesForFullRD = g_aucIntraModeNumFast[ uiWidthBit ];
     1856
     1857#if LGE_EDGE_INTRA
     1858        Bool bTestEdgeIntra = false;
     1859        if ( m_pcEncCfg->isDepthCoder() && uiWidth >= LGE_EDGE_INTRA_MIN_SIZE && uiWidth <= LGE_EDGE_INTRA_MAX_SIZE && uiWidth == uiHeight )
     1860        {
     1861                bTestEdgeIntra = true;
     1862
     1863                Bool bEdgeExist;
     1864
     1865                bEdgeExist = xEdgePartition( pcCU, uiPartOffset, pcCU->getPartitionSize(0) == SIZE_NxN );
     1866
     1867                if( !bEdgeExist )
     1868                        bTestEdgeIntra = false;
     1869        }
     1870#endif
    18091871   
    18101872#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
     
    18661928#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
    18671929        if( bTestDmm ) bTestDmm = uiSad ? true : false;
     1930#endif
     1931#if LGE_EDGE_INTRA
     1932                if ( bTestEdgeIntra ) bTestEdgeIntra = uiSad ? true : false;
    18681933#endif
    18691934      }
     
    19742039    }
    19752040#endif
     2041#if LGE_EDGE_INTRA
     2042        if( bTestEdgeIntra )
     2043        {
     2044                uiRdModeList[ numModesForFullRD++ ] = EDGE_INTRA_IDX;
     2045#if LGE_EDGE_INTRA_DELTA_DC
     2046                uiRdModeList[ numModesForFullRD++ ] = EDGE_INTRA_DELTA_IDX;
     2047#endif
     2048        }
     2049#endif
    19762050
    19772051    //===== check modes (using r-d costs) =====
     
    19872061    for( UInt uiMode = 0; uiMode < numModesForFullRD; uiMode++ )
    19882062    {
     2063#if LG_ZEROINTRADEPTHRESI_M26039
     2064                Bool bAllowZeroResi = pcCU->getSlice()->getIsDepth() && (pcCU->getSlice()->getPOC()%pcCU->getPic()->getIntraPeriod());// && (uiMode < NUM_INTRA_MODE);
     2065                for(UInt uiCnt = 0; uiCnt < (bAllowZeroResi ? 2 : 1); uiCnt++)
     2066                {
     2067                        Bool bZeroResi = uiCnt ? true : false;
     2068#endif
    19892069      // set luma prediction mode
    19902070      UInt uiOrgMode = uiRdModeList[uiMode];
    19912071     
    19922072#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
    1993       if( m_pcEncCfg->getIsDepth() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight ) )
    1994       {
    1995         continue;
    1996       }
     2073          if( m_pcEncCfg->getIsDepth() && !predIntraLumaDMMAvailable( uiOrgMode, uiWidth, uiHeight )
     2074#if LGE_EDGE_INTRA
     2075                  && uiOrgMode < EDGE_INTRA_IDX
     2076#endif
     2077                  )
     2078          {
     2079                  continue;
     2080          }
    19972081#endif
    19982082
     
    20202104
    20212105#if HHI_RQT_INTRA_SPEEDUP
    2022       xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );
    2023 #else
    2024       xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
     2106#if LG_ZEROINTRADEPTHRESI_M26039
     2107          xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost, bZeroResi );
     2108#else
     2109          xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, true, dPUCost );
     2110#endif
     2111#else
     2112          xRecurIntraCodingQT( pcCU, uiInitTrDepth, uiPartOffset, bLumaOnly, pcOrgYuv, pcPredYuv, pcResiYuv, uiPUDistY, uiPUDistC, dPUCost );
    20252113#endif
    20262114     
     
    20532141      }
    20542142#endif
    2055     } // Mode loop
     2143#if LG_ZEROINTRADEPTHRESI_M26039
     2144                }
     2145#endif
     2146        } // Mode loop
    20562147   
    20572148#if HHI_RQT_INTRA_SPEEDUP
     
    62076298}
    62086299#endif
     6300
     6301#if LGE_EDGE_INTRA
     6302Bool TEncSearch::xCheckTerminatedEdge( Bool* pbEdge, Int iX, Int iY, Int iWidth, Int iHeight )
     6303{
     6304        if( (iY % 2) == 0 ) // vertical edge
     6305        {
     6306                Bool bTopConnected = false;
     6307                Bool bBottomConnected = false;
     6308
     6309                if( iY != 0 )
     6310                {
     6311                        if( pbEdge[ iX + (iY - 2) * 2 * iWidth ] )
     6312                                bTopConnected = true;
     6313                        if( pbEdge[ (iX - 1) + (iY - 1) * 2 * iWidth ] )
     6314                                bTopConnected = true;
     6315                        if( pbEdge[ (iX + 1) + (iY - 1) * 2 * iWidth ] )
     6316                                bTopConnected = true;
     6317                }
     6318                else
     6319                {
     6320                        bTopConnected = true;
     6321                }
     6322
     6323
     6324                if( iY != 2 * iHeight - 2 )
     6325                {
     6326                        if( pbEdge[ iX + (iY + 2) * 2 * iWidth ] )
     6327                                bBottomConnected = true;
     6328                        if( pbEdge[ (iX - 1) + (iY + 1) * 2 * iWidth ] )
     6329                                bBottomConnected = true;
     6330                        if( pbEdge[ (iX + 1) + (iY + 1) * 2 * iWidth ] )
     6331                                bBottomConnected = true;
     6332                }
     6333                else
     6334                {
     6335                        bBottomConnected = true;
     6336                }
     6337
     6338
     6339                if( bTopConnected && bBottomConnected )
     6340                {
     6341                        return true;
     6342                }
     6343                else
     6344                {
     6345                        return false;
     6346                }
     6347        }
     6348        else
     6349        {
     6350                Bool bLeftConnected = false;
     6351                Bool bRightConnected = false;
     6352
     6353                if( iX != 0 )
     6354                {
     6355                        if( pbEdge[ (iX - 2) + iY * 2 * iWidth ] )
     6356                                bLeftConnected = true;
     6357                        if( pbEdge[ (iX - 1) + (iY - 1) * 2 * iWidth ] )
     6358                                bLeftConnected = true;
     6359                        if( pbEdge[ (iX - 1) + (iY + 1) * 2 * iWidth ] )
     6360                                bLeftConnected = true;
     6361                }
     6362                else
     6363                {
     6364                        bLeftConnected = true;
     6365                }
     6366
     6367                if( iX != 2 * iWidth - 2 )
     6368                {
     6369                        if( pbEdge[ (iX + 2) + iY * 2 * iWidth ] )
     6370                                bRightConnected = true;
     6371                        if( pbEdge[ (iX + 1) + (iY - 1) * 2 * iWidth ] )
     6372                                bRightConnected = true;
     6373                        if( pbEdge[ (iX + 1) + (iY + 1) * 2 * iWidth ] )
     6374                                bRightConnected = true;
     6375                }
     6376                else
     6377                {
     6378                        bRightConnected = true;
     6379                }
     6380
     6381
     6382                if( bLeftConnected && bRightConnected )
     6383                {
     6384                        return true;
     6385                }
     6386                else
     6387                {
     6388                        return false;
     6389                }
     6390        }
     6391}
     6392
     6393#if LGE_EDGE_INTRA_PIXEL_DIFFERENCE
     6394Bool TEncSearch::xEdgePartition( TComDataCU* pcCU, UInt uiPartIdx, Bool bPU4x4 )
     6395{
     6396        Pel* pcOrgY   = pcCU->getPic()->getPicYuvOrg()->getLumaAddr(pcCU->getAddr());
     6397        UInt uiStride = pcCU->getPic()->getPicYuvOrg()->getStride();
     6398        Int iWidth    = pcCU->getWidth(uiPartIdx) >> (bPU4x4 ? 1 : 0);
     6399        Int iHeight   = pcCU->getHeight(uiPartIdx) >> (bPU4x4 ? 1 : 0);
     6400        Bool* pbEdge  = (Bool*) xMalloc( Bool, iWidth * iHeight * 4 );
     6401
     6402        {
     6403                UInt uiOffsetX = 0;
     6404                UInt uiOffsetY = 0;
     6405                UInt uiAbsPartIdx = pcCU->getZorderIdxInCU() + uiPartIdx;
     6406
     6407                uiOffsetX =  (uiAbsPartIdx & 0x1) |
     6408                        ((uiAbsPartIdx & 0x4)  >> 1) |
     6409                        ((uiAbsPartIdx & 0x10) >> 2) |
     6410                        ((uiAbsPartIdx & 0x40) >> 3);
     6411                uiOffsetY = ((uiAbsPartIdx & 0x2)  >> 1) |
     6412                        ((uiAbsPartIdx & 0x8)  >> 2) |
     6413                        ((uiAbsPartIdx & 0x20) >> 3) |
     6414                        ((uiAbsPartIdx & 0x80) >> 4);
     6415                uiOffsetX *= 4;
     6416                uiOffsetY *= 4;
     6417                pcOrgY += (uiOffsetX + uiOffsetY * uiStride);
     6418                //printf("OffsetX %2d OffsetY %2d\n",uiOffsetX, uiOffsetY);
     6419        }
     6420
     6421        Short* psDiffX = new Short[ iWidth * iHeight ];
     6422        Short* psDiffY = new Short[ iWidth * iHeight ];
     6423        Bool*  pbEdgeX = new Bool [ iWidth * iHeight ];
     6424        Bool*  pbEdgeY = new Bool [ iWidth * iHeight ];
     6425
     6426        // Find Horizontal Gradient & Edge Detection ((x+1, y) - (x,y))
     6427        for( Int y=0; y<iHeight; y++ )
     6428        {
     6429                Short* psDiffXPtr = &psDiffX[ y * iHeight ];
     6430                Bool*  pbEdgeXPtr = &pbEdgeX[ y * iHeight ];
     6431                for(Int x=0; x<iWidth-1; x++ )
     6432                {
     6433                        *psDiffXPtr = pcOrgY[ x+1 + y*uiStride ] - pcOrgY[ x + y*uiStride ];
     6434                        if(*psDiffXPtr >= LGE_EDGE_INTRA_THRESHOLD || *psDiffXPtr <= (-1)*LGE_EDGE_INTRA_THRESHOLD)
     6435                        {
     6436                                *pbEdgeXPtr = true;
     6437                        }
     6438                        else
     6439                        {
     6440                                *pbEdgeXPtr = false;
     6441                        }
     6442
     6443                        psDiffXPtr++;
     6444                        pbEdgeXPtr++;
     6445                }
     6446        }
     6447
     6448        // Find Vertical Gradient & Edge Detection((x,y+1) - (x,y))
     6449        for( Int y=0; y<iHeight-1; y++ )
     6450        {
     6451                Short* psDiffYPtr = &psDiffY[ y * iHeight ];
     6452                Bool*  pbEdgeYPtr = &pbEdgeY[ y * iHeight ];
     6453                for(Int x=0; x<iWidth; x++ )
     6454                {
     6455                        *psDiffYPtr = pcOrgY[ x + (y+1)*uiStride ] - pcOrgY [ x + y*uiStride ];
     6456                        if(*psDiffYPtr >= LGE_EDGE_INTRA_THRESHOLD || *psDiffYPtr <= (-1)*LGE_EDGE_INTRA_THRESHOLD)
     6457                        {
     6458                                *pbEdgeYPtr = true;
     6459                        }
     6460                        else
     6461                        {
     6462                                *pbEdgeYPtr = false;
     6463                        }
     6464
     6465                        psDiffYPtr++;
     6466                        pbEdgeYPtr++;
     6467                }
     6468        }
     6469
     6470        // Eliminate local maximum
     6471        for( Int y=0; y<iHeight; y++ )
     6472        {
     6473                Short* psDiffXPtr = &psDiffX[ y * iHeight ];
     6474                Bool*  pbEdgeXPtr = &pbEdgeX[ y * iHeight ];
     6475                for( Int x=0; x<iWidth-1; x++ )
     6476                {
     6477                        UShort usAbs0=0, usAbs1=0, usAbs2=0;  // 0 : left, 1 : current, 2 : right
     6478                        Bool   bSign0=false, bSign1=false, bSign2=false;
     6479                        if( x > 0 && *(pbEdgeXPtr-1) == true )
     6480                        {
     6481                                if( *(psDiffXPtr-1) >= 0)
     6482                                {
     6483                                        usAbs0 = *(psDiffXPtr-1);
     6484                                        bSign0 = true;
     6485                                }
     6486                                else
     6487                                {
     6488                                        usAbs0 = (-1) * *(psDiffXPtr-1);
     6489                                        bSign0 = false;
     6490                                }
     6491                        }
     6492                        if( *pbEdgeXPtr == true )
     6493                        {
     6494                                if( *(psDiffXPtr) >= 0)
     6495                                {
     6496                                        usAbs1 = *(psDiffXPtr);
     6497                                        bSign1 = true;
     6498                                }
     6499                                else
     6500                                {
     6501                                        usAbs1 = (-1) * *(psDiffXPtr);
     6502                                        bSign1 = false;
     6503                                }
     6504                        }
     6505                        if( x < iWidth-2 && *(pbEdgeXPtr+1) == true )
     6506                        {
     6507                                if( *(psDiffXPtr+1) >= 0)
     6508                                {
     6509                                        usAbs2 = *(psDiffXPtr+1);
     6510                                        bSign2 = true;
     6511                                }
     6512                                else
     6513                                {
     6514                                        usAbs2 = (-1) * *(psDiffXPtr+1);
     6515                                        bSign2 = false;
     6516                                }
     6517                        }
     6518
     6519                        if( x == 0 )
     6520                        {
     6521                                if( usAbs1 < usAbs2 )
     6522                                {
     6523                                        *pbEdgeXPtr = false;
     6524                                }
     6525                        }
     6526                        else if( x == iWidth-2 )
     6527                        {
     6528                                if( usAbs1 <= usAbs0 )
     6529                                        *pbEdgeXPtr = false;
     6530                        }
     6531                        else
     6532                        {
     6533                                if( usAbs2 > usAbs0 )
     6534                                {
     6535                                        if( usAbs1 < usAbs2 )
     6536                                                *pbEdgeXPtr = false;
     6537                                }
     6538                                else
     6539                                {
     6540                                        if( usAbs1 <= usAbs0 )
     6541                                                *pbEdgeXPtr = false;
     6542                                }
     6543                        }
     6544
     6545                        psDiffXPtr++;
     6546                        pbEdgeXPtr++;
     6547                }
     6548        }
     6549
     6550        for( Int y=0; y<iHeight-1; y++ )
     6551        {
     6552                Short* psDiffYPtr = &psDiffY[ y * iWidth ];
     6553                Bool*  pbEdgeYPtr = &pbEdgeY[ y * iWidth ];
     6554                for( Int x=0; x<iWidth; x++ )
     6555                {
     6556                        UShort usAbs0=0, usAbs1=0, usAbs2=0;  // 0 : upper, 1 : current, 2 : bottom
     6557                        Bool   bSign0=false, bSign1=false, bSign2=false;
     6558                        if( y > 0 && *(pbEdgeYPtr-iWidth) == true )
     6559                        {
     6560                                if( *(psDiffYPtr-iWidth) >= 0)
     6561                                {
     6562                                        usAbs0 = *(psDiffYPtr-iWidth);
     6563                                        bSign0 = true;
     6564                                }
     6565                                else
     6566                                {
     6567                                        usAbs0 = (-1) * *(psDiffYPtr-iWidth);
     6568                                        bSign0 = false;
     6569                                }
     6570                        }
     6571                        if( *pbEdgeYPtr == true )
     6572                        {
     6573                                if( *(psDiffYPtr) >= 0)
     6574                                {
     6575                                        usAbs1 = *(psDiffYPtr);
     6576                                        bSign1 = true;
     6577                                }
     6578                                else
     6579                                {
     6580                                        usAbs1 = (-1) * *(psDiffYPtr);
     6581                                        bSign1 = false;
     6582                                }
     6583                        }
     6584                        if( y < iHeight-2 && *(pbEdgeYPtr+iWidth) == true )
     6585                        {
     6586                                if( *(psDiffYPtr+iWidth) >= 0)
     6587                                {
     6588                                        usAbs2 = *(psDiffYPtr+iWidth);
     6589                                        bSign2 = true;
     6590                                }
     6591                                else
     6592                                {
     6593                                        usAbs2 = (-1) * *(psDiffYPtr+iWidth);
     6594                                        bSign2 = false;
     6595                                }
     6596                        }
     6597
     6598                        if( y == 0 )
     6599                        {
     6600                                if( usAbs1 < usAbs2 )
     6601                                        *pbEdgeYPtr = false;
     6602                        }
     6603                        else if( y == iHeight-2 )
     6604                        {
     6605                                if( usAbs1 <= usAbs0 )
     6606                                        *pbEdgeYPtr = false;
     6607                        }
     6608                        else
     6609                        {
     6610                                if( usAbs2 > usAbs0 )
     6611                                {
     6612                                        if( usAbs1 < usAbs2 )
     6613                                                *pbEdgeYPtr = false;
     6614                                }
     6615                                else
     6616                                {
     6617                                        if( usAbs1 <= usAbs0 )
     6618                                                *pbEdgeYPtr = false;
     6619                                }
     6620                        }
     6621
     6622                        psDiffYPtr++;
     6623                        pbEdgeYPtr++;
     6624                }
     6625        }
     6626
     6627        // Edge Merging
     6628        for( Int i=0; i< 4 * iWidth * iHeight; i++ )
     6629                pbEdge[ i ] = false;
     6630        /// Even Line (0,2,4,6,...) => Vertical Edge
     6631        for( Int i=0; i<iHeight; i++)
     6632        {
     6633                for( Int j=0; j<iWidth-1; j++)
     6634                {
     6635                        pbEdge[ (2 * j + 1) + (2 * i) * 2 * iWidth ] = pbEdgeX[ j + i * iHeight ];
     6636                }
     6637        }
     6638        /// Odd Line (1,3,5,7,...) => Horizontal Edge
     6639        for( Int i=0; i<iHeight-1; i++)
     6640        {
     6641                for( Int j=0; j<iWidth; j++)
     6642                {
     6643                        pbEdge[ (2 * j) + (2 * i + 1) * 2 * iWidth ] = pbEdgeY[ j + i * iHeight ];
     6644                }
     6645        }
     6646
     6647        // Intersection Filling
     6648        /// Vertical Edge between Horizontal Edges
     6649        for( Int i = 1; i < 2 * iHeight - 3; i += 2)
     6650        {
     6651                for( Int j = 0; j < 2 * iWidth - 1; j += 2)
     6652                {
     6653                        if( pbEdge[ j + i * 2 * iWidth ] )
     6654                        {
     6655                                if( j != 0 && pbEdge[ (j - 2) + ((i + 2) * 2 * iWidth) ] )
     6656                                {
     6657                                        if( !pbEdge[ (j - 1) + ((i - 1) * 2 * iWidth) ] && !pbEdge[ (j - 1) + ((i + 3) * 2 * iWidth) ] )
     6658                                                pbEdge[ (j - 1) + ((i + 1) * 2 * iWidth) ] = true;
     6659                                }
     6660                                if( j != 2 * iWidth - 2 && pbEdge[ (j + 2) + ((i + 2) * 2 * iWidth) ] )
     6661                                {
     6662                                        if( !pbEdge[ (j + 1) + ((i - 1) * 2 * iWidth) ] && !pbEdge[ (j + 1) + ((i + 3) * 2 * iWidth) ] )
     6663                                                pbEdge[ (j + 1) + ((i + 1) * 2 * iWidth) ] = true;
     6664                                }
     6665                        }
     6666                }
     6667        }
     6668        /// Horizontal Edge between Vertical Edges
     6669        for( Int j = 1; j < 2 * iWidth - 3; j += 2)
     6670        {
     6671                for( Int i = 0; i < 2 * iHeight - 1; i += 2)
     6672                {
     6673                        if( pbEdge[ j + i * 2 * iWidth ] )
     6674                        {
     6675                                if( i != 0 && pbEdge[ (j + 2) + ((i - 2) * 2 * iWidth) ] )
     6676                                {
     6677                                        if( !pbEdge[ (j - 1) + ((i - 1) * 2 * iWidth) ] && !pbEdge[ (j + 3) + ((i - 1) * 2 * iWidth) ] )
     6678                                                pbEdge[ (j + 1) + ((i - 1) * 2 * iWidth) ] = true;
     6679                                }
     6680                                if( i != 2 * iHeight - 2 && pbEdge[ (j + 2) + ((i + 2) * 2 * iWidth) ] )
     6681                                {
     6682                                        if( !pbEdge[ (j - 1) + ((i + 1) * 2 * iWidth) ] && !pbEdge[ (j + 3) + ((i + 1) * 2 * iWidth) ] )
     6683                                                pbEdge[ (j + 1) + ((i + 1) * 2 * iWidth) ] = true;
     6684                                }
     6685                        }
     6686                }
     6687        }
     6688
     6689        // Static Pruning Unnecessary Edges
     6690        /// Step1. Stack push the unconnected edges
     6691        UShort* pusUnconnectedEdgeStack = new UShort[ 4 * iWidth * iHeight ]; // approximate size calculation
     6692        Int iUnconnectedEdgeStackPtr = 0;
     6693        //// Vertical Edges
     6694        for( Int i = 0; i < 2 * iHeight - 1; i += 2 )
     6695        {
     6696                for( Int j = 1; j < 2 * iWidth - 2; j += 2 )
     6697                {
     6698                        if( pbEdge[ j + i * 2 * iWidth ] )
     6699                        {
     6700                                if( !xCheckTerminatedEdge( pbEdge, j, i, iWidth, iHeight ) )
     6701                                {
     6702                                        pusUnconnectedEdgeStack[iUnconnectedEdgeStackPtr] = (i << 8) | (j);
     6703                                        iUnconnectedEdgeStackPtr++;
     6704                                }
     6705                        }
     6706                }
     6707        }
     6708
     6709        //// Horizontal Edges
     6710        for( Int i = 1; i < 2 * iHeight - 2; i += 2 )
     6711        {
     6712                for( Int j = 0; j < 2 * iWidth - 1; j += 2 )
     6713                {
     6714                        if( pbEdge[ j + i * 2 * iWidth ] )
     6715                        {
     6716                                if( !xCheckTerminatedEdge( pbEdge, j, i, iWidth, iHeight ) )
     6717                                {
     6718                                        pusUnconnectedEdgeStack[iUnconnectedEdgeStackPtr] = (i << 8) | (j);
     6719                                        iUnconnectedEdgeStackPtr++;
     6720                                }
     6721                        }
     6722                }
     6723        }
     6724
     6725        /// Step2. Remove the edges from the stack and push the new unconnected edges
     6726        //// (This step may contain duplicated edges already in the stack)
     6727        //// (But it doesn't cause any functional problems)
     6728        while( iUnconnectedEdgeStackPtr != 0 )
     6729        {
     6730                iUnconnectedEdgeStackPtr--;
     6731                Int iX = pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] & 0xff;
     6732                Int iY = pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] >> 8;
     6733
     6734                pbEdge[ iX + iY * 2 * iWidth ] = false;
     6735
     6736                if( iY % 2 == 1 && iX > 0 && pbEdge[ iX - 2 + iY * 2 * iWidth ] &&
     6737                        !xCheckTerminatedEdge( pbEdge, iX - 2, iY, iWidth, iHeight ) ) // left
     6738                {
     6739                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 0) << 8) | (iX - 2);
     6740                        iUnconnectedEdgeStackPtr++;
     6741                }
     6742                if( iY % 2 == 1 && iX < 2 * iWidth - 2 && pbEdge[ iX + 2 + iY * 2 * iWidth ] &&
     6743                        !xCheckTerminatedEdge( pbEdge, iX + 2, iY, iWidth, iHeight ) ) // right
     6744                {
     6745                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 0) << 8) | (iX + 2);
     6746                        iUnconnectedEdgeStackPtr++;
     6747                }
     6748                if( iY % 2 == 0 && iY > 0 && pbEdge[ iX + (iY - 2) * 2 * iWidth ] &&
     6749                        !xCheckTerminatedEdge( pbEdge, iX, iY - 2, iWidth, iHeight ) ) // top
     6750                {
     6751                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY - 2) << 8) | (iX + 0);
     6752                        iUnconnectedEdgeStackPtr++;
     6753                }
     6754                if( iY % 2 == 0 && iY < 2 * iHeight - 2 && pbEdge[ iX + (iY + 2) * 2 * iWidth ] &&
     6755                        !xCheckTerminatedEdge( pbEdge, iX, iY + 2, iWidth, iHeight ) ) // bottom
     6756                {
     6757                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 2) << 8) | (iX + 0);
     6758                        iUnconnectedEdgeStackPtr++;
     6759                }
     6760                if( iX > 0 && iY > 0 && pbEdge[ iX - 1 + (iY - 1) * 2 * iWidth ] &&
     6761                        !xCheckTerminatedEdge( pbEdge, iX - 1, iY - 1, iWidth, iHeight ) ) // left-top
     6762                {
     6763                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY - 1) << 8) | (iX - 1);
     6764                        iUnconnectedEdgeStackPtr++;
     6765                }
     6766                if( iX < 2 * iWidth - 1 && iY > 0 && pbEdge[ iX + 1 + (iY - 1) * 2 * iWidth ] &&
     6767                        !xCheckTerminatedEdge( pbEdge, iX + 1, iY - 1, iWidth, iHeight ) ) // right-top
     6768                {
     6769                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY - 1) << 8) | (iX + 1);
     6770                        iUnconnectedEdgeStackPtr++;
     6771                }
     6772                if( iX > 0 && iY < 2 * iHeight - 1 && pbEdge[ iX - 1 + (iY + 1) * 2 * iWidth ] &&
     6773                        !xCheckTerminatedEdge( pbEdge, iX - 1, iY + 1, iWidth, iHeight ) ) // left-bottom
     6774                {
     6775                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 1) << 8) | (iX - 1);
     6776                        iUnconnectedEdgeStackPtr++;
     6777                }
     6778                if( iX < 2 * iWidth - 1 && iY < 2 * iHeight - 1 && pbEdge[ iX + 1 + (iY + 1) * 2 * iWidth ] &&
     6779                        !xCheckTerminatedEdge( pbEdge, iX + 1, iY + 1, iWidth, iHeight ) ) // right-bottom
     6780                {
     6781                        pusUnconnectedEdgeStack[ iUnconnectedEdgeStackPtr ] = ((iY + 1) << 8) | (iX + 1);
     6782                        iUnconnectedEdgeStackPtr++;
     6783                }
     6784        }
     6785
     6786#if 0
     6787        // Loop Edge Pruning (permit only single chain)
     6788        /// Step 1. Stack push the boundary edges
     6789        UShort* pusBoundaryStack = new UShort[ iWidth + iHeight ];
     6790        Int iBoundaryStackPtr = 0;
     6791        for( Int i = iHeight - 1; i >= 0; i-- )
     6792        {
     6793                if( pbCUEdge[ i * iWidth ] )
     6794                {
     6795                        pusBoundaryStack[iBoundaryStackPtr] = (i << 8);
     6796                        iBoundaryStackPtr++;
     6797                }
     6798        }
     6799        for( Int i = iWidth - 1; i >= 0; i-- )
     6800        {
     6801                if( pbCUEdge[ i ] )
     6802                {
     6803                        pusBoundaryStack[iBoundaryStackPtr] = i;
     6804                        iBoundaryStackPtr++;
     6805                }
     6806        }
     6807
     6808        /// Step 2. Traverse edges
     6809        Bool      bFound = false;
     6810        //Bool*    pbVisit = new Bool[ iWidth * iHeight ];
     6811
     6812        for( Int i = iBoundaryStackPtr - 1; i >= 0 && !bFound; i-- )
     6813        {
     6814                //Int iX, iY;
     6815                Int iStartX, iStartY;
     6816                Bool*  pbStacked = new Bool[ iWidth * iHeight ];
     6817                UShort* pusStack = new UShort[ iWidth * iHeight ];
     6818                Int iStackPtr = 0;
     6819
     6820                for( Int ii = 0; ii < iWidth * iHeight; ii++ )
     6821                        pbVisit[ii] = false;
     6822                for( Int ii = 0; ii < iWidth * iHeight; ii++ )
     6823                        pbStacked[ii] = false;
     6824
     6825                iStartX = iX = *(pusBoundaryStack + i) & 0xff;
     6826                iStartY = iY = *(pusBoundaryStack + i) >> 8;
     6827                pbStacked[ iX + iY * iWidth ] = true;
     6828                pusStack[iStackPtr++] = (iY << 8) | (iX);
     6829
     6830                while(!bFound)
     6831                {
     6832                        //printf("(%d,%d) StackPtr %d\n",iX,iY,iStackPtr);
     6833                        // right
     6834                        if( iX < iWidth - 1 && !pbStacked[ (iX + 1) + iY * iWidth ] && pbCUEdge[ (iX + 1) + iY * iWidth ] )
     6835                        {
     6836                                iX = iX + 1;
     6837                                pbStacked[ iX + iY * iWidth ] = true;
     6838                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6839                                iStackPtr++;
     6840                        }
     6841                        // left
     6842                        else if( iX > 0 && !pbStacked[ (iX - 1) + iY * iWidth ] && pbCUEdge[ (iX - 1) + iY * iWidth ] )
     6843                        {
     6844                                iX = iX - 1;
     6845                                pbStacked[ iX + iY * iWidth ] = true;
     6846                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6847                                iStackPtr++;
     6848                        }
     6849                        // bottom
     6850                        else if( iY < iHeight - 1 && !pbStacked[ iX + (iY + 1) * iWidth ] && pbCUEdge[ iX + (iY + 1) * iWidth ] )
     6851                        {
     6852                                iY = iY + 1;
     6853                                pbStacked[ iX + iY * iWidth ] = true;
     6854                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6855                                iStackPtr++;
     6856                        }
     6857                        // top
     6858                        else if( iY > 0 && !pbStacked[ iX + (iY - 1) * iWidth ] && pbCUEdge[ iX + (iY - 1) * iWidth ] )
     6859                        {
     6860                                iY = iY - 1;
     6861                                pbStacked[ iX + iY * iWidth ] = true;
     6862                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6863                                iStackPtr++;
     6864                        }
     6865                        // left-top
     6866                        else if( iX > 0 && iY > 0 && !pbStacked[ (iX - 1) + (iY - 1) * iWidth ] && pbCUEdge[ (iX - 1) + (iY - 1) * iWidth])
     6867                        {
     6868                                iX = iX - 1;
     6869                                iY = iY - 1;
     6870                                pbStacked[ iX + iY * iWidth ] = true;
     6871                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6872                                iStackPtr++;
     6873                        }
     6874                        // right-top
     6875                        else if( iX < iWidth - 1 && iY > 0 && !pbStacked[ (iX + 1) + (iY - 1) * iWidth ] && pbCUEdge[ (iX + 1) + (iY - 1) * iWidth])
     6876                        {
     6877                                iX = iX + 1;
     6878                                iY = iY - 1;
     6879                                pbStacked[ iX + iY * iWidth ] = true;
     6880                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6881                                iStackPtr++;
     6882                        }
     6883                        // left-bottom
     6884                        else if( iX > 0 && iY < iHeight - 1 && !pbStacked[ (iX - 1) + (iY + 1) * iWidth ] && pbCUEdge[ (iX - 1) + (iY + 1) * iWidth])
     6885                        {
     6886                                iX = iX - 1;
     6887                                iY = iY + 1;
     6888                                pbStacked[ iX + iY * iWidth ] = true;
     6889                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6890                                iStackPtr++;
     6891                        }
     6892                        // right-bottom
     6893                        else if( iX < iWidth - 1 && iY < iHeight - 1 && !pbStacked[ (iX + 1) + (iY + 1) * iWidth ] && pbCUEdge[ (iX + 1) + (iY + 1) * iWidth])
     6894                        {
     6895                                iX = iX + 1;
     6896                                iY = iY + 1;
     6897                                pbStacked[ iX + iY * iWidth ] = true;
     6898                                pusStack[iStackPtr] = (iY << 8) | (iX);
     6899                                iStackPtr++;
     6900                        }
     6901                        else
     6902                        {
     6903                                if(iX == 0 || iY == 0 || iX == iWidth - 1 || iY == iHeight - 1 ) // boundary! (finished)
     6904                                {
     6905                                        if( iX == iStartX && iY == iStartY )
     6906                                        {
     6907                                                //printf("return back to starting edge\n");
     6908                                                break; // not found!
     6909                                        }
     6910                                        for( Int ii = 0; ii < iStackPtr; ii++ )
     6911                                        {
     6912                                                Int iVisitX = pusStack[ii] & 0xff;
     6913                                                Int iVisitY = pusStack[ii] >> 8;
     6914                                                pbVisit[ iVisitX + iVisitY * iWidth ] = true;
     6915                                        }
     6916                                        bFound = true;
     6917                                        //printf("\nEdge Found!!\n");
     6918                                }
     6919                                else
     6920                                {
     6921                                        pbCUEdge[ iX + iY * iWidth ] = false; // prune!
     6922                                        iStackPtr--;
     6923                                        iX = pusStack[iStackPtr-1] & 0xff;
     6924                                        iY = pusStack[iStackPtr-1] >> 8;
     6925                                        //printf("perform pruning!\n");
     6926                                }
     6927                        }
     6928                }
     6929                delete pbStacked;
     6930                delete pusStack;
     6931        } // result : pbVisit[]
     6932
     6933        // 3. Update Edge variable
     6934        for( Int i = 0; i < iWidth * iHeight; i++ )
     6935        {
     6936                pbCUEdge[ i ] = pbVisit[ i ];
     6937        }
     6938#endif
     6939
     6940        // Region Generation ( edge -> region )
     6941        Bool* pbRegion = pcCU->getEdgePartition( uiPartIdx );
     6942        Bool* pbVisit  = new Bool[ iWidth * iHeight ];
     6943
     6944        for( UInt ui = 0; ui < iWidth * iHeight; ui++ )
     6945        {
     6946                pbRegion[ ui ] = true; // fill it as region 1 (we'll discover region 0 next)
     6947                pbVisit [ ui ] = false;
     6948        }
     6949
     6950        Int* piStack = new Int[ iWidth * iHeight ];
     6951
     6952        Int iPtr = 0;
     6953
     6954        piStack[iPtr++] = (0 << 8) | (0);
     6955        pbRegion[ 0 ] = false;
     6956
     6957        while(iPtr > 0)
     6958        {
     6959                Int iTmp = piStack[--iPtr];
     6960                Int iX1, iY1;
     6961                iX1 = iTmp & 0xff;
     6962                iY1 = (iTmp >> 8) & 0xff;
     6963
     6964                pbVisit[ iX1 + iY1 * iWidth ] = true;
     6965
     6966                assert( iX1 >= 0 && iX1 < iWidth );
     6967                assert( iY1 >= 0 && iY1 < iHeight );
     6968
     6969                if( iX1 > 0 && !pbEdge[ 2 * iX1 - 1 + 4 * iY1 * iWidth ] && !pbVisit[ iX1 - 1 + iY1 * iWidth ] )
     6970                {
     6971                        piStack[iPtr++] = (iY1 << 8) | (iX1 - 1);
     6972                        pbRegion[ iX1 - 1 + iY1 * iWidth ] = false;
     6973                }
     6974                if( iX1 < iWidth - 1 && !pbEdge[ 2 * iX1 + 1 + 4 * iY1 * iWidth ] && !pbVisit[ iX1 + 1 + iY1 * iWidth ] )
     6975                {
     6976                        piStack[iPtr++] = (iY1 << 8) | (iX1 + 1);
     6977                        pbRegion[ iX1 + 1 + iY1 * iWidth ] = false;
     6978                }
     6979                if( iY1 > 0 && !pbEdge[ 2 * iX1 + 2 * (2 * iY1 - 1) * iWidth ] && !pbVisit[ iX1 + (iY1 - 1) * iWidth ] )
     6980                {
     6981                        piStack[iPtr++] = ((iY1 - 1) << 8) | iX1;
     6982                        pbRegion[ iX1 + (iY1 - 1) * iWidth ] = false;
     6983                }
     6984                if( iY1 < iHeight - 1 && !pbEdge[ 2 * iX1 + 2 * (2 * iY1 + 1) * iWidth ] && !pbVisit[ iX1 + (iY1 + 1) * iWidth ] )
     6985                {
     6986                        piStack[iPtr++] = ((iY1 + 1) << 8) | iX1;
     6987                        pbRegion[ iX1 + (iY1 + 1) * iWidth ] = false;
     6988                }
     6989        }
     6990
     6991        ///////////
     6992        iPtr = 0;
     6993        for( Int i = 0; i < iWidth * iHeight; i++ )
     6994                pbVisit[ i ] = false;
     6995        piStack[ iPtr++ ] = (0 << 8) | (0); // initial seed
     6996        while( iPtr > 0 && iPtr < iWidth * iHeight )
     6997        {
     6998                Int iX;
     6999                Int iY;
     7000                iPtr--;
     7001                iX = piStack[ iPtr ] & 0xff;
     7002                iY = piStack[ iPtr ] >> 8;
     7003                pbVisit[ iY * iWidth + iX ] = true;
     7004
     7005                if( iY > 0 && !pbVisit[ (iY - 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY - 1) * iWidth + iX ] )
     7006                {
     7007                        piStack[ iPtr++ ] = ((iY - 1) << 8) | iX;
     7008                }
     7009                if( iY < iHeight - 1 && !pbVisit[ (iY + 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY + 1) * iWidth + iX ] )
     7010                {
     7011                        piStack[ iPtr++ ] = ((iY + 1) << 8) | iX;
     7012                }
     7013                if( iX > 0 && !pbVisit[ iY * iWidth + (iX - 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX - 1) ] )
     7014                {
     7015                        piStack[ iPtr++ ] = (iY << 8) | (iX - 1);
     7016                }
     7017                if( iX < iWidth - 1 && !pbVisit[ iY * iWidth + (iX + 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX + 1) ] )
     7018                {
     7019                        piStack[ iPtr++ ] = (iY << 8) | (iX + 1);
     7020                }
     7021        }
     7022        assert( iPtr == 0 || iPtr == iWidth * iHeight );
     7023
     7024        Bool bBipartition;
     7025        if( iPtr == iWidth * iHeight )
     7026        {
     7027                bBipartition = false; // single partition
     7028        }
     7029        else
     7030        {
     7031                for( Int i = 0; i < iWidth * iHeight; i++ )
     7032                {
     7033                        if( !pbVisit[ i ] )
     7034                        {
     7035                                piStack[ iPtr++ ] = (( i / iWidth ) << 8) | ( i % iWidth );
     7036                                pbVisit[ i ] = true;
     7037                                break;
     7038                        }
     7039                }
     7040                while( iPtr > 0 )
     7041                {
     7042                        Int iX;
     7043                        Int iY;
     7044                        iPtr--;
     7045                        iX = piStack[ iPtr ] & 0xff;
     7046                        iY = piStack[ iPtr ] >> 8;
     7047                        pbVisit[ iY * iWidth + iX ] = true;
     7048
     7049                        if( iY > 0 && !pbVisit[ (iY - 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY - 1) * iWidth + iX ] )
     7050                        {
     7051                                piStack[ iPtr++ ] = ((iY - 1) << 8) | iX;
     7052                        }
     7053                        if( iY < iHeight - 1 && !pbVisit[ (iY + 1) * iWidth + iX ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ (iY + 1) * iWidth + iX ] )
     7054                        {
     7055                                piStack[ iPtr++ ] = ((iY + 1) << 8) | iX;
     7056                        }
     7057                        if( iX > 0 && !pbVisit[ iY * iWidth + (iX - 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX - 1) ] )
     7058                        {
     7059                                piStack[ iPtr++ ] = (iY << 8) | (iX - 1);
     7060                        }
     7061                        if( iX < iWidth - 1 && !pbVisit[ iY * iWidth + (iX + 1) ] && pbRegion[ iY * iWidth + iX ] == pbRegion[ iY * iWidth + (iX + 1) ] )
     7062                        {
     7063                                piStack[ iPtr++ ] = (iY << 8) | (iX + 1);
     7064                        }
     7065                }
     7066                bBipartition = true;
     7067                for( Int i = 0; i < iWidth * iHeight; i++ )
     7068                {
     7069                        if( !pbVisit[ i ] )
     7070                        {
     7071                                bBipartition = false;
     7072                                break;
     7073                        }
     7074                }
     7075        }
     7076
     7077        xFree( pbEdge );
     7078        delete[] pbEdgeX; pbEdgeX = NULL;
     7079        delete[] pbEdgeY; pbEdgeY = NULL;
     7080        delete[] psDiffX; psDiffX = NULL;
     7081        delete[] psDiffY; psDiffY = NULL;
     7082        delete[] pusUnconnectedEdgeStack; pusUnconnectedEdgeStack = NULL;
     7083        delete[] pbVisit; pbVisit = NULL;
     7084        delete[] piStack; piStack = NULL;
     7085
     7086        Bool bCheckPossibleChain;
     7087
     7088        if( bBipartition )
     7089                bCheckPossibleChain = xConstructChainCode( pcCU, uiPartIdx, bPU4x4 );
     7090        else
     7091                bCheckPossibleChain = false;
     7092
     7093        return bCheckPossibleChain;
     7094}
     7095
     7096#endif
     7097
     7098Bool TEncSearch::xConstructChainCode( TComDataCU* pcCU, UInt uiPartIdx, Bool bPU4x4 )
     7099{
     7100        UInt   uiWidth    = pcCU->getWidth( uiPartIdx ) >> (bPU4x4 ? 1 : 0);
     7101        UInt   uiHeight   = pcCU->getHeight( uiPartIdx ) >> (bPU4x4 ? 1 : 0);
     7102        Bool*  pbEdge     = (Bool*) xMalloc( Bool, uiWidth * uiHeight * 4 );
     7103        Bool*  pbVisit    = (Bool*) xMalloc( Bool, uiWidth * uiHeight * 4 );
     7104        UInt   uiMaxEdge  = uiWidth * (LGE_EDGE_INTRA_MAX_EDGE_NUM_PER_4x4 / 4);
     7105        Bool*  pbRegion   = pcCU->getEdgePartition( uiPartIdx );
     7106        UChar* piEdgeCode = pcCU->getEdgeCode( uiPartIdx );
     7107        Bool   bStartLeft = false;
     7108        Bool   bPossible  = false;
     7109        Bool   bFinish    = false;
     7110        Int    iStartPosition = -1;
     7111        Int    iPtr = 0;
     7112        Int    iDir = -1, iNextDir = -1;
     7113        Int    iArrow = -1, iNextArrow = -1;
     7114        Int    iX = -1, iY = -1;
     7115        Int    iDiffX = 0, iDiffY = 0;
     7116        UChar  iCode = 255;
     7117        UInt   uiWidth2 = uiWidth * 2;
     7118
     7119        for( Int i = 0; i < uiWidth * uiHeight * 4; i++ )
     7120                pbEdge[ i ] = false;
     7121
     7122        for( Int i = 0; i < uiHeight; i++ )
     7123        {
     7124                for( Int j = 0; j < uiWidth - 1; j++ )
     7125                {
     7126                        if( pbRegion[ i * uiWidth + j ] != pbRegion[ i * uiWidth + j + 1 ] )
     7127                                pbEdge[ i * uiWidth * 4 + j * 2 + 1 ] = true;
     7128                }
     7129        }
     7130
     7131        for( Int i = 0; i < uiHeight - 1; i++ )
     7132        {
     7133                for( Int j = 0; j < uiWidth; j++ )
     7134                {
     7135                        if( pbRegion[ (i + 0) * uiWidth + j ] != pbRegion[ (i + 1) * uiWidth + j ] )
     7136                                pbEdge[ (2 * i + 1) * 2 * uiWidth + j * 2 ] = true;
     7137                }
     7138        }
     7139
     7140        for( Int i = 1; i < uiWidth2 - 2; i+=2 )
     7141        {
     7142                if(pbEdge[ i ])
     7143                {
     7144                        bPossible  = true;
     7145                        bStartLeft = false;
     7146                        iStartPosition = iX = i;
     7147                        iY = 0;
     7148                        iDir = 3;
     7149                        iArrow = 3;
     7150                        break;
     7151                }
     7152        }
     7153
     7154        if( !bPossible )
     7155        {
     7156                for( Int i = 1; i < uiWidth2 - 2; i+=2 )
     7157                {
     7158                        if(pbEdge[ i * uiWidth2 ])
     7159                        {
     7160                                bPossible  = true;
     7161                                bStartLeft = true;
     7162                                iX = 0;
     7163                                iStartPosition = iY = i;
     7164                                iDir = 1;
     7165                                iArrow = 1;
     7166                                break;
     7167                        }
     7168                }
     7169        }
     7170
     7171        if( bPossible )
     7172        {
     7173                for( Int i = 0; i < 4 * uiWidth * uiHeight; i++ )
     7174                        pbVisit[ i ] = false;
     7175
     7176                while( !bFinish )
     7177                {
     7178                        Bool bArrowSkip = false;
     7179                        pbVisit[ iX + iY * uiWidth2 ] = true;
     7180
     7181                        switch( iDir )
     7182                        {
     7183                        case 0: // left
     7184                                if( iX > 0 && !pbVisit[ (iX - 2) + iY * uiWidth2 ] && pbEdge[ (iX - 2) + iY * uiWidth2 ] ) // left
     7185                                {
     7186                                        iDiffX = -2;
     7187                                        iDiffY =  0;
     7188                                        iNextDir = 0;
     7189                                        iNextArrow = 0;
     7190                                }
     7191                                else if( iX > 0 && !pbVisit[ (iX - 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY - 1) * uiWidth2 ] ) // top
     7192                                {
     7193                                        iDiffX = -1;
     7194                                        iDiffY = -1;
     7195                                        iNextDir = 2;
     7196                                        iNextArrow = 4;
     7197                                }
     7198                                else if( iX > 0 && !pbVisit[ (iX - 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY + 1) * uiWidth2 ] ) // bottom
     7199                                {
     7200                                        iDiffX = -1;
     7201                                        iDiffY = +1;
     7202                                        iNextDir = 3;
     7203                                        iNextArrow = iArrow;
     7204                                        if( !(iPtr == 0 && iX == uiWidth2 - 2 && iY == uiHeight * 2 - 3) )
     7205                                                bArrowSkip = true;
     7206                                        else
     7207                                                iNextArrow = 3;
     7208                                }
     7209                                else if( iX == 0 )
     7210                                {
     7211                                        iDiffX = 0;
     7212                                        iDiffY = 0;
     7213                                        iNextDir = iDir;
     7214                                        iNextArrow = iArrow;
     7215                                        bFinish = true;
     7216                                        continue;
     7217                                }
     7218                                else
     7219                                {
     7220                                        iPtr = 0; // edge loop or unwanted case
     7221                                        bFinish = true;
     7222                                        //continue;
     7223                                        assert(false);
     7224                                }
     7225                                break;
     7226                        case 1: // right
     7227                                if( iX < uiWidth2 - 2 && !pbVisit[ (iX + 2) + iY * uiWidth2 ] && pbEdge[ (iX + 2) + iY * uiWidth2 ] ) // right
     7228                                {
     7229                                        iDiffX = +2;
     7230                                        iDiffY =  0;
     7231                                        iNextDir = 1;
     7232                                        iNextArrow = 1;
     7233                                }
     7234                                else if( iX < uiWidth2 - 2 && !pbVisit[ (iX + 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY - 1) * uiWidth2 ] ) // top
     7235                                {
     7236                                        iDiffX = +1;
     7237                                        iDiffY = -1;
     7238                                        iNextDir = 2;
     7239                                        iNextArrow = iArrow;
     7240                                        if( !(iPtr == 0 && iX == 0 && iY == 1) )
     7241                                                bArrowSkip = true;
     7242                                        else
     7243                                                iNextArrow = 2;
     7244                                }
     7245                                else if( iX < uiWidth2 - 2 && !pbVisit[ (iX + 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY + 1) * uiWidth2 ] ) // bottom
     7246                                {
     7247                                        iDiffX = +1;
     7248                                        iDiffY = +1;
     7249                                        iNextDir = 3;
     7250                                        iNextArrow = 7;
     7251                                }
     7252                                else if( iX == uiWidth2 - 2 )
     7253                                {
     7254                                        iDiffX = 0;
     7255                                        iDiffY = 0;
     7256                                        iNextDir = iDir;
     7257                                        iNextArrow = iArrow;
     7258                                        bFinish = true;
     7259                                        continue;
     7260                                }
     7261                                else
     7262                                {
     7263                                        iPtr = 0; // edge loop or unwanted case
     7264                                        bFinish = true;
     7265                                        //continue;
     7266                                        assert(false);
     7267                                }
     7268                                break;
     7269                        case 2: // top
     7270                                if( iY > 0 && !pbVisit[ (iX - 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY - 1) * uiWidth2 ] ) // left
     7271                                {
     7272                                        iDiffX = -1;
     7273                                        iDiffY = -1;
     7274                                        iNextDir = 0;
     7275                                        iNextArrow = iArrow;
     7276                                        if( !(iPtr == 0 && iX == 1 && iY == uiHeight * 2 - 2) )
     7277                                                bArrowSkip = true;
     7278                                        else
     7279                                                iNextArrow = 0;
     7280                                }
     7281                                else if( iY > 0 && !pbVisit[ (iX + 1) + (iY - 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY - 1) * uiWidth2 ] ) // right
     7282                                {
     7283                                        iDiffX = +1;
     7284                                        iDiffY = -1;
     7285                                        iNextDir = 1;
     7286                                        iNextArrow = 5;
     7287                                }
     7288                                else if( iY > 0 && !pbVisit[ iX + (iY - 2) * uiWidth2 ] && pbEdge[ iX + (iY - 2) * uiWidth2 ] ) // top
     7289                                {
     7290                                        iDiffX =  0;
     7291                                        iDiffY = -2;
     7292                                        iNextDir = 2;
     7293                                        iNextArrow = 2;
     7294                                }
     7295                                else if( iY == 0 )
     7296                                {
     7297                                        iDiffX = 0;
     7298                                        iDiffY = 0;
     7299                                        iNextDir = iDir;
     7300                                        iNextArrow = iArrow;
     7301                                        bFinish = true;
     7302                                        continue;
     7303                                }
     7304                                else
     7305                                {
     7306                                        iPtr = 0; // edge loop or unwanted case
     7307                                        bFinish = true;
     7308                                        //continue;
     7309                                        assert(false);
     7310                                }
     7311                                break;
     7312                        case 3: // bottom
     7313                                if( iY < uiWidth2 - 2 && !pbVisit[ (iX - 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX - 1) + (iY + 1) * uiWidth2 ] ) // left
     7314                                {
     7315                                        iDiffX = -1;
     7316                                        iDiffY = +1;
     7317                                        iNextDir = 0;
     7318                                        iNextArrow = 6;
     7319                                }
     7320                                else if( iY < uiWidth2 - 2 && !pbVisit[ (iX + 1) + (iY + 1) * uiWidth2 ] && pbEdge[ (iX + 1) + (iY + 1) * uiWidth2 ] ) // right
     7321                                {
     7322                                        iDiffX = +1;
     7323                                        iDiffY = +1;
     7324                                        iNextDir = 1;
     7325                                        iNextArrow = iArrow;
     7326                                        if( !(iPtr == 0 && iX == uiWidth * 2 - 3 && iY == 0) )
     7327                                                bArrowSkip = true;
     7328                                        else
     7329                                                iNextArrow = 1;
     7330                                }
     7331                                else if( iY < uiWidth2 - 2 && !pbVisit[ iX + (iY + 2) * uiWidth2 ] && pbEdge[ iX + (iY + 2) * uiWidth2 ] ) // bottom
     7332                                {
     7333                                        iDiffX =  0;
     7334                                        iDiffY = +2;
     7335                                        iNextDir = 3;
     7336                                        iNextArrow = 3;
     7337                                }
     7338                                else if( iY == uiWidth2 - 2 )
     7339                                {
     7340                                        iDiffX = 0;
     7341                                        iDiffY = 0;
     7342                                        iNextDir = iDir;
     7343                                        iNextArrow = iArrow;
     7344                                        bFinish = true;
     7345                                        continue;
     7346                                }
     7347                                else
     7348                                {
     7349                                        iPtr = 0; // edge loop or unwanted case
     7350                                        bFinish = true;
     7351                                        //continue;
     7352                                        assert(false);
     7353                                }
     7354                                break;
     7355                        }
     7356
     7357                        const UChar tableCode[8][8] = { { 0, -1, 4, 3, 2, 6, 1, 5 }, // iArrow(current direction), iNextArrow(next direction)
     7358                        { -1, 0, 3, 4, 5, 1, 6, 2 },
     7359                        { 3, 4, 0, -1, 1, 2, 5, 6 },
     7360                        { 4, 3, -1, 0, 6, 5, 2, 1 },
     7361                        { 1, 6, 2, 5, 0, 4, 3, -1 },
     7362                        { 5, 2, 1, 6, 3, 0, -1, 4 },
     7363                        { 2, 5, 6, 1, 4, -1, 0, 3 },
     7364                        { 6, 1, 5, 2, -1, 3, 4, 0 } };
     7365
     7366                        iCode = tableCode[iArrow][iNextArrow];
     7367
     7368                        if(iPtr >= uiMaxEdge)
     7369                        {
     7370                                iPtr = 0; // over the maximum number of edge
     7371                                bPossible = false;
     7372                                break;
     7373                        }
     7374
     7375                        if( !bArrowSkip )
     7376                        {
     7377                                piEdgeCode[iPtr++] = iCode; // first edge coding
     7378                                //printf("xEdgeCoding: (%d,%d)->(%d,%d) code %d\n",iX,iY, iX+iDiffX, iY+iDiffY, iCode);
     7379                        }
     7380
     7381                        iX += iDiffX;
     7382                        iY += iDiffY;
     7383                        iDir = iNextDir;
     7384                        iArrow = iNextArrow;
     7385                }
     7386        }
     7387
     7388        pcCU->setEdgeLeftFirst( uiPartIdx, bStartLeft );
     7389        pcCU->setEdgeStartPos ( uiPartIdx, bStartLeft ? (iStartPosition - 1) >> 1 : (iStartPosition + 1) >> 1);
     7390        pcCU->setEdgeNumber   ( uiPartIdx, iPtr );
     7391
     7392        xFree( pbEdge );
     7393        xFree( pbVisit );
     7394
     7395        return (iPtr != 0);
     7396}
     7397
     7398#if LGE_EDGE_INTRA_DELTA_DC
     7399Void TEncSearch::xAssignEdgeIntraDeltaDCs( TComDataCU*   pcCU,
     7400                                                                                  UInt          uiAbsPartIdx,
     7401                                                                                  Pel*          piOrig,
     7402                                                                                  UInt          uiStride,
     7403                                                                                  Pel*          piPredic,
     7404                                                                                  UInt          uiWidth,
     7405                                                                                  UInt          uiHeight )
     7406{
     7407        Int iDC0 = 0;
     7408        Int iDC1 = 0;
     7409        Int iPredDC0 = 0;
     7410        Int iPredDC1 = 0;
     7411        Int iDeltaDC0 = 0;
     7412        Int iDeltaDC1 = 0;
     7413
     7414        Bool* pbRegion = pcCU->getEdgePartition( uiAbsPartIdx );
     7415
     7416        Int* piMask = pcCU->getPattern()->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt );
     7417        Int iMaskStride = ( uiWidth<<1 ) + 1;
     7418
     7419        // DC Calculation
     7420        {
     7421                UInt uiSum0 = 0;
     7422                UInt uiSum1 = 0;
     7423                UInt uiCount0 = 0;
     7424                UInt uiCount1 = 0;
     7425
     7426                Pel* piTemp = piOrig;
     7427                for( UInt ui = 0; ui < uiHeight; ui++ )
     7428                {
     7429                        for( UInt uii = 0; uii < uiWidth; uii++ )
     7430                        {
     7431                                if( pbRegion[ ui * uiWidth + uii ] == false )
     7432                                {
     7433                                        uiSum0 += (piTemp[ uii ]);
     7434                                        uiCount0++;
     7435                                }
     7436                                else
     7437                                {
     7438                                        uiSum1 += (piTemp[ uii ]);
     7439                                        uiCount1++;
     7440                                }
     7441                        }
     7442                        piTemp += uiStride;
     7443                }
     7444                if( uiCount0 == 0 )
     7445                        assert(false);
     7446                if( uiCount1 == 0 )
     7447                        assert(false);
     7448                iDC0 = uiSum0 / uiCount0; // TODO : integer op.
     7449                iDC1 = uiSum1 / uiCount1;
     7450        }
     7451
     7452        // PredDC Calculation
     7453        {
     7454                UInt uiSum0 = 0;
     7455                UInt uiSum1 = 0;
     7456                UInt uiCount0 = 0;
     7457                UInt uiCount1 = 0;
     7458
     7459                for( UInt ui = 0; ui < uiWidth; ui++ )
     7460                {
     7461                        if( pbRegion[ ui ] == false )
     7462                        {
     7463                                uiSum0 += (piMask[ ui + 1 ]);
     7464                                uiCount0++;
     7465                        }
     7466                        else
     7467                        {
     7468                                uiSum1 += (piMask[ ui + 1 ]);
     7469                                uiCount1++;
     7470                        }
     7471                }
     7472                for( UInt ui = 0; ui < uiHeight; ui++ ) // (0,0) recount (to avoid division)
     7473                {
     7474                        if( pbRegion[ ui * uiWidth ] == false )
     7475                        {
     7476                                uiSum0 += (piMask[ (ui + 1) * iMaskStride ]);
     7477                                uiCount0++;
     7478                        }
     7479                        else
     7480                        {
     7481                                uiSum1 += (piMask[ (ui + 1) * iMaskStride ]);
     7482                                uiCount1++;
     7483                        }
     7484                }
     7485                if( uiCount0 == 0 )
     7486                        assert(false);
     7487                if( uiCount1 == 0 )
     7488                        assert(false);
     7489                iPredDC0 = uiSum0 / uiCount0; // TODO : integer op.
     7490                iPredDC1 = uiSum1 / uiCount1;
     7491        }
     7492
     7493        iDeltaDC0 = iDC0 - iPredDC0;
     7494        iDeltaDC1 = iDC1 - iPredDC1;
     7495
     7496#if HHI_VSO
     7497        if( m_pcRdCost->getUseVSO() )
     7498        {
     7499                Int iFullDeltaDC0 = iDeltaDC0;
     7500                Int iFullDeltaDC1 = iDeltaDC1;
     7501
     7502                xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC0 );
     7503                xDeltaDCQuantScaleDown( pcCU, iFullDeltaDC1 );
     7504
     7505                Dist  uiBestDist     = RDO_DIST_MAX;
     7506                UInt  uiBestQStepDC0 = 0;
     7507                UInt  uiBestQStepDC1 = 0;
     7508
     7509                UInt uiDeltaDC0Max = abs(iFullDeltaDC0);
     7510                UInt uiDeltaDC1Max = abs(iFullDeltaDC1);
     7511
     7512                //VSO Level delta DC check range extension
     7513                uiDeltaDC0Max += (uiDeltaDC0Max>>1);
     7514                uiDeltaDC1Max += (uiDeltaDC1Max>>1);
     7515
     7516                for( UInt uiQStepDC0 = 1; uiQStepDC0 <= uiDeltaDC0Max; uiQStepDC0++  )
     7517                {
     7518                        Int iLevelDeltaDC0 = (Int)(uiQStepDC0) * (Int)(( iFullDeltaDC0 < 0 ) ? -1 : 1);
     7519                        xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC0 );
     7520
     7521                        Int iTestDC0 = Clip( iPredDC0 + iLevelDeltaDC0 );
     7522                        for( UInt uiQStepDC1 = 1; uiQStepDC1 <= uiDeltaDC1Max; uiQStepDC1++  )
     7523                        {
     7524                                Int iLevelDeltaDC1 = (Int)(uiQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
     7525                                xDeltaDCQuantScaleUp( pcCU, iLevelDeltaDC1 );
     7526
     7527                                Int iTestDC1 = Clip( iPredDC1 + iLevelDeltaDC1 );
     7528
     7529                                Pel* piTemp = piPredic;
     7530                                for( UInt ui = 0; ui < uiHeight; ui++ )
     7531                                {
     7532                                        for( UInt uii = 0; uii < uiWidth; uii++ )
     7533                                        {
     7534                                                if( pbRegion[ ui * uiWidth + uii ] == false )
     7535                                                {
     7536                                                        piTemp[ uii ] = iTestDC0;
     7537                                                }
     7538                                                else
     7539                                                {
     7540                                                        piTemp[ uii ] = iTestDC1;
     7541                                                }
     7542                                        }
     7543                                        piTemp += uiStride;
     7544                                }
     7545
     7546                                Dist uiActDist = m_pcRdCost->getDistVS( pcCU, 0, piPredic, uiStride,  piOrig, uiStride, uiWidth, uiHeight, false, 0 );
     7547                                if( uiActDist < uiBestDist || uiBestDist == RDO_DIST_MAX )
     7548                                {
     7549                                        uiBestDist     = uiActDist;
     7550                                        uiBestQStepDC0 = uiQStepDC0;
     7551                                        uiBestQStepDC1 = uiQStepDC1;
     7552                                }
     7553                        }
     7554                }
     7555
     7556                iFullDeltaDC0 = (Int)(uiBestQStepDC0) * (Int)(( iFullDeltaDC0 < 0 ) ? -1 : 1);
     7557                iFullDeltaDC1 = (Int)(uiBestQStepDC1) * (Int)(( iFullDeltaDC1 < 0 ) ? -1 : 1);
     7558                xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC0 );
     7559                xDeltaDCQuantScaleUp( pcCU, iFullDeltaDC1 );
     7560                iDeltaDC0 = iFullDeltaDC0;
     7561                iDeltaDC1 = iFullDeltaDC1;
     7562        }
     7563#endif
     7564
     7565        xDeltaDCQuantScaleDown( pcCU, iDeltaDC0 );
     7566        xDeltaDCQuantScaleDown( pcCU, iDeltaDC1 );
     7567
     7568        pcCU->setEdgeDeltaDC0( uiAbsPartIdx, iDeltaDC0 );
     7569        pcCU->setEdgeDeltaDC1( uiAbsPartIdx, iDeltaDC1 );
     7570}
     7571#endif
     7572#endif
     7573
    62097574//! \}
Note: See TracChangeset for help on using the changeset viewer.