1 ## Copyright (C) 2006 Muthiah Annamalai <muthiah.annamalai@uta.edu>
2 ## Copyright (C) 2011 Ferran Mesas Garcia <ferran.mesas01@gmail.com>
4 ## This program is free software; you can redistribute it and/or modify it under
5 ## the terms of the GNU General Public License as published by the Free Software
6 ## Foundation; either version 3 of the License, or (at your option) any later
9 ## This program is distributed in the hope that it will be useful, but WITHOUT
10 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 ## You should have received a copy of the GNU General Public License along with
15 ## this program; if not, see <http://www.gnu.org/licenses/>.
18 ## @deftypefn {Function File} {@var{sig} =} huffmandeco (@var{hcode}, @var{dict})
19 ## Decode signal encoded by @code{huffmanenco}.
21 ## This function uses a dict built from the
22 ## @code{huffmandict} and uses it to decode a signal list into a huffman
23 ## list. A restriction is that @var{hcode} is expected to be a binary code
25 ## The returned @var{sig} set that strictly belongs in the range @code{[1,N]}
26 ## with @code{N = length(@var{dict})}. Also @var{dict} can only be from the
27 ## @code{huffmandict} routine. Whenever decoding fails, those signal values a
28 ## re indicated by @code{-1}, and we successively try to restart decoding
29 ## from the next bit that hasn't failed in decoding, ad-infinitum. An example
30 ## of the use of @code{huffmandeco} is:
34 ## hd = huffmandict (1:4, [0.5 0.25 0.15 0.10]);
35 ## hcode = huffmanenco (1:4, hd);
36 ## back = huffmandeco (hcode, hd)
37 ## @result{} [1 2 3 4]
40 ## @seealso{huffmandict, huffmanenco}
43 function symbols = huffmandeco (hcode, dict)
47 elseif (!all((hcode == 1) + (hcode == 0)) || !isvector(hcode))
48 error ("first argument must be a binary array");
49 elseif (!strcmp (class (dict), "cell"))
50 error ("second argument must be of the class dict (from `huffmandict')");
53 ## Convert the Huffman Dictionary to a Huffman Tree represented by
55 tree = dict2tree(dict);
57 ## Traverse the tree and store the symbols.
59 pointer = 1; # a pointer to a node of the tree.
60 for i = 1:length (hcode);
61 if (tree(pointer) != -1)
62 symbols = [symbols, tree(pointer)];
65 pointer = 2 * pointer + hcode(i);
68 ## Check if decodification was successful
69 if (tree(pointer) == -1)
70 warning ("could not decode last symbol.")
72 symbols = [symbols, tree(pointer)];
75 function tree = dict2tree (dict)
79 ## the depth of the tree is limited by the maximum word length.
81 lengths(i) = length (dict{i});
85 tree = zeros(1,2^(m+1)-1)-1;
91 pointer = 2 * pointer + bit;
97 %!assert(huffmandeco(huffmanenco(1:4, huffmandict(1:4,[0.5 0.25 0.15 0.10])), huffmandict(1:4,[0.5 0.25 0.15 0.10])), [1:4],0)
98 %!assert(huffmandeco(huffmanenco([1:100 100:-1:1], huffmandict(1:100,ones(1,100)/100)), huffmandict(1:100,ones(1,100)/100)), [1:100 100:-1:1],0)
99 %!assert(huffmandeco([huffmanenco(1:4, huffmandict(1:4,[0.5 0.25 0.15 0.10])) 0], huffmandict(1:4,[0.5 0.25 0.15 0.10])), [1:4 -1],0)
100 %!fail('huffmandeco([huffmanenco(1:4, huffmandict(1:4,[0.5 0.25 0.15 0.10])) 0], huffmandict(1:4,[0.5 0.25 0.15 0.10]))','warning')
101 %!fail('huffmandeco(''this is not a code'',huffmandict(1:4,[0.5 0.25 0.15 0.10]))')
102 %!fail('huffmandeco([1 0 1 0],''this is not a dictionary'')')