예제 #1
0
Void TEncEntropy::xEncodeTransform( Bool& bCodeDQP, Bool& codeChromaQpAdj, TComTU &rTu )
{
//pcCU, absPartIdxCU, uiAbsPartIdx, uiDepth+1, uiTrIdx+1, quadrant,
  TComDataCU *pcCU=rTu.getCU();
  const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU();
  const UInt numValidComponent = pcCU->getPic()->getNumberValidComponents();
  const Bool bChroma = isChromaEnabled(pcCU->getPic()->getChromaFormat());
  const UInt uiTrIdx = rTu.GetTransformDepthRel();
  const UInt uiDepth = rTu.GetTransformDepthTotal();
#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
  const Bool bDebugRQT=pcCU->getSlice()->getFinalized() && DebugOptionList::DebugRQT.getInt()!=0;
  if (bDebugRQT)
  {
    printf("x..codeTransform: offsetLuma=%d offsetChroma=%d absPartIdx=%d, uiDepth=%d\n width=%d, height=%d, uiTrIdx=%d, uiInnerQuadIdx=%d\n",
           rTu.getCoefficientOffset(COMPONENT_Y), rTu.getCoefficientOffset(COMPONENT_Cb), uiAbsPartIdx, uiDepth, rTu.getRect(COMPONENT_Y).width, rTu.getRect(COMPONENT_Y).height, rTu.GetTransformDepthRel(), rTu.GetSectionNumber());
  }
#endif
  const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) > uiTrIdx;// + pcCU->getDepth( uiAbsPartIdx ) > uiDepth;
  const UInt uiLog2TrafoSize = rTu.GetLog2LumaTrSize();


  UInt cbf[MAX_NUM_COMPONENT] = {0,0,0};
  Bool bHaveACodedBlock       = false;
  Bool bHaveACodedChromaBlock = false;

  for(UInt ch=0; ch<numValidComponent; ch++)
  {
    const ComponentID compID = ComponentID(ch);

    cbf[compID] = pcCU->getCbf( uiAbsPartIdx, compID , uiTrIdx );
    
    if (cbf[ch] != 0)
    {
      bHaveACodedBlock = true;
      if (isChroma(compID))
      {
        bHaveACodedChromaBlock = true;
      }
    }
  }

  if( pcCU->isIntra(uiAbsPartIdx) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
  {
    assert( uiSubdiv );
  }
  else if( pcCU->isInter(uiAbsPartIdx) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
  {
    if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
    {
      assert( uiSubdiv );
    }
    else
    {
      assert(!uiSubdiv );
    }
  }
  else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
  {
    assert( uiSubdiv );
  }
  else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
  {
    assert( !uiSubdiv );
  }
  else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
  {
    assert( !uiSubdiv );
  }
  else
  {
    assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
    m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize );
  }

  const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx );
  const Bool bFirstCbfOfCU = uiTrDepthCurr == 0;

  for(UInt ch=COMPONENT_Cb; ch<numValidComponent; ch++)
  {
    const ComponentID compID=ComponentID(ch);
    if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compID) )
    {
      if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) )
      {
        m_pcEntropyCoderIf->codeQtCbf( rTu, compID, (uiSubdiv == 0) );
      }
    }
    else
    {
      assert( pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) );
    }
  }

  if( uiSubdiv )
  {
    TComTURecurse tuRecurseChild(rTu, true);
    do
    {
      xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurseChild );
    } while (tuRecurseChild.nextSection(rTu));
  }
  else
  {
    {
      DTRACE_CABAC_VL( g_nSymbolCounter++ );
      DTRACE_CABAC_T( "\tTrIdx: abspart=" );
      DTRACE_CABAC_V( uiAbsPartIdx );
      DTRACE_CABAC_T( "\tdepth=" );
      DTRACE_CABAC_V( uiDepth );
      DTRACE_CABAC_T( "\ttrdepth=" );
      DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) );
      DTRACE_CABAC_T( "\n" );
    }

    if( !pcCU->isIntra(uiAbsPartIdx) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && (!bChroma || (!pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cb, 0 ) && !pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cr, 0 ) ) ) )
    {
      assert( pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, 0 ) );
      //      printf( "saved one bin! " );
    }
    else
    {
      m_pcEntropyCoderIf->codeQtCbf( rTu, COMPONENT_Y, true ); //luma CBF is always at the lowest level
    }

    if ( bHaveACodedBlock )
    {
      // dQP: only for CTU once
      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
      {
        if ( bCodeDQP )
        {
          encodeQP( pcCU, rTu.GetAbsPartIdxCU() );
          bCodeDQP = false;
        }
      }

      if ( pcCU->getSlice()->getUseChromaQpAdj() )
      {
        if ( bHaveACodedChromaBlock && codeChromaQpAdj && !pcCU->getCUTransquantBypass(rTu.GetAbsPartIdxCU()) )
        {
          encodeChromaQpAdjustment( pcCU, rTu.GetAbsPartIdxCU() );
          codeChromaQpAdj = false;
        }
      }

      const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();

      for(UInt ch=COMPONENT_Y; ch<numValidComp; ch++)
      {
        const ComponentID compID=ComponentID(ch);

        if (rTu.ProcessComponentSection(compID))
        {
#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
          if (bDebugRQT)
          {
            printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, rTu.getRect(compID).width, rTu.getRect(compID).height, 1);
          }
#endif

          if (rTu.getRect(compID).width != rTu.getRect(compID).height)
          {
            //code two sub-TUs
            TComTURecurse subTUIterator(rTu, false, TComTU::VERTICAL_SPLIT, true, compID);

            do
            {
              const UChar subTUCBF = pcCU->getCbf(subTUIterator.GetAbsPartIdxTU(compID), compID, (uiTrIdx + 1));

              if (subTUCBF != 0)
              {
#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
                if (bDebugRQT)
                {
                  printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, subTUIterator.getRect(compID).width, subTUIterator.getRect(compID).height, 1);
                }
#endif
                m_pcEntropyCoderIf->codeCoeffNxN( subTUIterator, (pcCU->getCoeff(compID) + subTUIterator.getCoefficientOffset(compID)), compID );
              }
            }
            while (subTUIterator.nextSection(rTu));
          }
          else
          {
            if (isChroma(compID) && (cbf[COMPONENT_Y] != 0))
            {
              m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID );
            }

            if (cbf[compID] != 0)
            {
              m_pcEntropyCoderIf->codeCoeffNxN( rTu, (pcCU->getCoeff(compID) + rTu.getCoefficientOffset(compID)), compID );
            }
          }
        }
      }
    }
  }
}
예제 #2
0
//index== 0 above 1 left 2 above and left 3 above and right
Int  GolombCode_Predict_SingleNeighbor(TComYuv *pcResiYuv, TComTU&     rTu, const ComponentID compID, UInt uiCUHandleAddr, UInt uiAIndex, TCoeff* pcCoeff)
{
	const Bool       bIsLuma = isLuma(compID);
	const TComRectangle &rect = rTu.getRect(compID);
	TComDataCU *pcCU = rTu.getCU();
	UInt  uiCUAddr = pcCU->getCtuRsAddr();

	//if  ((int)uiCUHandleAddr < 0)     return -1;

	TComPicYuv *pcPicYuvResi = pcCU->getPic()->getPicYuvResi();
	if (pcPicYuvResi == NULL)  return -1;
	const UInt uiAbsPartIdx = rTu.GetAbsPartIdxTU();
	//    const UInt  uiZOrder      = pcCU->getZorderIdxInCU() +uiAbsPartIdx;

	const UInt uiTrDepth = rTu.GetTransformDepthRelAdj(compID);
	const UInt uiFullDepth = rTu.GetTransformDepthTotal();
	const UInt uiLog2TrSize = rTu.GetLog2LumaTrSize();
	const ChromaFormat chFmt = pcCU->getPic()->getChromaFormat();

	const UInt    uiWidth = rect.width;
	const UInt    uiHeight = rect.height;
	const UInt    uiStride = pcResiYuv->getStride(compID);

	UInt   uiAddr = pcCU->getCtuRsAddr();

	TComYuv  *pcTemp;
	pcTemp = new TComYuv;
	UInt  uiSrc1Stride = pcPicYuvResi->getStride(compID);
	UInt  CUPelX, CUPelY;
	CUPelX = (uiCUHandleAddr % pcCU->getPic()->getFrameWidthInCtus()) * g_uiMaxCUWidth;
	CUPelY = (uiCUHandleAddr / pcCU->getPic()->getFrameWidthInCtus()) * g_uiMaxCUHeight;
	CUPelX = CUPelX + g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]];
	CUPelY = CUPelY + g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
	//for(int m=0;m<256;m++) cout<<g_auiZscanToRaster[m] <<" ";cout<<endl;
	//for(int m=0;m<256;m++) cout<<g_auiRasterToPelX[m] <<" ";cout<<endl;
	//for(int m=0;m<256;m++) cout<<g_auiRasterToPelY[m] <<" ";cout<<endl;
	//Pel *pSrc1 = pcPicYuvResi->getAddr(compID) +CUPelY * uiSrc1Stride + CUPelX;
	Pel  *pSrc1 = pcPicYuvResi->getAddr(compID, uiCUHandleAddr, uiAbsPartIdx + pcCU->getZorderIdxInCtu());
	/*       if( compID != COMPONENT_Y)
		   {
		   pSrc1 = pcPicYuvResi->getAddr(COMPONENT_Y, uiCUHandleAddr, uiAbsPartIdx + pcCU->getZorderIdxInCU());
		   }*/
	pcTemp->create(uiWidth, uiHeight, chFmt);
	//       pcTemp->copyFromPicComponent(compID,pcPicYuvResi,uiCUHandleAddr, pcCU->getZorderIdxInCU()+uiAbsPartIdx);

	UInt  uiTempStride = pcTemp->getStride(compID);
	Pel  *pTemp = pcTemp->getAddr(compID);
	for (Int y = 0; y < uiHeight; y++)
	{
		for (Int x = 0; x < uiWidth; x++)
		{
			pTemp[x] = pSrc1[x];
		}
		pTemp += uiTempStride;
		pSrc1 += uiSrc1Stride;
	}

	int srclx = 0; int srcly = 0; int srclv = 0;
	int srchasleft = 1;
	Pel  srcpel;
	int  srclist[3][64 * 64];
	int  srcindex = 0;
	memset(srclist, -1, 3 * 64 * 64 * sizeof(int));
	int cursrclistindex = 0;

	Pel*  piSrc = pcTemp->getAddr(compID);
	//Pel*  piSrc     = pcTemp->getAddr(compID, uiAbsPartIdx);
	Pel*  pSrc = piSrc;
	//found the source list
	while (srchasleft) {
		int ndis = 1000;
		int nx = -1; int ny = -1;
		pSrc = piSrc;
		for (UInt y = 0; y < uiHeight; y++) {
			for (UInt x = 0; x<uiWidth; x++) {
				assert(pSrc[x] >-256 && pSrc[x] < 256);
				if (pSrc[x] != 0) {
					int dis = 0;
					dis += getG0Bits((x - srclx));
					dis += getG0Bits((y - srcly));
					if (dis < ndis) {
						nx = x;
						ny = y;
						ndis = dis;
					}
				}
			}
			pSrc += uiTempStride;
		}
		if (nx != -1 && ny != -1) {
			srcpel = *(piSrc + ny*uiTempStride + nx);
			srclx = nx; srcly = ny; srclv = srcpel;
			srclist[0][srcindex] = srclx;
			srclist[1][srcindex] = srcly;
			srclist[2][srcindex] = srcpel;
			srcindex++;
			*(piSrc + ny*uiTempStride + nx) = 0;
		}
		else {
			srchasleft = 0;
		}
	}
	if (srcindex == 0)  {
		pcTemp->destroy();
		delete pcTemp;
		pcTemp = NULL;
		return -1;
	}
	////
	TComPicYuv *pcPicOrg = pcCU->getPic()->getPicYuvOrg();
	Pel*  piOrg = pcPicOrg->getAddr(compID, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu() + uiAbsPartIdx);
	const UInt   uiOrgStride = pcPicOrg->getStride(compID);
	////
	Pel*  piResi = pcResiYuv->getAddr(compID, uiAbsPartIdx);
	Pel*  pResi = piResi;
	int dstindex = 0;
	int  indexlist[64 * 64][5];
	memset(indexlist, 0, 5 * 64 * 64 * sizeof(int));
	int contz = 0;
	int contnz = 0;
	int cs = 0;
	int bits = 0;
	//        int temp;
	int lx = 0; int ly = 0; int lv = 0;
	int hasleft = 1;
	Pel  pel;

	while (hasleft) {
		//found the least distance point
		int ndis = 1000;
		int nx = -1; int ny = -1;
		pResi = piResi;
		for (UInt y = 0; y < uiHeight; y++) {
			for (UInt x = 0; x < uiWidth; x++) {
				if (pResi[x] != 0) {
					int dis = 0;
					dis += getG0Bits((x - lx));
					dis += getG0Bits((y - ly));
					if (dis < ndis) {
						nx = x;
						ny = y;
						ndis = dis;
					}
				}
			}
			pResi += uiStride;
		}
		if (nx != -1 && ny != -1) {
			pel = *(piResi + ny*uiStride + nx);

			int srcdis = 1024 * 4;
			int srccur = -1;
			for (UInt s = 0; s < srcindex; s++) {
				int curdis = 0;

				curdis += getG0Bits((nx - srclist[0][s]));
				curdis += getG0Bits((ny - srclist[1][s]));
				//                          curdis += getG0Bits( (pel-srclist[2][s]));// getG0Bits can handle -512 && 512

				if (curdis < srcdis) {
					srccur = s;
					srcdis = curdis;
				}
			}
			if (srccur != -1) {
				indexlist[dstindex][0] = nx - srclist[0][srccur];
				indexlist[dstindex][1] = ny - srclist[1][srccur];
				assert(pel != 0);

				indexlist[dstindex][4] = srccur;

				dstindex++;
				cursrclistindex = srccur;
			}
			else {
				assert(true);
			}
			lx = nx; ly = ny; lv = pel;
			*(piResi + ny*uiStride + nx) = 0;
		}
		else {
			hasleft = 0;
		}
	}

	pcTemp->destroy();
	delete pcTemp;
	pcTemp = NULL;

	if (dstindex == 0) {
		assert(bits == 0);
		return bits;
	}
	qsort(indexlist, dstindex, sizeof(int)* 5, compare5);

	for (UInt x = dstindex - 1; x > 0; x--) {
		indexlist[x][4] -= indexlist[x - 1][4];
	}

	//bits += getG0Bits( (indexlist[0][0]));
	//bits += getG0Bits( (indexlist[0][1]));

	int maxlength = 0;
	UInt truebits = 0;
	bool  vlcf[3] = { false, false, false };// dx & dy   residual  srcindex
	int z01 = 0;
	for (UInt x = 1; x < dstindex; x++) {
		if (indexlist[x][0] == indexlist[x - 1][0] && indexlist[x][1] == indexlist[x - 1][1]) {
			maxlength++;
		}
		else {
			bits += getG0Bits((maxlength));
			bits += getG0Bits((indexlist[x - 1][0]));
			bits += getG0Bits((indexlist[x - 1][1]));
			maxlength = 0;
		}
		if (indexlist[x][0] == 0 && indexlist[x][1] == 0) z01++;
	}

	bits += getG0Bits((maxlength));
	bits += getG0Bits((indexlist[dstindex - 1][0]));
	bits += getG0Bits((indexlist[dstindex - 1][1]));
	UInt sbits = 0;
	for (UInt x = 0; x < dstindex; x++) {
		sbits += getG0Bits((indexlist[x][0]));
		sbits += getG0Bits((indexlist[x][1]));
	}
	//   printf("gain %6d position before %6d after %6d\n",sbits-bits,sbits,bits);

	if (sbits < bits)  {
		vlcf[0] = true;
		bits = sbits;
	}

	sbits = bits + 1;
	//bits += getG0Bits( PTable(compID,indexlist[0][2]));
	{
		maxlength = 0;
		for (UInt x = 1; x < dstindex; x++) {
			if (indexlist[x][2] == indexlist[x - 1][2] && indexlist[x][3] == indexlist[x - 1][3]) {
				maxlength++;
			}
			else {
				bits += getG0Bits((maxlength));
				bits += getG0Bits(indexlist[x - 1][3]);

				bits += getG0Bits(indexlist[x - 1][2]);
				maxlength = 0;
			}
		}
		bits += getG0Bits((maxlength));
		bits += getG0Bits(indexlist[dstindex - 1][3]);
		bits += getG0Bits((indexlist[dstindex - 1][2]));
	}
	UInt vbits = 0;
	sbits = bits - sbits;
	for (UInt x = 0; x < dstindex; x++) {
		{
			vbits += getG0Bits(indexlist[x][2]);
			vbits += getG0Bits(indexlist[x][3]);
		}
	}
	//        printf("gain %6d delta resi before %6d after %6d\n",vbits-sbits,vbits,sbits);
	if (vbits < sbits) {
		vlcf[1] = true;
		bits = bits - sbits + vbits;
	}
	sbits = bits + 1;
	//bits += getG0Bits( (indexlist[0][3]));
	Int srcPosIndex;

	srcPosIndex = 4;

	maxlength = 0;

	for (UInt x = 1; x < dstindex; x++) {
		if (indexlist[x][srcPosIndex] == indexlist[x - 1][srcPosIndex]) {
			maxlength++;
		}
		else {
			bits += getG0Bits((maxlength));
			bits += getG0Bits((indexlist[x - 1][srcPosIndex]));
			maxlength = 0;
		}
	}

	bits += getG0Bits((maxlength));
	bits += getG0Bits((indexlist[dstindex - 1][srcPosIndex]));

	sbits = bits - sbits;
	vbits = 0;
	for (UInt x = 0; x < dstindex; x++) {
		vbits += getG0Bits((indexlist[x][srcPosIndex]));
	}
	//        printf("gain %6d delta index before %6d after %6d\n",vbits-sbits,vbits,sbits);
	if (vbits < sbits) {
		vlcf[2] = true;
		bits = bits - sbits + vbits;
	}
	//#if INTRA_PR_DEBUG
	//        if( pcCU->getAddr()==INTRA_PR_CUNUM )
	//            printf("position distance zero  %6d of %6d  total bits %6d\n",z01,dstindex,bits+1);
	//#endif
	truebits = 0;
	ExpGolombEncode(uiAIndex, pcCoeff, truebits);
	//--------------encode  srcindex

	if (vlcf[2]) {
		ExpGolombEncode(0, pcCoeff, truebits);
		for (UInt x = 0; x < dstindex; x++) {
			//cout<<"  "<<indexlist[x][3]  ;
			ExpGolombEncode((indexlist[x][srcPosIndex]), pcCoeff, truebits);
		}
	}
	else{
		ExpGolombEncode(1, pcCoeff, truebits);
		maxlength = 0;
		for (UInt x = 1; x<dstindex; x++) {
			if (indexlist[x][srcPosIndex] == indexlist[x - 1][srcPosIndex]) {
				maxlength++;
			}
			else {
				ExpGolombEncode((maxlength), pcCoeff, truebits);
				ExpGolombEncode((indexlist[x - 1][srcPosIndex]), pcCoeff, truebits);
				maxlength = 0;
			}
		}
		assert(maxlength>-1);
		ExpGolombEncode((maxlength), pcCoeff, truebits);
		ExpGolombEncode((indexlist[dstindex - 1][srcPosIndex]), pcCoeff, truebits);
	}
	ExpGolombEncode(-1, pcCoeff, truebits);
	//---------------encode  residual

	if (vlcf[1]) {
		ExpGolombEncode(0, pcCoeff, truebits);
		for (UInt x = 0; x < dstindex; x++) {
			{
				ExpGolombEncode(indexlist[x][2], pcCoeff, truebits);
				//  if( !bNoResidual)
				//      ExpGolombEncode( indexlist[x][3],pcCoeff,truebits);
			}
		}
	}
	else{
		ExpGolombEncode(1, pcCoeff, truebits);
		//ExpGolombEncode( (indexlist[0][2]),pcCoeff,truebits);
		maxlength = 0;
		{
			for (UInt x = 1; x < dstindex; x++) {
				if (indexlist[x][2] == indexlist[x - 1][2] && indexlist[x][3] == indexlist[x - 1][3]) {
					maxlength++;
				}
				else {
					ExpGolombEncode((maxlength), pcCoeff, truebits);
					//assert( (maxlength)>=0);
					ExpGolombEncode(indexlist[x - 1][2], pcCoeff, truebits);
					//   if( !bNoResidual)
					//       ExpGolombEncode( indexlist[x-1][3],pcCoeff,truebits);

					maxlength = 0;
				}
			}
			ExpGolombEncode((maxlength), pcCoeff, truebits);
			ExpGolombEncode(indexlist[dstindex - 1][2], pcCoeff, truebits);
			//if( !bNoResidual)
			//    ExpGolombEncode( indexlist[dstindex-1][3] , pcCoeff, truebits);
		}
	}
	//--------------encode dx and dy -----------
	if (vlcf[0])  {
		ExpGolombEncode(0, pcCoeff, truebits);
		for (UInt x = 0; x < dstindex; x++) {
			ExpGolombEncode((indexlist[x][0]), pcCoeff, truebits);
			ExpGolombEncode((indexlist[x][1]), pcCoeff, truebits);
		}
	}
	else{
		ExpGolombEncode(1, pcCoeff, truebits);
		//ExpGolombEncode( (indexlist[0][0]),pcCoeff,truebits);
		//ExpGolombEncode( (indexlist[0][1]),pcCoeff,truebits);

		maxlength = 0;

		for (UInt x = 1; x < dstindex; x++) {
			if (indexlist[x][0] == indexlist[x - 1][0] && indexlist[x][1] == indexlist[x - 1][1]) {
				maxlength++;
			}
			else {
				ExpGolombEncode((maxlength), pcCoeff, truebits);
				ExpGolombEncode((indexlist[x - 1][0]), pcCoeff, truebits);
				ExpGolombEncode((indexlist[x - 1][1]), pcCoeff, truebits);
				maxlength = 0;
			}
		}
		ExpGolombEncode((maxlength), pcCoeff, truebits);
		ExpGolombEncode((indexlist[dstindex - 1][0]), pcCoeff, truebits);
		ExpGolombEncode((indexlist[dstindex - 1][1]), pcCoeff, truebits);
	}
	return   truebits;/* bits +1*/;
}