huffencode.m
上传用户:hwtw888
上传日期:2016-03-15
资源大小:177k
文件大小:3k
源码类别:

压缩解压

开发平台:

Matlab

  1. function [zipped, info] = huffencode(vector)
  2. % 输入和输出都是 uint8 格式
  3. % info 返回解码需要的结构信息
  4. % info.pad 是添加的比特数
  5. % info.huffcodes 是 Huffman 码字
  6. % info.rows 是原始图像行数
  7. % info.cols 是原始图像列数
  8. % info.length 是原始图像数据长度
  9. % info.maxcodelen 是最大码长
  10. if ~isa(vector, 'uint8')
  11.     error('input argument must be a uint8 vector');
  12. end
  13. [m, n] = size(vector);
  14. vector = vector(:)';
  15. f = frequency(vector);      %计算各符号出现的概率
  16. symbols = find(f~=0);
  17. f = f(symbols);
  18. [f, sortindex] = sort(f);    %将符号按照出现的概率大小排列
  19. symbols = symbols(sortindex);
  20. len = length(symbols);
  21. symbols_index = num2cell(1:len);
  22. codeword_tmp = cell(len, 1);
  23. % 生成 Huffman 树,得到码字编码表
  24. while length(f)>1
  25.     index1 = symbols_index{1};
  26.     index2 = symbols_index{2};
  27.     codeword_tmp(index1) = addnode(codeword_tmp(index1), uint8(0));
  28.     codeword_tmp(index2) = addnode(codeword_tmp(index2), uint8(1));
  29.     f = [sum(f(1:2)),f(3:end)];
  30.     symbols_index = [{[index1, index2]},symbols_index(3:end)];
  31.     [f, sortindex] = sort(f);
  32.     symbols_index = symbols_index(sortindex);
  33. end
  34. codeword = cell(256, 1);
  35. codeword(symbols) = codeword_tmp;
  36. len = 0;
  37. for index = 1:length(vector)       %得到整个图像所有比特数
  38.     len = len + length(codeword{double(vector(index))+1});
  39. end
  40. string = repmat(uint8(0), 1, len);
  41. pointer = 1;
  42. for index = 1:length(vector)       %对输入图像进行编码
  43.     code = codeword{double(vector(index))+1};
  44.     len = length(code);
  45.     string(pointer + (0:len-1))=code;
  46.     pointer = pointer + len;
  47. end
  48. len = length(string);
  49. pad = 8-mod(len, 8);
  50. if pad > 0
  51.     string = [string uint8(zeros(1, pad))];
  52. end
  53. codeword = codeword(symbols);
  54. codelen = zeros(size(codeword));
  55. weights = 2.^(0:23);
  56. maxcodelen = 0;
  57. for index = 1:length(codeword)
  58.     len = length(codeword{index});
  59.     if len > maxcodelen;
  60.         maxcodelen = len;
  61.     end
  62.     if len > 0
  63.         code = sum(weights(codeword{index} == 1));
  64.         code = bitset(code, len + 1);
  65.         codeword{index} = code;
  66.         codelen(index) = len;
  67.     end
  68. end
  69. codeword = [codeword{:}];
  70.     
  71. %计算压缩的向量
  72. cols = length(string)/8;
  73. string = reshape(string, 8, cols);
  74. weights = 2.^(0: 7);
  75. zipped = uint8(weights * double(string));
  76.     
  77. %码表存储到一个希疏矩阵
  78. huffcodes = sparse(1, 1);
  79. for index = 1:nnz(codeword)   % length(codeword)  %numel(codeword)
  80.     huffcodes(codeword(index), 1) = symbols(index);
  81. end
  82.     
  83. %填写解码时所需的结构信息
  84. info.pad = pad;
  85. info.huffcodes = huffcodes;
  86. info.ratio = cols./length(vector);
  87. info.length = length(vector);
  88. info.maxcodelen = maxcodelen;
  89. info.rows = m;
  90. info.cols = n;
  91.     
  92. %函数addnode添加节点
  93. function codeword_new = addnode(codeword_old, item)
  94. codeword_new = cell(size(codeword_old));
  95. for index = 1:length(codeword_old)
  96.     codeword_new{index} = [item codeword_old{index}];
  97. end
  98. %函数frequency计算各符号出现的概率
  99. function f = frequency(vector)
  100. if ~isa(vector, 'uint8')
  101.     error('input argument must be a uint8 vector');
  102. end
  103. f = repmat(0, 1, 256);
  104. len = length(vector);
  105. for index = 0:255
  106.     f(index+1) = sum(vector == uint8(index));
  107. end
  108. f = f./len;   %归一化
  109.     
  110.