Demo entry 6850832

yyy

   

Submitted by anonymous on Jul 11, 2019 at 18:52
Language: C. Code size: 6.6 kB.

#include <iostream>
#include<fstream>
#include<cstdio>
#include<string>
#include<malloc.h>
#include "HXLBMPFILE.h"
using namespace std;
//读取灰度图片并求出各灰度级的权重
void CountBmp(HXLBMPFILE& bmpfile, int GrayWeights[256]) {
	for (int i = 0; i < bmpfile.imageh; i++) {
		for (int j = 0; j < bmpfile.imagew; j++) {
			unsigned Gray = bmpfile.pDataAt(i)[j];
			GrayWeights[Gray]++;
		}
	}
}
//节点的结构
typedef struct Node {
	int weight;
	int parent;
	int  lchild, rchild;
}HTNode, * HuffmanTree;
typedef char** HuffmanCode;
//根据给定的n个权值构造一颗Huffman树
int mins(HuffmanTree HT, int k) {
	int i = 0;
	int min;
	int min_weight;
	while (HT[i].parent != -1) {
		i++;
	}
	min_weight = HT[i].weight;
	min = i;

	for (; i < k; i++) {
		if (HT[i].weight < min_weight && HT[i].parent == -1) {
			min_weight = HT[i].weight;
			min = i;
		}
	}
	HT[min].parent = 1;
	return min;
}
void select_minium(HuffmanTree HT, int k, int& min, int& secmin) {
	min = mins(HT, k);
	secmin = mins(HT, k);

}
HuffmanTree create_HuffmanTree(int* wet, int n) {
	int total = 2 * n - 1;//总共有2n-1个节点
	HuffmanTree HT = (HuffmanTree)malloc(total * sizeof(HTNode));//给树开辟空间
	if (!HT) {
		printf("空间开辟失败\n");
		exit(-1);
	}
	int i;
	//初始化叶子节点
	for (i = 0; i < n; i++) {
		HT[i].lchild = -1;
		HT[i].rchild = -1;
		HT[i].weight = *wet;
		HT[i].parent = -1;
		wet++;
	}
	//初始化非叶子节点
	for (; i < total; i++) {
		HT[i].lchild = -1;
		HT[i].rchild = -1;
		HT[i].parent = -1;
		HT[i].weight = -1;
	}
	int min, secmin;//查找最小和次小的两个节点
	for (i = n; i < total; i++) {
		select_minium(HT, i, min, secmin);
		HT[min].parent = i;
		HT[secmin].parent = i;
		HT[i].lchild = min;
		HT[i].rchild = secmin;
		HT[i].weight = HT[min].weight + HT[secmin].weight;
	}
	return HT;
}


//从叶子节点到根节点逆向求Huffman树的各个叶子节点字符的Huffman编码
void HuffmanCoding(HuffmanTree HT, HuffmanCode& HC, int n) {
	HC = (HuffmanCode)malloc(n * sizeof(char*));//用来保存指向每个字符的Huffman编码
	if (!HC) {
		printf("存储编码空间开辟失败\n");
		exit(-1);
	}
	//临时存储每次求得的Huffman编码串
	char* code = (char*)malloc(n * sizeof(char));
	code[n - 1] = '\0';
	//求每个字符的Huffman编码
	int i;
	for (i = 0; i < n; i++) {
		int current = i;
		int father = HT[i].parent;
		int start = n - 1;//每次编码的位置,初始为编码结束符的位置
		while (father != -1) {
			if (HT[father].lchild == current)
				code[--start] = '0';
			else
				code[--start] = '1';
			current = father;
			father = HT[father].parent;
		}
		HC[i] = (char*)malloc((n - start) * sizeof(char));
		if (!HC[i]) {
			printf("HC[i] malloc faild");
			exit(-1);
		}
		strcpy(HC[i], code + start);
	}
	free(code);
}

int Code( char** HuffmanCode, HXLBMPFILE& bmpfile) {
		FILE* fpwrite = fopen("abc.dat", "wb");
		//将码表存入二进制文件
		
		if (fpwrite == NULL) {
			printf("数据存储失败\n");
			return 0;
		}

		char* BitArray = { 0 };
		int x = 0;
		int count = 0;
		int left = 0;
		BitArray = (char*)malloc(1 * sizeof(char));
		//存储像素点灰度值串
		for (int i = 0; i < bmpfile.imageh;i++) {
			for (int j = 0; j < bmpfile.imagew; j++) {
				char ConstChar = { 1 };
				char* Gray = HuffmanCode[bmpfile.pDataAt(i)[j]];
				for (int i = 0; i < strlen(Gray); i++) {
					if (Gray[i] == '1') {
						BitArray[x] = BitArray[x] | ConstChar;
						BitArray[x] = BitArray[x] << 1;
						count++;
						if (count % 8 == 0) {
							count = 0;
							x++;
							BitArray = (char*)realloc(BitArray, (x + 1) * sizeof(char));
						}
						left = 8 - count;
					}
					else if (Gray[i] == '0') {
						BitArray[x]= BitArray[x] << 1;
						count++;
						if (count % 8 == 0) {
							count = 0;
							x++;
							BitArray=(char*)realloc(BitArray, (x + 1) * sizeof(char));		
						}
						left = 8 - count;
					}
				}

			}
		}
		BitArray[x] = BitArray[x] << left;
		fwrite(BitArray, sizeof(char),x, fpwrite);
		fclose(fpwrite);
		
		FILE* ftwrite = fopen("abc.txt", "w");
		//存储图片的宽高
		//fprintf(ftwrite, "%d\n", bmpfile.imageh);
		//fprintf(ftwrite, "%d\n", bmpfile.imagew);

		//存储码表
		for (int i = 0; i < 256; i++) {
			char* CodeList = { 0 };
			CodeList = HuffmanCode[i];
			fprintf(ftwrite, "%d\n", i);
			fprintf(ftwrite, "%s\n", CodeList);
		}
		fclose(ftwrite);
	}

void readBit(string* data)
{

	FILE* fp = NULL;
	int count;
	int num;
	int left;
	int i, j;
	errno_t err;
	err = fopen_s(&fp, "abc.dat", "rb");
	unsigned char flag = 128;	//即0b1000000,用于做位运算 ,注意要用无符号的字符型 
	char* p = NULL;
	if (NULL == (err = fopen_s(&fp, "abc.dat", "rb")))
	{
		printf("open file error\n");
	}

	fread(&count, sizeof(count), 1, fp);
	num = count / 8;
	left = count % 8;

	if (left == 0)
	{
		p = (char*)malloc(sizeof(char) * num);
		fread(p, 1, num, fp);
	}
	else
	{
		p = (char*)malloc(sizeof(char) * (num + 1));
		fread(p, 1, num + 1, fp);
	}
	fclose(fp);

	j = -1;
	for (i = 0; i < count; i++)
	{
		if (i % 8 == 0)
		{
			j++;
			flag = 128;
		}

		if ((p[j] & flag))//通过改变flag字符2进制1的位置判读,一个字节哪个位是1,哪个位是0
		{						//并输出字符形式 
			printf("1");
			(*data) =(*data)+ "1";
			flag /= 2;

		}
		else
		{
			printf("0");
			(*data) =(*data)+ "0";
			flag /= 2;
		}

	}
	printf("end\n");

}




//进行解码

void Decode(string * code,HXLBMPFILE &bmpfile) {
	//读取码表
	FILE* ftread = fopen("abc.txt", "r");
	char a[1000] ;
	memset(a, 0, 1000);
	string CodeList[256] = { "" };
	bmpfile.imageh = 512;
	bmpfile.imagew = 512;
	for (int i = 0; i < 256; i++) {
		fgets(a, sizeof(a), ftread);
		
		CodeList[i] = a;
		printf("%s\n", CodeList[i].c_str());
	}
	fclose(ftread);
	//读取二进制串
	//code->at(0);

	
	int count = 0;
	int k=0;
	int flag = 0;
	char* List = { 0 };
	int m=0, n=0;
	
	while (flag == 0) {
		List[k] = code->at(count);
		for (int i = 0; i < 256; i++) {
			if (strcmp(List,CodeList[i].c_str())) {
				bmpfile.pDataAt(m)[n] = i;
				List = {0};
				k = 0;
				count++;
				m++;
				if (m+1 % 512 == 0) {
					n++;
				}
				break;
			}
			else {
				count++;
				k++;
			}
		}
		if (m == 511 && n == 511) {
			flag = 1;
		}
		printf("%d\n", &count);
	}
	bmpfile.SaveBMPFILE("Aim.bmp");
}




int main() {
	HuffmanTree HT;
	string* code=NULL;
	string tool;
	code = &tool;
	readBit(code);
	HXLBMPFILE bmpfile;
	HXLBMPFILE aimfile;
	int GrayWeights[256] = { 0 };
	bmpfile.LoadBMPFILE("1.bmp");
	CountBmp(bmpfile, GrayWeights);
	int n = 256;
	HT = create_HuffmanTree(GrayWeights, n);
	HuffmanCode HC;
	HuffmanCoding(HT, HC, n);
	
	Code(HC, bmpfile);
	Decode(code,aimfile);
	return 0;
}

This snippet took 0.02 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).