| /* |
| * 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; |
| } |