diff options
Diffstat (limited to 'src/libstrongswan/plugins/bliss/bliss_huffman_coder.c')
-rw-r--r-- | src/libstrongswan/plugins/bliss/bliss_huffman_coder.c | 138 |
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; +} |