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

📄 coding.cpp

📁 各种数据压缩和解压的源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		rc = fread((int*)&(res2), 2, 1, fp); 
		m_bytesRead += 2;
		if (rc != 1)
		{
			fclose(fp); 
			return NULL;
		}

		rc = fread((long*)&(pixoff), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1) 
		{ 
			fclose(fp); 
			return NULL;
		}

		rc = fread((long*)&(bmisize), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1) 
		{
			fclose(fp); 
			return NULL;
		}

		rc = fread((long*)&(inBM.bmWidth), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1) 
		{
			fclose(fp);
			return NULL;
		}

		rc = fread((long*)&(inBM.bmHeight), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1)
		{
			fclose(fp); 
			return NULL;
		}

		rc = fread((int*)&(inBM.bmPlanes), 2, 1, fp); 
		m_bytesRead += 2;
		if (rc != 1) 
		{
			fclose(fp);
			return NULL;
		}

		rc = fread((int*)&(inBM.bmBitsPixel), 2, 1, fp);
		m_bytesRead += 2;
		if (rc != 1)
		{
			fclose(fp); 
			return NULL;
		}

		rc = fread((long*)&(compression), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1) 
		{
			fclose(fp);
			return NULL;
		}

		rc = fread((long*)&(sizeimage), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1) 
		{
			fclose(fp); 
			return NULL;
		}

		rc = fread((long*)&(xscale), 4, 1, fp);
		m_bytesRead += 4;

		if (rc != 1) 
		{
			fclose(fp);
			return NULL;
		}

		rc = fread((long*)&(yscale), 4, 1, fp); 
		m_bytesRead += 4;
		if (rc != 1)
		{
			fclose(fp);
			return NULL;
		}

		rc = fread((long*)&(colors), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1)
		{
			fclose(fp); 
			return NULL;
		}

		rc = fread((long*)&(impcol), 4, 1, fp);
		m_bytesRead += 4;
		if (rc != 1)
		{
			fclose(fp);
			return NULL;
		}

		// 对RLE文件不做处理
		if (compression != BI_RGB) 
		{
	    	fclose(fp);
	    	return NULL;
	    }

		if (colors == 0) 
			colors = 1 << inBM.bmBitsPixel;
		
		// 读取颜色表
		RGBQUAD *colormap = NULL;

		if ((long)m_bytesRead > pixoff) 
		{
			fclose(fp);
			delete [] colormap;
			fclose(fp);
			return NULL;
		}

		while ((long)m_bytesRead < pixoff) 
		{
			char dummy;
			fread(&dummy,1,1,fp);
			m_bytesRead++;
		}

		int w = inBM.bmWidth;
		int h = inBM.bmHeight;

		// 设置输出参数
		*width = w;
		*height = h;

		long row_size = w * 3;

		long bufsize = (long)w * 3 * (long)h;

		// 分配内存
		outBuf = (BYTE*) new BYTE [bufsize];
		if (outBuf != NULL) 
		{
			long row = 0;
			long rowOffset = 0;

			// 读取点阵数据
			for (row = inBM.bmHeight - 1; row >= 0;row--) 
			{
				rowOffset = (long unsigned)row*row_size;						      

				if (inBM.bmBitsPixel == 24)
				{
					for (int col = 0; col < w; col++) 
					{
						long offset = col * 3;
						char pixel[3];

						if (fread((void  *)(pixel), 1, 3, fp) == 3)
						{
							//交换R、B信息
							*(outBuf + rowOffset + offset + 0) = pixel[2];		// r
							*(outBuf + rowOffset + offset + 1) = pixel[1];		// g
							*(outBuf + rowOffset + offset + 2) = pixel[0];		// b
						}

					}

					m_bytesRead += row_size;
					
					while ((m_bytesRead - pixoff) & 3)
					{
						char dummy;
						if (fread(&dummy, 1, 1, fp) != 1)
						{
							delete [] outBuf;
							fclose(fp);
							return NULL;
						}
						m_bytesRead++;
					}
				} 
			}
		}

		if (colormap) 
			delete [] colormap;

		fclose(fp);
    }
	return outBuf;
}

/*************************************************************************
 *
 * 函数名称:
 *   DIBToPCX()
 *
 * 参数:
 *   HDIB hDIB				- DIB句柄
 *   CString strPath	    - 要保存的文件路径
 *
 * 返回值:
 *   BOOL               - 成功返回True,否则返回False。
 *
 * 说明:
 *   该函数将DIB保存为PCX文件。
 *
 *************************************************************************/

BOOL CCoding::DIBToPCX(HDIB hDIB, CString strPath)
{
	// 循环变量
	LONG	i;
	LONG	j;
	LONG	k;
	
	// 中间变量
	BYTE	bChar1;
	BYTE	bChar2;
	
	// 指向源图像象素的指针
	BYTE*	lpSrc;
	
	// 指向编码后图像数据的指针
	BYTE*	lpDst;
	
	// 重复像素计数
	int		iCount;
	
	// 调整顺序:B、G、R
	int	RGB[3] = {2, 1, 0};

	// 打开文件
	CFile file;
	file.Open(strPath, CFile::modeCreate | CFile::modeReadWrite);
	
	// 缓冲区已使用的字节数
	DWORD	dwBuffUsed;
	
	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 锁定DIB
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	// 判断是否是24-bpp位图
	if (m_clsDIB.DIBBitCount(lpDIB) != 24)
	{
		// 提示用户
		MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hDIB);
		
		// 返回
		return FALSE;
	}
	
	// 更改光标形状
	BeginWaitCursor();
	
	// DIB的宽度
	LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
	
	// DIB的高度
	LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
	
	// 计算图像每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 24);
	
	//*************************************************************************
	// PCX文件头
	PCXHEADER pcxHdr;
	
	// 给文件头赋值
	
	// PCX标识码
	pcxHdr.bManufacturer = 0x0A;
	
	// PCX版本号
	pcxHdr.bVersion = 5;
	
	// PCX编码方式(1表示RLE编码)
	pcxHdr.bEncoding = 1;
	
	// 像素位数(24位色为8位)
	pcxHdr.bBpp = 8;
	
	// 图像相对于屏幕的左上角X坐标(以像素为单位)
	pcxHdr.wLeft = 0;
	
	// 图像相对于屏幕的左上角Y坐标(以像素为单位)
	pcxHdr.wTop = 0;
	
	// 图像相对于屏幕的右下角X坐标(以像素为单位)
	pcxHdr.wRight = lWidth - 1;
	
	// 图像相对于屏幕的右下角Y坐标(以像素为单位)
	pcxHdr.wBottom = lHeight - 1;
		
	// 图像的水平分辨率
	pcxHdr.wXResolution = (WORD)lWidth;
	
	// 图像的垂直分辨率
	pcxHdr.wYResolution = (WORD)lHeight;

	// 保留域,设定为0。
	pcxHdr.bReserved = 0;
	
	// 图像色彩平面数目
	pcxHdr.bPlanes = 3;
	
	// 图像的宽度(字节为单位),必须为偶数。
	pcxHdr.wLineBytes = (WORD)lWidth;
	
	// 图像调色板的类型,1表示彩色或者单色图像,2表示图像是灰度图。
	pcxHdr.wPaletteType = 1;
	
	// 制作该图像的屏幕宽度(像素为单位)
	pcxHdr.wSrcWidth = 0;
	
	// 制作该图像的屏幕高度(像素为单位)
	pcxHdr.wSrcDepth = 0;
	
	// 保留域,取值设定为0。
	for (i = 0; i < 54; i ++)
	{
		pcxHdr.bFiller[i] = 0;
	}
	
	// 写入文件头
	file.Write((LPBYTE)&pcxHdr, sizeof(PCXHEADER));
	
	//*******************************************************************************
	// 开始编码
	
	// 开辟一片缓冲区(2被原始图像大小)以保存编码结果
	lpDst = new BYTE[lHeight * lLineBytes * 2];
	
	// 指明当前已经用了多少缓冲区(字节数)
	dwBuffUsed = 0;
	
	// 每行
	for (i = 0; i < lHeight; i++)
	{
		for (k = 0; k < 3; k++)
		{
			// 指向DIB第i行,第0个象素的指针
			lpSrc = (BYTE*)(lpDIBBits + lLineBytes * (lHeight - 1 - i) + RGB[k]);
			
			// 给bChar1赋值
			bChar1 = *lpSrc;
			
			// 设置iCount为1
			iCount = 1;
		
			// 剩余列
			for (j = 3; j < lLineBytes; j += 3)
			{
				// 指向DIB第i行,第j个象素的指针
				bChar2 = *(lpSrc + j);

				// 判断是否和bChar1相同并且iCount < 63
				if ((bChar1 == bChar2) && (iCount < 63))
				{
					// 相同,计数加1
					iCount ++;
				}	
				else// 不同,或者iCount = 63
				{
					// 写入缓冲区
					if ((iCount > 1) || (bChar1 >= 0xC0))
					{
						// 保存码长信息
						lpDst[dwBuffUsed] = iCount | 0xC0;
					
						// 保存bChar1
						lpDst[dwBuffUsed + 1] = bChar1;
					
						// 更新dwBuffUsed
						dwBuffUsed += 2;
					}
					else
					{
						// 直接保存该值
						lpDst[dwBuffUsed] = bChar1;
					
						// 更新dwBuffUsed
						dwBuffUsed ++;
					}
				
					// 重新给bChar1赋值
					bChar1 = bChar2;
				
					// 设置iCount为1
					iCount = 1;
				}
			}
	
			// 保存每行最后一部分编码
			if ((iCount > 1) || (bChar1 >= 0xC0))
			{
				// 保存码长信息
				lpDst[dwBuffUsed] = iCount | 0xC0;
			
				// 保存bChar1
				lpDst[dwBuffUsed + 1] = bChar1;
				
				// 更新dwBuffUsed
				dwBuffUsed += 2;
			}
			else
			{
				// 直接保存该值
				lpDst[dwBuffUsed] = bChar1;
			
				// 更新dwBuffUsed
				dwBuffUsed ++;
			}
		}
	}

	// 写入编码结果
	file.WriteHuge((LPBYTE)lpDst, dwBuffUsed);
	
	// 释放内存
	delete[] lpDst;
	
	// 关闭文件
	file.Close();

	// 更改光标形状
	EndWaitCursor();

	// 返回
	return TRUE;
}


/*************************************************************************
 *
 * 函数名称:
 *   PCXToDIB()
 *
 * 参数:
 *   CString strPath	    - 要装载的文件路径
 *
 * 返回值:
 *   HDIB		            - 成功返回DIB的句柄,否则返回NULL。
 *
 * 说明:
 *   该函数将读取指定的PCX文件。读取的结果保存在DIB对象中。
 *
 *************************************************************************/

HDIB CCoding::PCXToDIB(CString strPath)
{
	// PCX文件头
	PCXHEADER pcxHdr;
	
	// DIB大小(字节数)
	DWORD	dwDIBSize;
	
	// DIB句柄
	HDIB	hDIB;
	
	// DIB指针
	LPBYTE	pDIB;
	
	// 循环变量
	LONG	i;
	LONG	j;
	LONG	k;
	LONG    l;

	// 重复像素计数
	int		iCount;
	
	// 调整RGB顺序
	int	RGB[3] = {2, 1, 0};
	
	// 中间变量
	BYTE	bChar;
	
	// 指向源图像象素的指针
	BYTE *	lpSrc;
	
	// 指向编码后图像数据的指针
	BYTE *	lpDst;
	
	// 临时指针
	BYTE *	lpTemp;

	// 打开文件
	CFile file;
	file.Open(strPath, CFile::modeReadWrite);
	
	// 尝试读取PCX文件头
	if (file.Read((LPBYTE)&pcxHdr, sizeof(PCXHEADER)) != sizeof(PCXHEADER))
	{
		// 大小不对,返回NULL。
		return NULL;
	}
	
	// 判断是否是24位色PCX文件,检查第一个字节是否是0x0A,
	if ((pcxHdr.bManufacturer != 0x0A) || (pcxHdr.bBpp != 8) || (pcxHdr.bPlanes != 3))
	{
		// 非24位色PCX文件,返回NULL。
		return NULL;
	}
	
	// 获取图像高度
	LONG lHeight = pcxHdr.wBottom - pcxHdr.wTop + 1;
	
	// 获取图像宽度
	LONG lWidth  = pcxHdr.wRight - pcxHdr.wLeft + 1;
	
	// 计算图像每行的字节数
	LONG lLineBytes = WIDTHBYTES(lWidth * 24);
	
	// 计算DIB长度(字节)
	dwDIBSize = sizeof(BITMAPINFOHEADER) + 1024 + lHeight * lLineBytes;
	
	// 为DIB分配内存
	hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize);
	if (hDIB == 0)
	{
		// 内存分配失败,返回NULL。
		return NULL;
	}
	
	// 锁定
	pDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
	
	// 指向BITMAPINFOHEADER的指针
	LPBITMAPINFOHEADER lpBI;
	
	// 赋值
	lpBI = (LPBITMAPINFOHEADER) pDIB;
	
	// 给lpBI成员赋值
	lpBI->biSize = 40;
	lpBI->biWidth = lWidth;
	lpBI->biHeight = lHeight;
	lpBI->biPlanes = 1;
	lpBI->biBitCount = 24;
	lpBI->biCompression = BI_RGB;
	lpBI->biSizeImage = lHeight * lLineBytes;
	lpBI->biXPelsPerMeter = pcxHdr.wXResolution;
	lpBI->biYPelsPerMeter = pcxHdr.wYResolution;
	lpBI->biClrUsed = 0;
	lpBI->biClrImportant = 0;
	
	// 分配内存以读取编码后的象素
	lpSrc = new BYTE[file.GetLength() - sizeof(PCXHEADER) - 769];
	lpTemp = lpSrc;
	
	// 读取编码后的象素
	if (file.ReadHuge(lpSrc, file.GetLength() - sizeof(PCXHEADER) - 769) !=
		file.GetLength() - sizeof(PCXHEADER) - 769 )
	{
		// 大小不对。
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hDIB);
		
		// 释放内存
		::GlobalFree((HGLOBAL) hDIB);
		
		// 返回NULL。
		return NULL;
	}
	
	// 计算DIB中像素位置
	lpDst = (BYTE *) m_clsDIB.FindDIBBits(pDIB);
	

⌨️ 快捷键说明

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