summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/bliss/bliss_huffman_coder.c')
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_coder.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c
new file mode 100644
index 000000000..018ae0efa
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_huffman_coder.h"
+
+typedef struct private_bliss_huffman_coder_t private_bliss_huffman_coder_t;
+
+/**
+ * Private data structure for bliss_huffman_coder_t object
+ */
+struct private_bliss_huffman_coder_t {
+ /**
+ * Public interface.
+ */
+ bliss_huffman_coder_t public;
+
+ /**
+ * Bitpacker to write to or read from
+ */
+ bliss_bitpacker_t *packer;
+
+ /**
+ * Huffman code table to be used
+ */
+ bliss_huffman_code_t *code;
+
+ /**
+ * Maximum index into tuples table
+ */
+ int index_max;
+
+ /**
+ * Number of encoded or decoded bits
+ */
+ size_t bits;
+
+};
+
+METHOD(bliss_huffman_coder_t, get_bits, size_t,
+ private_bliss_huffman_coder_t *this)
+{
+ return this->bits;
+}
+
+METHOD(bliss_huffman_coder_t, encode, bool,
+ private_bliss_huffman_coder_t *this, int32_t z1, int16_t z2)
+{
+ uint32_t code;
+ uint16_t bits;
+ int index;
+
+ index = z1 * (2*this->code->n_z2 - 1) + z2 + this->code->n_z2 - 1;
+ if (index >= this->index_max)
+ {
+ DBG1(DBG_LIB, "index exceeded in Huffman encoding table");
+ return FALSE;
+ }
+ code = this->code->tuples[index].code;
+ bits = this->code->tuples[index].bits;
+ if (!this->packer->write_bits(this->packer, code, bits))
+ {
+ DBG1(DBG_LIB, "bitpacker exceeded its buffer");
+ return FALSE;
+ }
+ this->bits += bits;
+
+ return TRUE;
+}
+
+METHOD(bliss_huffman_coder_t, decode, bool,
+ private_bliss_huffman_coder_t *this, int32_t *z1, int16_t *z2)
+{
+ bliss_huffman_code_node_t *node;
+ uint32_t bit;
+
+ node = this->code->nodes;
+ while (node->tuple == BLISS_HUFFMAN_CODE_NO_TUPLE)
+ {
+ if (node->node_0 == BLISS_HUFFMAN_CODE_NO_NODE ||
+ node->node_1 == BLISS_HUFFMAN_CODE_NO_NODE)
+ {
+ DBG1(DBG_LIB, "error in Huffman decoding table");
+ return FALSE;
+ }
+ if (!this->packer->read_bits(this->packer, &bit, 1))
+ {
+ DBG1(DBG_LIB, "bitpacker depleted its buffer");
+ return FALSE;
+ }
+ node = &this->code->nodes[bit ? node->node_1 : node->node_0];
+ this->bits++;
+ }
+ *z1 = node->tuple / (2*this->code->n_z2 - 1);
+ *z2 = node->tuple - (2*this->code->n_z2 - 1) * (*z1) - this->code->n_z2 + 1;
+
+ return TRUE;
+}
+
+METHOD(bliss_huffman_coder_t, destroy, void,
+ private_bliss_huffman_coder_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_huffman_coder_t *bliss_huffman_coder_create(bliss_huffman_code_t *code,
+ bliss_bitpacker_t *packer)
+{
+ private_bliss_huffman_coder_t *this;
+
+ INIT(this,
+ .public = {
+ .get_bits = _get_bits,
+ .encode = _encode,
+ .decode = _decode,
+ .destroy = _destroy,
+ },
+ .packer = packer,
+ .code = code,
+ .index_max = (2*code->n_z2 - 1) * code->n_z1,
+ );
+
+ return &this->public;
+}