strongswan/src/libstrongswan/plugins/bliss/bliss_huffman_coder.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;
}