This source file includes following definitions.
- jpc_tagtree_create
- jpc_tagtree_destroy
- jpc_tagtree_alloc
- jpc_tagtree_copy
- jpc_tagtree_reset
- jpc_tagtree_setvalue
- jpc_tagtree_getleaf
- jpc_tagtree_encode
- jpc_tagtree_decode
- jpc_tagtree_dump
#include <limits.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "jasper/jas_malloc.h"
#include "jpc_tagtree.h"
static jpc_tagtree_t *jpc_tagtree_alloc(void);
jpc_tagtree_t *jpc_tagtree_create(int numleafsh, int numleafsv)
{
int nplh[JPC_TAGTREE_MAXDEPTH];
int nplv[JPC_TAGTREE_MAXDEPTH];
jpc_tagtreenode_t *node;
jpc_tagtreenode_t *parentnode;
jpc_tagtreenode_t *parentnode0;
jpc_tagtree_t *tree;
int i;
int j;
int k;
int numlvls;
int n;
assert(numleafsh > 0 && numleafsv > 0);
if (!(tree = jpc_tagtree_alloc())) {
return 0;
}
tree->numleafsh_ = numleafsh;
tree->numleafsv_ = numleafsv;
numlvls = 0;
nplh[0] = numleafsh;
nplv[0] = numleafsv;
do {
n = nplh[numlvls] * nplv[numlvls];
nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
tree->numnodes_ += n;
++numlvls;
} while (n > 1);
if (!(tree->nodes_ = jas_alloc2(tree->numnodes_, sizeof(jpc_tagtreenode_t)))) {
return 0;
}
node = tree->nodes_;
parentnode = &tree->nodes_[tree->numleafsh_ * tree->numleafsv_];
parentnode0 = parentnode;
for (i = 0; i < numlvls - 1; ++i) {
for (j = 0; j < nplv[i]; ++j) {
k = nplh[i];
while (--k >= 0) {
node->parent_ = parentnode;
++node;
if (--k >= 0) {
node->parent_ = parentnode;
++node;
}
++parentnode;
}
if ((j & 1) || j == nplv[i] - 1) {
parentnode0 = parentnode;
} else {
parentnode = parentnode0;
parentnode0 += nplh[i];
}
}
}
node->parent_ = 0;
jpc_tagtree_reset(tree);
return tree;
}
void jpc_tagtree_destroy(jpc_tagtree_t *tree)
{
if (tree->nodes_) {
jas_free(tree->nodes_);
}
jas_free(tree);
}
static jpc_tagtree_t *jpc_tagtree_alloc()
{
jpc_tagtree_t *tree;
if (!(tree = jas_malloc(sizeof(jpc_tagtree_t)))) {
return 0;
}
tree->numleafsh_ = 0;
tree->numleafsv_ = 0;
tree->numnodes_ = 0;
tree->nodes_ = 0;
return tree;
}
void jpc_tagtree_copy(jpc_tagtree_t *dsttree, jpc_tagtree_t *srctree)
{
int n;
jpc_tagtreenode_t *srcnode;
jpc_tagtreenode_t *dstnode;
assert(srctree->numleafsh_ == dsttree->numleafsh_ &&
srctree->numleafsv_ == dsttree->numleafsv_);
n = srctree->numnodes_;
srcnode = srctree->nodes_;
dstnode = dsttree->nodes_;
while (--n >= 0) {
dstnode->value_ = srcnode->value_;
dstnode->low_ = srcnode->low_;
dstnode->known_ = srcnode->known_;
++dstnode;
++srcnode;
}
}
void jpc_tagtree_reset(jpc_tagtree_t *tree)
{
int n;
jpc_tagtreenode_t *node;
n = tree->numnodes_;
node = tree->nodes_;
while (--n >= 0) {
node->value_ = INT_MAX;
node->low_ = 0;
node->known_ = 0;
++node;
}
}
void jpc_tagtree_setvalue(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf,
int value)
{
jpc_tagtreenode_t *node;
tree = 0;
assert(value >= 0);
node = leaf;
while (node && node->value_ > value) {
node->value_ = value;
node = node->parent_;
}
}
jpc_tagtreenode_t *jpc_tagtree_getleaf(jpc_tagtree_t *tree, int n)
{
return &tree->nodes_[n];
}
int jpc_tagtree_encode(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf,
int threshold, jpc_bitstream_t *out)
{
jpc_tagtreenode_t *stk[JPC_TAGTREE_MAXDEPTH - 1];
jpc_tagtreenode_t **stkptr;
jpc_tagtreenode_t *node;
int low;
tree = 0;
assert(leaf);
assert(threshold >= 0);
stkptr = stk;
node = leaf;
while (node->parent_) {
*stkptr++ = node;
node = node->parent_;
}
low = 0;
for (;;) {
if (low > node->low_) {
node->low_ = low;
} else {
low = node->low_;
}
while (low < threshold) {
if (low >= node->value_) {
if (!node->known_) {
if (jpc_bitstream_putbit(out, 1) == EOF) {
return -1;
}
node->known_ = 1;
}
break;
}
if (jpc_bitstream_putbit(out, 0) == EOF) {
return -1;
}
++low;
}
node->low_ = low;
if (stkptr == stk) {
break;
}
node = *--stkptr;
}
return (leaf->low_ < threshold) ? 1 : 0;
}
int jpc_tagtree_decode(jpc_tagtree_t *tree, jpc_tagtreenode_t *leaf,
int threshold, jpc_bitstream_t *in)
{
jpc_tagtreenode_t *stk[JPC_TAGTREE_MAXDEPTH - 1];
jpc_tagtreenode_t **stkptr;
jpc_tagtreenode_t *node;
int low;
int ret;
tree = 0;
assert(threshold >= 0);
stkptr = stk;
node = leaf;
while (node->parent_) {
*stkptr++ = node;
node = node->parent_;
}
low = 0;
for (;;) {
if (low > node->low_) {
node->low_ = low;
} else {
low = node->low_;
}
while (low < threshold && low < node->value_) {
if ((ret = jpc_bitstream_getbit(in)) < 0) {
return -1;
}
if (ret) {
node->value_ = low;
} else {
++low;
}
}
node->low_ = low;
if (stkptr == stk) {
break;
}
node = *--stkptr;
}
return (node->value_ < threshold) ? 1 : 0;
}
void jpc_tagtree_dump(jpc_tagtree_t *tree, FILE *out)
{
jpc_tagtreenode_t *node;
int n;
node = tree->nodes_;
n = tree->numnodes_;
while (--n >= 0) {
fprintf(out, "node %p, parent %p, value %d, lower %d, known %d\n",
(void *) node, (void *) node->parent_, node->value_, node->low_,
node->known_);
++node;
}
}