139 lines
3.2 KiB
C
139 lines
3.2 KiB
C
/*
|
|
* 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;
|
|
}
|