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

📄 hyperspectralimagcode.cpp

📁 改进的JPEG-LS算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		//累计总的码流比特数
		BitPerPixel+=CodeBit_cp;
		//计算当前压缩块总字节数
		*((int *)lpAuxData)=AuxData_cp+(CodeBit_cp>>3)+((CodeBit_cp&7)?1:0);
		//保存当前压缩块信息头
		AppendDataToFile(lpAuxData,AuxData_cp);
		//保存当前压缩块码流
		AppendDataToFile(lpCodeStreamBuf,(CodeBit_cp>>3)+((CodeBit_cp&7)?1:0));
		ClearCodeStreamBuf();
	}
	//计算压缩误差的均方值
	ErrMse/=(Height*Width*BandNumber);
	//计算单象素比特值
	BitPerPixel/=(Height*Width*BandNumber);
	delete lpImageData;
	delete lpAuxData;
	if(lpErrMsePerPixel!=NULL)*lpErrMsePerPixel=ErrMse;
	if(lpBitPerPixel!=NULL)*lpBitPerPixel=BitPerPixel;
}
void CHyperspectralImageCode::WriteDataToFile(void *lpBuf,int Bytes)
{
	CFile f;
	if(f.Open((LPCTSTR)CompressFile,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary)==TRUE)
	{
		f.Write(lpBuf,Bytes);
		f.Close();
	}
}

void CHyperspectralImageCode::AppendDataToFile(void *lpBuf,int Bytes)
{
	CFile f;
	if(f.Open((LPCTSTR)CompressFile,CFile::modeReadWrite|CFile::typeBinary)==TRUE)
	{
		f.SeekToEnd();
		f.Write(lpBuf,Bytes);
		f.Close();
	}
}
//加载压缩码流
BOOL CHyperspectralImageCode::LoadCompressBitStream(LPCTSTR CompressFile)
{//将压缩文件映射到内存、获取存放于压缩头的控制数据,获取第一个压缩块的指针。
	LPBYTE lpCS;
	int i=::GetFileLength(CompressFile);//取得完整高光谱压缩数据长度
	if(CMF.CreateFileMap(CompressFile,//创建文件映射内存
						PAGE_READONLY,
						i,
						NULL,
						OPEN_ALWAYS)!=NULL)
	{
		lpCS=(LPBYTE)CMF.MapOfFile(0,i);//获取映射文件内存指针
		HyperspectralDataFormat=lpCS[0];//格式字节
		BandNumber=*((short int *)(lpCS+1));//波段数
		if((lpCS[0]==BSQ_H||lpCS[0]==BIP_H||lpCS[0]==BIL_H||lpCS[0]==BFILE)&&(BandNumber>0&&BandNumber<=MAXBANDNUMBER))
		{//如果是指定的四种格式
			Width=*((short int *)(lpCS+3));//图像宽度
			Height=*((short int *)(lpCS+5));//图像高度
			if(HyperspectralDataFormat==BFILE)
			{//纯图像格式时
				OnePixelBits=*((char *)(lpCS+7));//单象素字节数
				OnePixelBytes=*((char *)(lpCS+8));//单象素数比特数
				if(lpPredictTable!=NULL)delete lpPredictTable;
				lpPredictTable=new short int[BandNumber];
				MoveMemory(lpPredictTable,lpCS+9,BandNumber*sizeof(short int));//以短整数形式存放的预测波段配置表
				lpBlockHead=lpCS+9+BandNumber*sizeof(short int);//压缩数据块头
				OneLineAuxDataWidth=0;//每行图像的辅助数据
			}
			else 
			{//OMIS高光谱图像数据存放格式
				if(lpPredictTable!=NULL)delete lpPredictTable;
				lpPredictTable=new short int[BandNumber];
				MoveMemory(lpPredictTable,lpCS+7,BandNumber*sizeof(short int));//以短整数形式存放的预测波段配置表
				lpHead=(stAuxMsg *)(lpCS+7+BandNumber*sizeof(short int));//高光谱数据的格式头
				//压缩块数据头的起始位置
				lpBlockHead=lpCS+7+BandNumber*sizeof(short int)+sizeof(stAuxMsg)+lpHead->stLineAuxDataInfo.ladHeight*lpHead->stLineAuxDataInfo.ladWidth;
				//由高光谱数据头设置部分与压缩有关的变量
				HImageBand=lpHead->iImageBand;//波段数
				HImageWidth=lpHead->iImageWidth;//高光谱数据宽度
				Height=HImageHeight=lpHead->iImageHeight;//高光谱数据高度
				OnePixelBits=HBitPerPixel=lpHead->iBitPerPixel;//每象素比特数
				HDataStartPosition=lpHead->iDataStartPosition;//高光谱数据在文件中的实际位置
				OneLineAuxDataWidth=HImageWidth-Width;
				if(OnePixelBits<=8)OnePixelBytes=1;//由象素比特数产生单象素字节数
				else OnePixelBytes=2;
			}
			return TRUE;
		}
		else
		{
			CMF.Close();
			return FALSE;
		}
	}
	return FALSE;
}
//准备压缩图像缓冲
BOOL CHyperspectralImageCode::PrepareConstructionImageBuf(LPCTSTR lpHyperspectralImageFile)
{//为高光谱重建图像准备缓冲
	LPBYTE lpHpic;
	int i;
	DeleteFile(lpHyperspectralImageFile);
	i=sizeof(stAuxMsg)+lpHead->stLineAuxDataInfo.ladHeight*lpHead->stLineAuxDataInfo.ladWidth+
		HImageWidth*HImageHeight*HImageBand*OnePixelBytes;//缓冲区总长度
	if(HMF.CreateFileMap(lpHyperspectralImageFile,//创建文件映射内存
						PAGE_READWRITE,
						i,
						NULL,
						OPEN_ALWAYS)!=NULL)
	{
		lpHpic=(LPBYTE)HMF.MapOfFile(0,i);
		//高光谱数据格式头
		MoveMemory(lpHpic,lpHead,sizeof(stAuxMsg)+lpHead->stLineAuxDataInfo.ladHeight*lpHead->stLineAuxDataInfo.ladWidth);
		//高光谱数据指针
		lpImageData=lpHpic+sizeof(stAuxMsg)+lpHead->stLineAuxDataInfo.ladHeight*lpHead->stLineAuxDataInfo.ladWidth;
		return TRUE;
	}
	return FALSE;
}
BOOL CHyperspectralImageCode::PrepareConstructionImageBuf(LPCTSTR *lpBandImageFile)
{//为单波段纯图像方式保存高光谱重建成图像准备缓冲
	int i,l;
	lpIMF=new CMapFile *[BandNumber];//创建映射文件表
	for(i=0;i<BandNumber;i++)
	{
		lpIMF[i]=new CMapFile;
	}
	lpImageIndex=new LPBYTE[BandNumber];//创建各波段数据指针表
	l=Width*Height*OnePixelBytes;
	for(i=0;i<BandNumber;i++)
	{
		DeleteFile(lpBandImageFile[i]);
		if(lpIMF[i]->CreateFileMap(lpBandImageFile[i],
									PAGE_READWRITE,
									l,
									NULL,
									OPEN_ALWAYS)!=NULL)
		{
			lpImageIndex[i]=(LPBYTE)lpIMF[i]->MapOfFile(0,l);//从映射文件中获得数据指针表
		}
		else break;
	}
	if(i<BandNumber)
	{//若其中有文件映射失败,清理已创建的对象.
		for(i=0;i<BandNumber;i++)
		{
			delete lpIMF[i];
		}
		delete lpIMF;lpIMF=NULL;
		delete lpImageIndex;lpImageIndex=NULL;
		return FALSE;
	}
	return TRUE;
}
//设置一行重建图像数据
void CHyperspectralImageCode::SetOneLineImageData(LPBYTE lpOneLineBuf,int Band,int Line)
{
	LPBYTE lpLineData;
	int i,j;
	if(HyperspectralDataFormat==BFILE)//纯图像格式
	{
		MoveMemory(lpImageIndex[Band]+Line*Width*OnePixelBytes,lpOneLineBuf,Width*OnePixelBytes);
	}
	else if(HyperspectralDataFormat==BSQ_H)//BSQ_H图像格式
	{
		MoveMemory(lpImageData+(Band*HImageWidth*HImageHeight*OnePixelBytes)+(Line*HImageWidth*OnePixelBytes),
					lpOneLineBuf,
					Width*OnePixelBytes);
	}
	else if(HyperspectralDataFormat==BSQ_H)//BIL_H图像格式
	{
		MoveMemory(lpImageData+(Line*HImageWidth*HImageBand*OnePixelBytes)+(Band*HImageWidth*OnePixelBytes),
					lpOneLineBuf,
					Width*OnePixelBytes);
	}
	else if(HyperspectralDataFormat==BIP_H)//BIP_H图像格式
	{
		lpLineData=lpImageData+(Line*HImageWidth*HImageBand*OnePixelBytes);
		//须按波段间隔采样才能得到单一波段连续一行的数据。
		if(OnePixelBytes==1)
		{
			for(i=0,j=Band;i<Width;i++,j+=HImageBand)
			{
				lpLineData[j]=lpOneLineBuf[i];
			}
		}
		else
		{
			for(i=0,j=Band;i<Width;i++,j+=HImageBand)
			{
				*(((short int *)lpLineData)+j)=*(((short int *)lpOneLineBuf)+i);
			}
		}
	}
}
//设置一行辅助数据
int CHyperspectralImageCode::SetOneLineAuxData(LPBYTE lpOneLineBuf,int Band,int Line)
{
	if(HyperspectralDataFormat==BSQ_H)//BSQ_H图像格式
	{
		MoveMemory(lpImageData+(Band*HImageWidth*HImageHeight*OnePixelBytes)+(Line*HImageWidth*OnePixelBytes)+Width*OnePixelBytes,
					lpOneLineBuf,
					OneLineAuxDataWidth*OnePixelBytes);
		return OneLineAuxDataWidth*OnePixelBytes;
	}
	else if(HyperspectralDataFormat==BSQ_H)//BIL_H图像格式
	{
		MoveMemory(lpImageData+(Line*HImageWidth*HImageBand*OnePixelBytes)+(Band*HImageWidth*OnePixelBytes)+Width*OnePixelBytes,
					lpOneLineBuf,
					OneLineAuxDataWidth*OnePixelBytes);
		return OneLineAuxDataWidth*OnePixelBytes;
	}
	return 0;
}
//完成解压缩全过程
void CHyperspectralImageCode::DoUnCompress()
{
	/*
			a、建立解压缩块循环。
				b、取得压缩块信息头。
				c、建立图像行循环
					d、建立波段循环
						e、解压缩取某行某波段数据
						f、保存该行该波段数据。
					g、下一个波段。
				h、下一个图像行
			j、下一个压缩图像块
	*/
	int Line,i,j,LineBG,LineN,AuxData_L,AuxData_cp,CodeBit_cp,Block_L,AllowMaxErr;
	LPBYTE lpImageData=new BYTE[Width*OnePixelBytes+4];
	//执行压缩循环
	for(Line=0;Line<Height;)
	{//这是块循环层
		Block_L=*((int *)lpBlockHead);
		AuxData_L=LoadBlockCompressHead(lpBlockHead,AllowMaxErr,LineBG,LineN);
		AuxData_cp=9;
		AllowMaxError=AllowMaxErr;
		lpCodeStreamBuf=lpBlockHead+AuxData_L;
		for(i=0;i<BandNumber;i++)
		{//各波段编码器复位
			lpCompressUnit[i]->InitialisationsCode(OnePixelBits,AllowMaxError);
		}
		CodeBit_cp=0;
		for(j=0;j<LineN;j++)
		{
			for(i=0;i<BandNumber;i++)
			{
				//解压缩当前行图像,码流指针以比特为单位
				CodeBit_cp+=lpCompressUnit[i]->DoDecodeLine(lpImageData,
															OnePixelBytes,
															lpCodeStreamBuf,
															CodeBit_cp);
				//保存当前行图像数据
				SetOneLineImageData(lpImageData,i,j+LineBG);
				//保当前行辅助数据
				AuxData_cp+=SetOneLineAuxData(lpBlockHead+AuxData_cp,i,j+LineBG);
			}
		}
		Line+=LineN;
		//块指针指向下一块
		lpBlockHead+=Block_L;
	}
	delete lpImageData;
}

//含预测的多波段图像压缩实例
BOOL HyperspectralImageCompress(LPCTSTR lpHyperspectralImageFile,
								LPCTSTR lpPredictBandConfig,
								LPCTSTR CompressFile,
								int AllowMaxError,
								int LinesPerBlock,
								int OneLineImageAuxDataL,
								double *lpErrMsePerPixel,
								double *lpBitPerPixel)
{//针对具有高光谱数据格式信息的单一高光谱数据文件
	CHyperspectralImageCode HEncode;
//		1、加载高光谱数据。
			
//			  a、支持三种形式的高光谱数据文件格式(BSQ_H、BIP_H、BIL_H)及各波段独立文件格式。
//			  b、从格式文件的头部获取数据各类参数,独立文件形式必须输入压缩所需格式信息。
//			  c、配置预测波段。(配置信息来自预先的设定)
	if(HEncode.LoadHyperspectralImageFile(lpHyperspectralImageFile,OneLineImageAuxDataL)==FALSE)
		return FALSE;
	HEncode.LoadPredictTable(lpPredictBandConfig);
//		2、为各波段创建编码器。

//			a、编码器实际上是用来独立保存各波段编码的上下文信息(包括波段预测所需上下文)。
//			b、创建的同时要根据单波段相关参数及预测配置初始化编码器。
	
	HEncode.CreatCompressObject();

//		3、为压缩码流准备缓冲区及存放文件。(缓冲区大小取决于压缩图像块的大小)

	HEncode.PrepareCodeStreamBuf(LinesPerBlock,CompressFile);

//		4、执行压缩循环

	HEncode.DoCompress(AllowMaxError,lpErrMsePerPixel,lpBitPerPixel);

//		5、释放码流及各波段编码器缓冲区。
	
	HEncode.EndHyperspectralCode();

	return TRUE;
}
BOOL HyperspectralImageCompress(LPCTSTR *lpHyperspectralImageFile,
								LPCTSTR lpPredictBandConfig,
								LPCTSTR CompressFile,
								int BandNumber,
								int Height,
								int Width,
								int BitsPerPixel,
								int BytesPerPixel,
								int AllowMaxError,
								int LinesPerBlock,
								double *lpErrMsePerPixel,
								double *lpBitPerPixel)
{//针对以单波段纯图像文件存放的高谱数据
	CHyperspectralImageCode HEncode;
//		1、加载高光谱数据。
			
//			  a、支持三种形式的高光谱数据文件格式(BSQ_H、BIP_H、BIL_H)及各波段独立文件格式。
//			  b、从格式文件的头部获取数据各类参数,独立文件形式必须输入压缩所需格式信息。
//			  c、配置预测波段。(配置信息来自预先的设定)
	if(HEncode.LoadHyperspectralImageFile(lpHyperspectralImageFile,
											BandNumber,
											Height,
											Width,
											BytesPerPixel,
											BitsPerPixel)==FALSE)
		return FALSE;

	HEncode.LoadPredictTable(lpPredictBandConfig);
//		2、为各波段创建编码器。

//			a、编码器实际上是用来独立保存各波段编码的上下文信息(包括波段预测所需上下文)。
//			b、创建的同时要根据单波段相关参数及预测配置初始化编码器。
	
	HEncode.CreatCompressObject();

//		3、为压缩码流准备缓冲区及存放文件。(缓冲区大小取决于压缩图像块的大小)

	HEncode.PrepareCodeStreamBuf(LinesPerBlock,CompressFile);

//		4、执行压缩循环

	HEncode.DoCompress(AllowMaxError,lpErrMsePerPixel,lpBitPerPixel);

//		5、释放码流及各波段编码器缓冲区。
	
	HEncode.EndHyperspectralCode();

	return TRUE;
}
//含预测的多波段图像解压缩实例
BOOL HyperspectralImageUnCompress(LPCTSTR lpHyperspectralImageFile,
									LPCTSTR CompressFile)
{//重建单一高谱数据文件,如果压缩时是单波段纯图像,重建时用BSQ_H格式
	CHyperspectralImageCode HDecode;
//		1、加载高光谱压缩码流。
			
	if(HDecode.LoadCompressBitStream(CompressFile)==FALSE)
		return FALSE;
	if(HDecode.HyperspectralDataFormat==BFILE)return FALSE;

	//为重建图像准备缓冲
	if(HDecode.PrepareConstructionImageBuf(lpHyperspectralImageFile)==FALSE)return FALSE;
//		2、为各波段创建解码器。

	HDecode.CreatCompressObject();

//		4、执行解压缩循环

	HDecode.DoUnCompress();

//		5、释放码流及各波段编码器缓冲区。
	
	HDecode.EndHyperspectralCode();

	return TRUE;
}

BOOL HyperspectralImageUnCompress(LPCTSTR *lpHyperspectralImageFile,
									LPCTSTR CompressFile)
{//重建单波段纯图像数据
	CHyperspectralImageCode HDecode;
//		1、加载高光谱压缩码流。
			
	if(HDecode.LoadCompressBitStream(CompressFile)==FALSE)
		return FALSE;
	//为重建图像准备缓冲
	if(HDecode.PrepareConstructionImageBuf(lpHyperspectralImageFile)==FALSE)return FALSE;
//		2、为各波段创建解码器。

	HDecode.CreatCompressObject();

//		4、执行解压缩循环

	HDecode.DoUnCompress();

//		5、释放码流及各波段编码器缓冲区。
	
	HDecode.EndHyperspectralCode();

	return TRUE;
}

⌨️ 快捷键说明

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