0,0 → 1,213 |
/* |
* Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium |
* Copyright (c) 2002-2007, Professor Benoit Macq |
* Copyright (c) 2001-2003, David Janssens |
* Copyright (c) 2002-2003, Yannick Verschueren |
* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe |
* Copyright (c) 2005, Herve Drolon, FreeImage Team |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
#include "opj_includes.h" |
|
/* |
========================================================== |
Tag-tree coder interface |
========================================================== |
*/ |
|
opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) { |
int nplh[32]; |
int nplv[32]; |
opj_tgt_node_t *node = NULL; |
opj_tgt_node_t *parentnode = NULL; |
opj_tgt_node_t *parentnode0 = NULL; |
opj_tgt_tree_t *tree = NULL; |
int i, j, k; |
int numlvls; |
int n; |
|
tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); |
if(!tree) return NULL; |
tree->numleafsh = numleafsh; |
tree->numleafsv = numleafsv; |
|
numlvls = 0; |
nplh[0] = numleafsh; |
nplv[0] = numleafsv; |
tree->numnodes = 0; |
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); |
|
/* ADD */ |
if (tree->numnodes == 0) { |
opj_free(tree); |
return NULL; |
} |
|
tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t)); |
if(!tree->nodes) { |
opj_free(tree); |
return NULL; |
} |
|
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; |
|
tgt_reset(tree); |
|
return tree; |
} |
|
void tgt_destroy(opj_tgt_tree_t *tree) { |
opj_free(tree->nodes); |
opj_free(tree); |
} |
|
void tgt_reset(opj_tgt_tree_t *tree) { |
int i; |
|
if (NULL == tree) |
return; |
|
for (i = 0; i < tree->numnodes; i++) { |
tree->nodes[i].value = 999; |
tree->nodes[i].low = 0; |
tree->nodes[i].known = 0; |
} |
} |
|
void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value) { |
opj_tgt_node_t *node; |
node = &tree->nodes[leafno]; |
while (node && node->value > value) { |
node->value = value; |
node = node->parent; |
} |
} |
|
void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { |
opj_tgt_node_t *stk[31]; |
opj_tgt_node_t **stkptr; |
opj_tgt_node_t *node; |
int low; |
|
stkptr = stk; |
node = &tree->nodes[leafno]; |
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) { |
bio_write(bio, 1, 1); |
node->known = 1; |
} |
break; |
} |
bio_write(bio, 0, 1); |
++low; |
} |
|
node->low = low; |
if (stkptr == stk) |
break; |
node = *--stkptr; |
} |
} |
|
int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { |
opj_tgt_node_t *stk[31]; |
opj_tgt_node_t **stkptr; |
opj_tgt_node_t *node; |
int low; |
|
stkptr = stk; |
node = &tree->nodes[leafno]; |
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 (bio_read(bio, 1)) { |
node->value = low; |
} else { |
++low; |
} |
} |
node->low = low; |
if (stkptr == stk) { |
break; |
} |
node = *--stkptr; |
} |
|
return (node->value < threshold) ? 1 : 0; |
} |