⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filebitstreamreaderagent.cpp

📁 jpeg 2000 压缩算法源代码 核心ebcot
💻 CPP
字号:
double CEBCOTRateAllocator::OptimizeBitstreamLayer(int nLayerNumber, double fMaxSThresh, int nMaxBytes, int nPrevBytes)
{
	double fSlopeThresh;


	//在估计该层的Slope之前,应先保存packetencoder的状态;
	m_pPktEncoder->Save();

	double fMinSlope;

	//根据m_pnRDSlopesRates所包含的单纯的码块压缩码流信息,进行slope的估计;


	int sidx;

	for (sidx=RD_SUMMARY_SIZE-1;sidx>0;sidx--)
	{
		if (m_pnRDSlopesRates[sidx]>=nMaxBytes)
			break;
	}

	fMinSlope=GetSlopeFromSIndex(sidx);

	if (fMinSlope>=fMaxSThresh)
	{
		sidx--;
		if (sidx<0)
			fMinSlope=0;
		else
		{
			fMinSlope=GetSlopeFromSIndex(sidx);
		}
	}

	fSlopeThresh=(fMinSlope+fMaxSThresh)/2;

	if (fSlopeThresh<=fMinSlope)
		fSlopeThresh=fMaxSThresh;

	int nActualBytes;
	
	int nTileNums,nComNums;
	nTileNums=m_pCodedImgBlkData->GetTileNums();
	nComNums=m_pCodedImgBlkData->GetImgComNums();


	int nTileNumber,nComNumber;
	int r;
	int nPrecIndex;
	bool bPktEncoder=false;
	bool bSOPUsed,bEPHUsed;
	int nPrecNums;

//	int s,startSIdx,endSIdx;


	do 
	{
		nActualBytes=nPrevBytes;

		for (nTileNumber=0;nTileNumber<nTileNums;nTileNumber++)
			for (nComNumber=0;nComNumber<nComNums;nComNumber++)
			{
				bSOPUsed=pEncoderSpec->pSOPUsed->GetTileDef(nTileNumber);
				bEPHUsed=pEncoderSpec->pEPHUsed->GetTileDef(nTileNumber);


				for (r=0;r<m_pnMrl[nTileNumber][nComNumber];r++)
				{
					nPrecNums=m_pPrecNums[nTileNumber][nComNumber][r].m_nX*m_pPrecNums[nTileNumber][nComNumber][r].m_nY;

				
						for (nPrecIndex=0;nPrecIndex<nPrecNums;nPrecIndex++)
						{
						    FindTruncIndex(nLayerNumber,nTileNumber,nComNumber,r,nPrecIndex,fSlopeThresh);
		
						    bPktEncoder=m_pPktEncoder->EncodePacket(nLayerNumber+1,nComNumber,nTileNumber,r,nPrecIndex,m_pBlkRateDistStats[nTileNumber][nComNumber][r],m_pnTruncIndex[nTileNumber][nLayerNumber][nComNumber][r]);

						    nActualBytes+=m_pPktEncoder->GetCurPktBodyLenth();
						    nActualBytes+=m_pPktEncoder->GetCurPktHeaderBuf()->GetValidBLenth();

						    if (bSOPUsed)
							    nActualBytes+=CMarkers::SOP_LENGTH;
						    if (bEPHUsed)
							    nActualBytes+=CMarkers::EPH_LENGTH;
						}


					


				}

			}

			if (nActualBytes>nMaxBytes)
			{
				fMinSlope=fSlopeThresh;
			}
			else
			{
				fMaxSThresh=fSlopeThresh;
			}

			fSlopeThresh=(fMinSlope+fMaxSThresh)/2;

			m_pPktEncoder->Restore();



	}while((fSlopeThresh<fMaxSThresh*(1.0-FLOAT_REL_PRECISION))&&(fSlopeThresh<(fMaxSThresh-FLOAT_ABS_PRECISION)));
	

	if (fSlopeThresh<=FLOAT_ABS_PRECISION)
		fSlopeThresh=0;
	else
		fSlopeThresh=fMaxSThresh;
	
	return fSlopeThresh;



}

void CEBCOTRateAllocator::FindTruncIndex(int nLayerNumber, int nTileNumber, int nComNumber, int r, int nPrecIndex, double fSThresh)
{
	int startSIdx,endSIdx,s;

	startSIdx=1;
	endSIdx=3;

	if (r==0)
	{
		startSIdx=0;
		endSIdx=0;

	}

	int *pnCBlkInPrec=0;
	int nBlkInPrecNums;
	int nBlkNumber,nBlkIdx;
	CBlkRateDistStats *pBlkRateDistStats=0;
	int n;

	for (s=startSIdx;s<=endSIdx;s++)
	{
								
		pnCBlkInPrec=m_pPktEncoder->GetBlkInPrec(nTileNumber,nComNumber,r,s,nPrecIndex);

		if (pnCBlkInPrec)
		{
			nBlkInPrecNums=pnCBlkInPrec[0];

			for (nBlkIdx=3;nBlkIdx<(nBlkInPrecNums+3);nBlkIdx++)
			{
		        nBlkNumber=pnCBlkInPrec[nBlkIdx];
				pBlkRateDistStats=m_pBlkRateDistStats[nTileNumber][nComNumber][r][s][nBlkNumber];

				for (n=0;n<pBlkRateDistStats->m_nVldTrunc;n++)
				{
					if (pBlkRateDistStats->m_pTruncSlopes[n]<fSThresh)
						break;
				}

			  
				m_pnTruncIndex[nTileNumber][nLayerNumber][nComNumber][r][s][nBlkNumber]=n-1;


			}


		}
		
		delete []pnCBlkInPrec;
		pnCBlkInPrec=0;

	}

}

double CEBCOTRateAllocator::EstimateLayerThreshold(int nTargetBytes, CEBCOTLayer &LastLayer)
{
	double fSlopeThresh;

	double flog_sl1,flog_sl2;
	double flog_len1,flog_len2;
	double flog_isl;
	double flog_ilen;
	double flog_lab;
	int nSIdx;
	double flog_off;
	double flthresh;
	int nlab=LastLayer.m_nActualBytes;
	int tlen;
	

	flthresh=LastLayer.m_fRDThreshold;
	if (flthresh>m_fMaxSlope)
		flthresh=m_fMaxSlope;
	if (flthresh<FLOAT_ABS_PRECISION)
		return 0;
	
	nSIdx=GetLimitedSIndexFromSlope(flthresh);

	if (nSIdx>=RD_SUMMARY_SIZE-1)
		nSIdx=RD_SUMMARY_SIZE-2;

	if (m_pnRDSlopesRates[nSIdx+1]==0)
	{
		flog_len1=log((m_pnRDSlopesRates[nSIdx]<<1)+1);
		flog_len2=log(m_pnRDSlopesRates[nSIdx]+1);
		flog_lab=log(nlab+m_pnRDSlopesRates[nSIdx]+1);

	}
	else
	{
		flog_len1=log(m_pnRDSlopesRates[nSIdx]);
		flog_len2=log(m_pnRDSlopesRates[nSIdx+1]);
		flog_lab=log(nlab);
	}

	flog_sl1=log(GetSlopeFromSIndex(nSIdx));
	flog_sl2=log(GetSlopeFromSIndex(nSIdx+1));

	flog_isl=log(flthresh);

	flog_ilen=flog_len1+(flog_isl-flog_sl1)*(flog_len1-flog_len2)/(flog_sl1-flog_sl2);

	flog_off=flog_lab-flog_ilen;

	tlen=(int)(nTargetBytes/exp(flog_off));

	for (nSIdx=RD_SUMMARY_SIZE-1;nSIdx>0;nSIdx--)
	{
		if (m_pnRDSlopesRates[nSIdx]>=tlen)
			break;
	}
	nSIdx++;

	if (nSIdx>=RD_SUMMARY_SIZE)
		nSIdx=RD_SUMMARY_SIZE-1;
	
	if (nSIdx<=0)
		nSIdx=1;

	if (m_pnRDSlopesRates[nSIdx]==0)
	{
		flog_len1=log(m_pnRDSlopesRates[nSIdx-1]+1);
		flog_len2=log((m_pnRDSlopesRates[nSIdx-1]<<1)+1);
		flog_lab=log(tlen+m_pnRDSlopesRates[nSIdx-1]+1);

	}
	else
	{
		flog_len1=log(m_pnRDSlopesRates[nSIdx]);
		flog_len2=log(m_pnRDSlopesRates[nSIdx-1]);
		flog_lab=log(tlen);

	}

	flog_sl1=log(GetSlopeFromSIndex(nSIdx));
	flog_sl2=log(GetSlopeFromSIndex(nSIdx-1));

	flog_isl=flog_sl1+(flog_ilen-flog_len1)*(flog_sl1-flog_sl2)/(flog_len1-flog_len2);

	fSlopeThresh=exp(flog_isl);

	if (fSlopeThresh>flthresh)
		fSlopeThresh=flthresh;
	if (fSlopeThresh<FLOAT_ABS_PRECISION)
		fSlopeThresh=0;
	
	return fSlopeThresh;


	

 




}

void CEBCOTRateAllocator::BuildandWriteLayers()
{

	int nMaxBytes,nActualBytes,nPakcetBytes=0;

	int nLayerNumber;

	double fRDThresh=m_fMaxSlope;

	int nTileNums,nComNums;
	nTileNums=m_pCodedImgBlkData->GetTileNums();
	nComNums=m_pCodedImgBlkData->GetImgComNums();


	int *pnTileLength=new int[nTileNums];

	int nTileNumber,nComNumber;

	for (nTileNumber=0;nTileNumber<nTileNums;nTileNumber++)
	{
		pnTileLength[nTileNumber]=0;
	}

	bool bSOPUsed,bEPHUsed;
	int r;
	int startSIdx,endSIdx;
	int nPrecIndex,nPrecNums;
	int ntmp=0;
	bool bPktEncoder;

	nActualBytes=0;


	/*-------------------------------------------------
	 *       估计每一层的截断点门限和每一层的字节数   *
	--------------------------------------------------*/
	for (nLayerNumber=0;nLayerNumber<m_nLayerNums;nLayerNumber++)
	{
		nMaxBytes=m_pEBCOTLayer[nLayerNumber].m_nMaxBytes;
		if (m_pEBCOTLayer[nLayerNumber].m_bOptimize)
			fRDThresh=OptimizeBitstreamLayer(nLayerNumber,fRDThresh,nMaxBytes,nActualBytes);
		else
			fRDThresh=EstimateLayerThreshold(nMaxBytes,m_pEBCOTLayer[nLayerNumber-1]);

		for (nTileNumber=0;nTileNumber<nTileNums;nTileNumber++)
		{
			if (nLayerNumber==0)
			{
				CHeaderEncoder *pp=m_pHeadEncoder;
				m_pHeadEncoder->Reset();

				m_pHeadEncoder->WriteTilePartHeader(0,nTileNumber);

				pnTileLength[nTileNumber]+=m_pHeadEncoder->GetBufferLength();
				
			}

			for (nComNumber=0;nComNumber<nComNums;nComNumber++)
			{
				bSOPUsed=pEncoderSpec->pSOPUsed->GetTileComVal(nTileNumber,nComNumber);

				bEPHUsed=pEncoderSpec->pEPHUsed->GetTileComVal(nTileNumber,nComNumber);

			    for (r=0;r<m_pnMrl[nTileNumber][nComNumber];r++)
				{
					nPrecNums=m_pPrecNums[nTileNumber][nComNumber][r].m_nX*m_pPrecNums[nTileNumber][nComNumber][r].m_nY;

					startSIdx=1;
					endSIdx=3;

					if (r==0)
					{
						startSIdx=0;
						endSIdx=0;
					}

				

						for (nPrecIndex=0;nPrecIndex<nPrecNums;nPrecIndex++)
						{
						    FindTruncIndex(nLayerNumber,nTileNumber,nComNumber,r,nPrecIndex,fRDThresh);
		
						    bPktEncoder=m_pPktEncoder->EncodePacket(nLayerNumber+1,nComNumber,nTileNumber,r,nPrecIndex,m_pBlkRateDistStats[nTileNumber][nComNumber][r],m_pnTruncIndex[nTileNumber][nLayerNumber][nComNumber][r]);

						    ntmp=m_pPktEncoder->GetCurPktBodyLenth();
						    ntmp+=m_pPktEncoder->GetCurPktHeaderBuf()->GetValidBLenth();

						    if (bSOPUsed)
							    ntmp+=CMarkers::SOP_LENGTH;
						    if (bEPHUsed)
							    ntmp+=CMarkers::EPH_LENGTH;

							nActualBytes+=ntmp;
							pnTileLength[nTileNumber]+=ntmp;
						}


				}

			}
		}
      m_pEBCOTLayer[nLayerNumber].m_fRDThreshold=fRDThresh;

      m_pEBCOTLayer[nLayerNumber].m_nActualBytes=nActualBytes;

	}



	/*-----------------------------------------------------------
	 *   根据上面所得到的每一层的截断点以及编码参数progression, *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -