aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpacien2018-11-30 12:33:09 +0100
committerpacien2018-11-30 12:35:46 +0100
commitec045869d02d033f2614e7162b100bae9b2580ba (patch)
tree98ef53efd855660dc81c2ba58f3a3325453661e0
parentccc45ad33b3da9e415ef35a393930cde1136ae99 (diff)
downloadgziplike-ec045869d02d033f2614e7162b100bae9b2580ba.tar.gz
add huffman decoder
-rw-r--r--src/huffmandecoder.nim34
-rw-r--r--src/huffmantree.nim6
-rw-r--r--tests/thuffmandecoder.nim43
3 files changed, 80 insertions, 3 deletions
diff --git a/src/huffmandecoder.nim b/src/huffmandecoder.nim
new file mode 100644
index 0000000..4df712a
--- /dev/null
+++ b/src/huffmandecoder.nim
@@ -0,0 +1,34 @@
1# gzip-like LZSS compressor
2# Copyright (C) 2018 Pacien TRAN-GIRARD
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17import huffmantree, bitreader
18
19type HuffmanDecoder*[T: SomeUnsignedInt] = object
20 tree: HuffmanTreeNode[T]
21
22proc decoder*[T](tree: HuffmanTreeNode[T]): HuffmanDecoder[T] =
23 HuffmanDecoder[T](tree: tree)
24
25proc decode*[T](decoder: HuffmanDecoder[T], bitReader: BitReader): T =
26 proc walk(node: HuffmanTreeNode[T]): T =
27 case node.kind:
28 of branch:
29 case bitReader.readBool():
30 of false: walk(node.left)
31 of true: walk(node.right)
32 of leaf:
33 node.value
34 walk(decoder.tree)
diff --git a/src/huffmantree.nim b/src/huffmantree.nim
index c57b55c..44c9990 100644
--- a/src/huffmantree.nim
+++ b/src/huffmantree.nim
@@ -24,12 +24,12 @@ type HuffmanTreeNodeKind* = enum
24 leaf 24 leaf
25 25
26type HuffmanTreeNode*[T: SomeUnsignedInt] = ref object 26type HuffmanTreeNode*[T: SomeUnsignedInt] = ref object
27 case kind: HuffmanTreeNodeKind 27 case kind*: HuffmanTreeNodeKind
28 of branch: 28 of branch:
29 left, right: HuffmanTreeNode[T] 29 left*, right*: HuffmanTreeNode[T]
30 maxChildValue: T 30 maxChildValue: T
31 of leaf: 31 of leaf:
32 value: T 32 value*: T
33 weight: int 33 weight: int
34 34
35proc huffmanBranch*[T](left, right: HuffmanTreeNode[T]): HuffmanTreeNode[T] = 35proc huffmanBranch*[T](left, right: HuffmanTreeNode[T]): HuffmanTreeNode[T] =
diff --git a/tests/thuffmandecoder.nim b/tests/thuffmandecoder.nim
new file mode 100644
index 0000000..d4d81b4
--- /dev/null
+++ b/tests/thuffmandecoder.nim
@@ -0,0 +1,43 @@
1# gzip-like LZSS compressor
2# Copyright (C) 2018 Pacien TRAN-GIRARD
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17import unittest, streams
18import bitreader, bitwriter
19import huffmantree, huffmandecoder
20
21suite "huffdecoder":
22 let tree = huffmanBranch(
23 huffmanLeaf(1'u),
24 huffmanBranch(
25 huffmanLeaf(2'u),
26 huffmanLeaf(3'u)))
27
28 test "decode":
29 let stream = newStringStream()
30 defer: stream.close()
31 let bitWriter = stream.bitWriter()
32 bitWriter.writeBool(true) # 2
33 bitWriter.writeBool(false)
34 bitWriter.writeBool(false) # 1
35 bitWriter.writeBool(true) # 3
36 bitWriter.writeBool(true)
37 bitWriter.flush()
38 stream.setPosition(0)
39 let bitReader = stream.bitReader()
40 let decoder = tree.decoder()
41 check decoder.decode(bitReader) == 2'u
42 check decoder.decode(bitReader) == 1'u
43 check decoder.decode(bitReader) == 3'u