From ec045869d02d033f2614e7162b100bae9b2580ba Mon Sep 17 00:00:00 2001
From: pacien
Date: Fri, 30 Nov 2018 12:33:09 +0100
Subject: add huffman decoder
---
src/huffmandecoder.nim | 34 ++++++++++++++++++++++++++++++++++
src/huffmantree.nim | 6 +++---
tests/thuffmandecoder.nim | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 3 deletions(-)
create mode 100644 src/huffmandecoder.nim
create mode 100644 tests/thuffmandecoder.nim
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 @@
+# gzip-like LZSS compressor
+# Copyright (C) 2018 Pacien TRAN-GIRARD
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import huffmantree, bitreader
+
+type HuffmanDecoder*[T: SomeUnsignedInt] = object
+ tree: HuffmanTreeNode[T]
+
+proc decoder*[T](tree: HuffmanTreeNode[T]): HuffmanDecoder[T] =
+ HuffmanDecoder[T](tree: tree)
+
+proc decode*[T](decoder: HuffmanDecoder[T], bitReader: BitReader): T =
+ proc walk(node: HuffmanTreeNode[T]): T =
+ case node.kind:
+ of branch:
+ case bitReader.readBool():
+ of false: walk(node.left)
+ of true: walk(node.right)
+ of leaf:
+ node.value
+ 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
leaf
type HuffmanTreeNode*[T: SomeUnsignedInt] = ref object
- case kind: HuffmanTreeNodeKind
+ case kind*: HuffmanTreeNodeKind
of branch:
- left, right: HuffmanTreeNode[T]
+ left*, right*: HuffmanTreeNode[T]
maxChildValue: T
of leaf:
- value: T
+ value*: T
weight: int
proc 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 @@
+# gzip-like LZSS compressor
+# Copyright (C) 2018 Pacien TRAN-GIRARD
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import unittest, streams
+import bitreader, bitwriter
+import huffmantree, huffmandecoder
+
+suite "huffdecoder":
+ let tree = huffmanBranch(
+ huffmanLeaf(1'u),
+ huffmanBranch(
+ huffmanLeaf(2'u),
+ huffmanLeaf(3'u)))
+
+ test "decode":
+ let stream = newStringStream()
+ defer: stream.close()
+ let bitWriter = stream.bitWriter()
+ bitWriter.writeBool(true) # 2
+ bitWriter.writeBool(false)
+ bitWriter.writeBool(false) # 1
+ bitWriter.writeBool(true) # 3
+ bitWriter.writeBool(true)
+ bitWriter.flush()
+ stream.setPosition(0)
+ let bitReader = stream.bitReader()
+ let decoder = tree.decoder()
+ check decoder.decode(bitReader) == 2'u
+ check decoder.decode(bitReader) == 1'u
+ check decoder.decode(bitReader) == 3'u
--
cgit v1.2.3