数据压缩第六次作业':还存在未知bug的PNG转YUV程序(上一篇文章TGA已完成)

数据压缩第六次作业’:还存在未知bug的PNG转YUV程序(上一篇文章TGA已完成)
一、前言:
在进行PNG和YUV的转化过程中,其实这些所有的文件之间的转化的思路都大同小异,都是先去查一下这个文件的存储格式是什么样子的,根据存储格式设计结构体来读取文件头,如果有调色板就设计调色板相关的读取方法,如果没有调色板,就按照真彩色来进行读取。但是,PNG的存储过程是一种利用了LZ77压缩算法的过程,PNG中的IDAT数据块,是经过压缩之后,完成的存储,所以若是要恢复压缩之前的状态,我们先需要在VS里配置zlib库,才可以完成解压缩。但是在实验过程中,配置成功zlib之后出现了一系列问题。在经过两周的努力后还是没搞出来最后的结果,所以就只好先行放弃,把TGA转YUV先做出来。故现将基本完成的PNG头YUV的代码发在此处,日后有时间再重新修改调整。
最终遇见的主要问题是,使用uncompress函数来正常解压一些其他的字符串可以正常解压出正确的结果,先对IDAT中的数据进行uncompress解压,再利用compress函数压缩回去也会得到和之前IDAT中数据块一样的结果。
但是如果单纯的用uncompress来解压,得出来的结果并不能恢复成RGB文件,得出来的结果往往会出现大片的“00”,代码中我调适过程中的一些痕迹已经注释掉了,剩下的均为主程序的内容。
代码如下:

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <cstring>
#include <cstdlib>
#include"header.h"

int Turnround(int a)
{
	int b;
	b = (a & 0xFF000000) >> 24;
	b += (a & 0x000000FF) << 24;
	b += (a & 0x00FF0000) >> 8;
	b += (a & 0x0000FF00) << 8;
	return b;
}
extern"C"
{
#include"..\..\Commonfiles\zlib.h"
}

#include"header.h"
using namespace std;
typedef struct PNGFILEHEADER {
	DWORD head;
	DWORD others;
}PNGFILEHEADER;
//Define a struct to put the fileheader in it
//The length of the header is 8 Bytes, but only need to get the first 4 BYTE of it to recognize PNG

typedef struct PNGIHDR {
	DWORD Length;//4字节长,指定数据块中数据域的长度
	DWORD Chunktypecode;//4字节长,数据块类型码由ASCII字母(A-Z和a-z)组成
	DWORD Width;//4字节,图像宽度,以像素为单位
	DWORD Height;//4字节,图像高度,以像素为单位
	BYTE Bitdepth;//1字节,图像深度
	BYTE Colortype;//1字节,颜色类型
	BYTE Compression_method;//1字节,压缩方法
	BYTE Filter_method;//1字节,滤波器方法
	BYTE Interlace_method;//1字节,隔行扫描方法
}PNGIHDR;
//Define a struct to put the fileheader in it

typedef struct PNGIDATHEAD {
	DWORD length;
	DWORD head;
}PNGIDATHEAD;

typedef struct PNGCRC {
	DWORD CRC;
}PNGCRC;

int main(int argc, char* argv[])
{
	FILE* PNG = NULL;
	FILE* IDAT = NULL;
	const char* OutPath = "\\Mac\\Home\\Desktop\\学习\\数据压缩\\ConsoleApplication1\\ConsoleApplication1\\2.gz";
	PNGFILEHEADER FILE_HEADER;
	PNGIHDR FILE_IHDR;
	if (fopen_s(&PNG, "C:\\20.png", "rb") != 0)
	{
		cout << "Failed to open the png file!" << endl;
	}
	else
	{
		cout << "Successfully opened the png file!" << endl;
	}

	if (fopen_s(&IDAT, "C:\\2.gz", "wb") != 0)
	{
		cout << "Failed to create the rgb file!" << endl;
	}
	else
	{
		cout << "Successfully created the rgb file!" << endl;
	}
	cout << sizeof(PNGIHDR) << endl;
	if (fread(&FILE_HEADER, sizeof(PNGFILEHEADER), 1, PNG) != 1)
	{
		cout << "Read File Header error!" << endl;
	}
	else
	{
		cout << "Successfully read File Header!" << endl;
	}
	if (FILE_HEADER.head != 0x474E5089)//The order of it is opposite
	{
		cout << "This is not a PNG file!" << endl;
	}
	else
	{
		cout << "This is a PNG file!" << endl;
	}

	if (fread(&FILE_IHDR, sizeof(PNGIHDR), 1, PNG) != 1)
	{
		cout << "Read IHDR error!" << endl;
	}
	else
	{
		cout << "Successfully read IHDR!" << endl;
	}
	if (FILE_IHDR.Chunktypecode != 0x52444849)
	{
		cout << "Failed to read in IHDR!" << endl;
	}
	else
	{
		cout << "Successfully read in IHDR!" << endl;
	}


	unsigned long width;
	unsigned long height;
	width = Turnround(FILE_IHDR.Width);
	height = Turnround(FILE_IHDR.Height);
	cout << "The width of the picture is " << width << "." << endl;
	cout << "The height of the picture is " << height << "." << endl;

	int bitdepth;
	int colortype;
	bitdepth = FILE_IHDR.Bitdepth;
	colortype = FILE_IHDR.Colortype;
	cout << "The bitdepth of the picture is " << bitdepth << "." << endl;
	cout << "The colortype of the picture is " << colortype << "." << endl;
	int compressionmethod;
	int filtermethod;
	int interlacemethod;


	compressionmethod = FILE_IHDR.Compression_method;
	filtermethod = FILE_IHDR.Filter_method;
	interlacemethod = FILE_IHDR.Interlace_method;
	cout << "The compressionmethod of the picture is " << compressionmethod << "." << endl;
	cout << "The filtermethod of the picture is " << filtermethod << "." << endl;
	cout << "The interlace method of the picture is " << interlacemethod << "." << endl;
	if (bitdepth == 8 && colortype == 2 && compressionmethod == 0 && filtermethod == 0 && interlacemethod == 0)
	{
		cout << "This program can analyse this picture!" << endl;
	}
	else
	{
		cout << "This program can't analyse this picture!" << endl;
	}

	unsigned char* IDAT_DATA = NULL;
	unsigned char* IDAT_UNCOMPRESS = NULL;
	unsigned char* RED_DATA = NULL;
	unsigned char* GREEN_DATA = NULL;
	unsigned char* BLUE_DATA = NULL;
	unsigned char* ALPHA_DATA = NULL;//need to test the order of RGB later!

	IDAT_DATA = (unsigned char*)malloc(sizeof(unsigned char)*111);
	IDAT_UNCOMPRESS = (unsigned char*)malloc(height * width * bitdepth / 2);
	RED_DATA = (unsigned char*)malloc(height * width);
	GREEN_DATA = (unsigned char*)malloc(height * width);
	BLUE_DATA = (unsigned char*)malloc(height * width);
	ALPHA_DATA = (unsigned char*)malloc(height * width);

	uLong IDAT_Chunksize;
	IDAT_Chunksize = width * height * bitdepth / 2;
	cout << "The size of the chunks in IDAT is " << IDAT_Chunksize * 2 << " Bytes." << endl;
	FILE* FILE_X = NULL;
	fread(&FILE_X, sizeof(unsigned char), 1, PNG);
	/*int looptimes;
	int loopleft;
	looptimes = (int)(IDAT_Chunksize / 4096)+1;
	loopleft = (IDAT_Chunksize * 2) - (looptimes-1) * 8192;
	cout <<"The looptimes is "<< looptimes<<endl;
	cout << "The loopleft is "<< loopleft << endl;*/
	int chunk = 0;

	for (int i = 0; ; i++)
	{
		PNGIDATHEAD FILE_IDATHEAD;
		if (fread(&FILE_IDATHEAD, sizeof(PNGIDATHEAD), 1, PNG) == 1)
		{
			if (FILE_IDATHEAD.head == 0x54414449)
			{
				int chunklength = Turnround(FILE_IDATHEAD.length);
				if (chunklength == 8192)
				{
					if (fread(IDAT_DATA, sizeof(unsigned char), chunklength, PNG) != 0)
					{
						//for (int j = 0; j < chunklength; j++)
						//{
						//	/*cout << IDAT_DATA[j] << " ";*/
						//	printf("%02X ", IDAT_DATA[j]);
						//}
						PNGCRC CRC2;
						fread(&CRC2, sizeof(PNGCRC), 1, PNG);
						chunk += chunklength;
						cout << chunk << " ";

					}
				}
				if (chunklength != 8192)
				{
					if (fread(IDAT_DATA, sizeof(unsigned char), chunklength, PNG) != 0)
					{
						for (int j = 0; j < chunklength; j++)
						{
							/*cout << IDAT_DATA[j] << " ";*/
							printf("%02X ", IDAT_DATA[j]);
						}
						PNGCRC CRC2;
						fread(&CRC2, sizeof(PNGCRC), 1, PNG);
						chunk += chunklength;
						cout << chunk << " " << endl;
					}
					break;
				}

			}
		}
	}
	/*FILE* idat = NULL;
	fopen_s(&idat,"C:\\2.gz", "rb");
	fseek(idat, 0L, SEEK_END);
	int size;
	size = ftell(idat);
	fseek(idat, 0L, SEEK_SET);*/
	/*FILE* idat = NULL;
	fopen_s(&idat,"C:\\3.rgb", "wb");*/
	/*printf("% d", size);*/
	Bytef dest[10000] = { 0 };
	/*Byte dest[177396];*/
	unsigned long ulen = 10000;
	Bytef DATA[200] = { 0 };
	for (int i = 0; i < chunk; i++)
	{
	    DATA[i] = IDAT_DATA[i];
	}
	/*for (int i = 0; i < chunk; i++)
	{
		cout << IDAT_DATA[i] << " ";
	}*/
	unsigned long ulen1 = 200;
	int r = 0;
	/*r = uncompress(dest, &ulen, DATA, ulen1);*/
	cout << r <<" "<<ulen<<endl;
	/*compress(DATA,&ulen1,dest,ulen);
	uncompress(dest, &ulen, IDAT_DATA, ulen1);*/
	for (int i = 0; i < 111; i++)
	{
		printf("%02X ", DATA[i]);
	}
	fwrite(IDAT_DATA, sizeof(unsigned char), 111, IDAT);
	/*fwrite(BLUE_DATA, sizeof(unsigned char), 6400, IDAT);
	fwrite(GREEN_DATA, sizeof(unsigned char), 6400, IDAT);
	fwrite(RED_DATA, sizeof(unsigned char), 6400, IDAT);*/
	/*for (int i = 0; i < 25680; i++)
	{
		printf("%02X ", dest[i]);
    }*/
	/*unsigned long ulen2 = chunk;*/
	/*compress(DATA,&ulen2,dest,ulen);*/
	
	/*fwrite(DATA, sizeof(unsigned char), chunk, idat);*/
	/*int k = 0;*/
	//for (int i = 0; i <25600; i++)
	//{
	//	if (dest[i] == 0)
	//		k++;
	//	/*printf("%02X ", dest[i]);*/
	//}
	/*cout << k;*/

	/*for (int i = 0; i < 25600;)
	{
		BLUE_DATA[i] = dest[i];
		GREEN_DATA[i] = dest[i + 1];
		RED_DATA[i] = dest[i + 2];
		i += 4;
	}*/
	/*fwrite(BLUE_DATA,sizeof(unsigned char),6400,IDAT);
	fwrite(GREEN_DATA, sizeof(unsigned char), 6400, IDAT);
	fwrite(RED_DATA, sizeof(unsigned char), 6400, IDAT);*/

	unsigned char szSrc[] = "test the compression and uncompression of zlib.";
	unsigned long nSrcLen = sizeof(szSrc);
	unsigned char szZip[1024] = { 0 };
	unsigned long nZipLen = 1024;
	compress(szZip, &nZipLen, szSrc, nSrcLen);
	unsigned char szUnZip[1024] = { 0 };
	unsigned long nUnZipLen = 1024;
	uncompress(szUnZip, &nUnZipLen, szZip, nZipLen);
	cout << "Src:" << szSrc << ", len:" << nSrcLen << endl;
	cout << "Zip:" << szZip << ", len:" << nZipLen << endl;
	cout << "UnZip:" << szUnZip << ", len:" << nUnZipLen << endl;






}

//int main()
//{
//	unsigned char* compr = NULL;
//	unsigned char* uncompr = NULL; 
//	unsigned char* comprlen = NULL;
//	unsigned long comprLen = 111;
//	unsigned long uncomprLen;
//	FILE* fpin, * fpout;
//	int file_len_dest = 111;
//	int src_len_src = 0;
//	int wsize = 0;
//	int err;
//	fpin = fopen("C:\\2.gz", "rb");  //读取压缩文件
//	fpout = fopen("C:\\a_dest.rgb", "wb");//将压缩内容输出到此文件
//	if (fpin && fpout)
//	{
//		fseek(fpin, 0, SEEK_END);
//		file_len_dest = ftell(fpin); //得到压缩文件大小
//		fseek(fpin, 0, SEEK_SET);
//		if (file_len_dest > 0)
//		{
//			//comprlen = malloc(sizeof(file_len_dest)); //分配读取前4字节原始文件长度的缓存区
//			compr = new unsigned char[111]; //分配读取压缩文件缓存区
//			/*if (compr == Z_NULL || uncompr == Z_NULL)
//			{
//				fprintf(stderr, "内存分配失败\n");
//				return 1;
//			}*/
//			//fread(comprlen, 4, 1, fpin);//读取前4字节原始文件长度
//			/*src_len_src = *((int*)comprlen);*/
//			src_len_src = 4128;
//			uncompr = new unsigned char[4128];//分配读取解压后写入文件的缓存区
//			//fseek(fpin, 4, SEEK_SET);//设置从4字节之后读
//			fread(compr,sizeof(unsigned char),4128, fpin);//读取压缩文件内容
//			err = uncompress(uncompr, &uncomprLen, compr, comprLen);//解压
//			if (err != Z_OK)
//			{
//				fprintf(stderr, "解压错误\n");
//			}
//			else
//			{
//				wsize = fwrite(uncompr, src_len_src, 1, fpout);//将解压之后的内容写入指定文件
//			}
//			fclose(fpin);
//			fclose(fpout);
//			free(compr);
//			free(comprlen);
//			free(uncompr);
//		}
//		else
//		{
//			fprintf(stderr, "输入文件长度为0");
//		}
//	}
//	else
//	{
//		printf("打开文件出错\n");
//	}
//}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值