彩色图像霍(哈)夫曼编码、解码
来源:互联网 发布:java反射获取私有属性 编辑:程序博客网 时间:2024/05/16 07:21
/***********************************************************************************************************Huffman.c本演示程序提供了哈夫曼编码法的压缩和解压缩函数,并实现了对图象文件的压缩和解压缩**********************************************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>/* 函数原型 */int Huffman_Compression(char * infilename, char * outfilename);int Huffman_Decompression(char * infilename, char * outfilename);/* 内部函数 */unsigned short generate_code_table ();void build_code_tree ();void build_initial_heap ();void compress_image ();void get_frequency_count ();voidbuild_decomp_tree ();voiddecompress_image ();/* 全局变量 */short father[512];unsigned short code[256], heap_length;unsigned long compress_charcount, file_size, heap[257];unsigned char code_length[256];long frequency_count[512];short decomp_tree[512];FILE *ifile, *ofile;int total_time;clock_t start, finish;/* 主程序 */void main(){printf("Huffman compression and decompression utility\n");if (1){printf("\nCompress...");start = clock();Huffman_Compression("2.bmp", "3.bmp");//压缩finish = clock();total_time = finish - start;printf("\n耗时: %d毫秒\n", total_time);}else {printf("\nDecompress...");//解压Huffman_Decompression("3.bmp", "4.bmp");}}/********************************************************************************* Huffman_Compression () 用Huffman编码压缩指定的文件,并将结果存为新的文件 ********************************************************************************/int Huffman_Compression(char * infilename, char * outfilename){if ((ifile = fopen (infilename, "rb")) != NULL){fseek (ifile, 0L, 2);file_size = (unsigned long) ftell (ifile);//文件的长度fseek (ifile, 0L, 0);get_frequency_count ();//本函数对需要进行压缩的数据进行频率统计build_initial_heap ();build_code_tree ();if (!generate_code_table ()){printf ("ERROR! Code Value Out of Range. Cannot Compress.\n");return 0;}else{if ((ofile = fopen (outfilename, "wb")) != NULL){fwrite (&file_size, sizeof (file_size), 1, ofile);fwrite (code, 2, 256, ofile);fwrite (code_length, 1, 256, ofile);fseek (ifile, 0L, 0);compress_image ();fclose (ofile);}else{printf("\nERROR: Couldn't create output file %s\n", outfilename);return 0;}}fclose (ifile);}else{printf ("\nERROR: %s -- File not found!\n", infilename);return 0;}return 1;}/************************************************************************** COMPRESS_IMAGE () 本函数进行数据的压缩操作 **************************************************************************/void compress_image (){ register unsigned int thebyte = 0; register short loop1; register unsigned short current_code; register unsigned long loop; unsigned short current_length, dvalue; unsigned long curbyte = 0; short curbit = 7; for (loop = 0L; loop < file_size; loop++) { dvalue = (unsigned short) getc (ifile); current_code = code[dvalue]; current_length = (unsigned short) code_length[dvalue]; for (loop1 = current_length-1; loop1 >= 0; --loop1) { if ((current_code >> loop1) & 1) thebyte |= (char) (1 << curbit); if (--curbit < 0) { putc (thebyte, ofile); thebyte = 0; curbyte++; curbit = 7; } } } putc (thebyte, ofile); compress_charcount = ++curbyte;}/************************************************************************** GENERATE_CODE_TABLE () 本函数生成压缩码表 **************************************************************************/unsigned short generate_code_table (){ register unsigned short loop; register unsigned short current_length; register unsigned short current_bit; unsigned short bitcode; short parent; for (loop = 0; loop < 256; loop++) if (frequency_count[loop]) { current_length = bitcode = 0; current_bit = 1; parent = father[loop]; while (parent) { if (parent < 0) { bitcode += current_bit; parent = -parent; } parent = father[parent]; current_bit <<= 1; current_length++; } code[loop] = bitcode; if (current_length > 16) return (0); else code_length[loop] = (unsigned char) current_length; } else code[loop] = code_length[loop] = 0; return (1);}/************************************************************************** BUILD_CODE_TREE () 建立压缩编码树 **************************************************************************/void build_code_tree (){ void reheap (); register unsigned short findex; register unsigned long heap_value; while (heap_length != 1) { heap_value = heap[1]; heap[1] = heap[heap_length--]; reheap (1); findex = heap_length + 255; frequency_count[findex] = frequency_count[heap[1]] + frequency_count[heap_value]; father[heap_value] = findex; father[heap[1]] = -findex; heap[1] = findex; reheap (1); } father[256] = 0;}/************************************************************************** REHEAP () 从当前的堆树结构中建立逻辑堆结构 **************************************************************************/void reheap (heap_entry)unsigned short heap_entry;{ register unsigned short index; register unsigned short flag = 1; unsigned long heap_value; heap_value = heap[heap_entry]; while ((heap_entry <= (heap_length >> 1)) && (flag)) { index = heap_entry << 1; if (index < heap_length) if (frequency_count[heap[index]] >= frequency_count[heap[index+1]]) index++; if (frequency_count[heap_value] < frequency_count[heap[index]]) flag--; else { heap[heap_entry] = heap[index]; heap_entry = index; } } heap[heap_entry] = heap_value;}/************************************************************************** BUILD_INITIAL_HEAP () 本函数从初始的频率统计数据中建立堆结构 **************************************************************************/void build_initial_heap (){ void reheap ();//从当前的堆树结构中建立逻辑堆结构 register unsigned short loop; heap_length = 0; for (loop = 0; loop < 256; loop++) if (frequency_count[loop]) heap[++heap_length] = (unsigned long) loop; for (loop = heap_length; loop > 0; loop--) reheap (loop);}/************************************************************************** GET_FREQUENCY_COUNT () 本函数对需要进行压缩的数据进行频率统计 **************************************************************************/void get_frequency_count (){register unsigned long loop;//如某个变量使用过于频繁,可能把变量放在 寄存器 更合适 for (loop = 0; loop < file_size; loop++) frequency_count[getc (ifile)]++;//getc (ifile)从文件指针指向的文件读入一个字符}/************************************************************************** Huffman_Decompression () 本函数进行Huffman解码 **************************************************************************/int Huffman_Decompression(char * infilename, char * outfilename){if ((ifile = fopen (infilename, "rb")) != NULL){fread (&file_size, sizeof (file_size), 1, ifile);fread (code, 2, 256, ifile);fread (code_length, 1, 256, ifile);build_decomp_tree ();if ((ofile = fopen (outfilename, "wb")) != NULL){decompress_image();fclose (ofile);}else{printf ("\nERROR: Couldn't create output file %s\n", outfilename);return 0;}fclose (ifile);}else{printf ("\nERROR: %s -- File not found!\n", infilename);return 0;}return 1;}/************************************************************************** BUILD_DECOMP_TREE () 创建解压缩树 **************************************************************************/void build_decomp_tree (){ register unsigned short loop1; register unsigned short current_index; unsigned short loop; unsigned short current_node = 1; decomp_tree[1] = 1; for (loop = 0; loop < 256; loop++) { if (code_length[loop]) { current_index = 1; for (loop1 = code_length[loop] - 1; loop1 > 0; loop1--) { current_index = (decomp_tree[current_index] << 1) + ((code[loop] >> loop1) & 1); if (!(decomp_tree[current_index])) decomp_tree[current_index] = ++current_node; } decomp_tree[(decomp_tree[current_index] << 1) + (code[loop] & 1)] = -loop; } }}/************************************************************************** DECOMPRESS_IMAGE () 进行解压缩操作 **************************************************************************/void decompress_image (){ register unsigned short cindex = 1; register char curchar; register short bitshift; unsigned long charcount = 0L; while (charcount < file_size) { curchar = (char) getc (ifile); for (bitshift = 7; bitshift >= 0; --bitshift) { cindex = (cindex << 1) + ((curchar >> bitshift) & 1); if (decomp_tree[cindex] <= 0) { putc ((int) (-decomp_tree[cindex]), ofile); if ((++charcount) == file_size) bitshift = 0; else cindex = 1; } else cindex = decomp_tree[cindex]; } }}
注:此程序是针对彩色图像进行的编解码
把2.bmp压缩成3.bmp.但3.bmp打不开,
把3.bmp解压到4.bmp,即原来的2.bmp
0 0
- 彩色图像霍(哈)夫曼编码、解码
- JPEG图像编码解码
- OpenCV图像编码和解码
- ---WebCam网络摄像头12 ---图像编码解码,视频编码解码
- jpeg图像的压缩编码与解码
- 图像压缩编码和解码原理
- 图像压缩编码和解码原理
- 图像压缩编码和解码原理
- 彩色图像->灰度图像:
- 灰度图像彩色图像
- 256级灰度图像进行霍夫曼编码、解码
- 经验及技巧:windows phone 8.1开发图像编码解码
- 彩色图像--图像分割 彩色空间分割
- 编码->解码
- 编码 解码
- 编码解码
- 编码 解码
- 编码、解码
- poj 2115 C Looooops(扩展欧几里得)
- js javascript js控制分页打印,打印分页
- C#事件学习
- Django:ManyToManyField
- Groovy入门教程
- 彩色图像霍(哈)夫曼编码、解码
- 一些无聊时的关于技术设计的想法
- photoshop切片工具
- 《算法艺术与信息学竞赛》题目-提交方式对照表
- svn连接不上的问题
- 浅谈函数的可变参数
- android 怎么引用Libray
- 电脑内存常见问题处理方法
- c#在WinForms程序里实现窗体传值的最佳实践