1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker * The copyright in this software is being made available under the 2-clauses
3*3ac0a46fSAndroid Build Coastguard Worker * BSD License, included below. This software may be subject to other third
4*3ac0a46fSAndroid Build Coastguard Worker * party and contributor rights, including patent rights, and no such rights
5*3ac0a46fSAndroid Build Coastguard Worker * are granted under this license.
6*3ac0a46fSAndroid Build Coastguard Worker *
7*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2002-2014, Professor Benoit Macq
9*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2001-2003, David Janssens
10*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2002-2003, Yannick Verschueren
11*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2003-2007, Francois-Olivier Devaux
12*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2003-2014, Antonin Descampe
13*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2005, Herve Drolon, FreeImage Team
14*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
15*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 2012, CS Systemes d'Information, France
16*3ac0a46fSAndroid Build Coastguard Worker * All rights reserved.
17*3ac0a46fSAndroid Build Coastguard Worker *
18*3ac0a46fSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
19*3ac0a46fSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
20*3ac0a46fSAndroid Build Coastguard Worker * are met:
21*3ac0a46fSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
22*3ac0a46fSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
23*3ac0a46fSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
24*3ac0a46fSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
25*3ac0a46fSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
26*3ac0a46fSAndroid Build Coastguard Worker *
27*3ac0a46fSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
28*3ac0a46fSAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*3ac0a46fSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*3ac0a46fSAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*3ac0a46fSAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*3ac0a46fSAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*3ac0a46fSAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*3ac0a46fSAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*3ac0a46fSAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*3ac0a46fSAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*3ac0a46fSAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
38*3ac0a46fSAndroid Build Coastguard Worker */
39*3ac0a46fSAndroid Build Coastguard Worker
40*3ac0a46fSAndroid Build Coastguard Worker #include "opj_includes.h"
41*3ac0a46fSAndroid Build Coastguard Worker
42*3ac0a46fSAndroid Build Coastguard Worker /*
43*3ac0a46fSAndroid Build Coastguard Worker ==========================================================
44*3ac0a46fSAndroid Build Coastguard Worker Tag-tree coder interface
45*3ac0a46fSAndroid Build Coastguard Worker ==========================================================
46*3ac0a46fSAndroid Build Coastguard Worker */
47*3ac0a46fSAndroid Build Coastguard Worker
opj_tgt_create(OPJ_UINT32 numleafsh,OPJ_UINT32 numleafsv,opj_event_mgr_t * p_manager)48*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv,
49*3ac0a46fSAndroid Build Coastguard Worker opj_event_mgr_t *p_manager)
50*3ac0a46fSAndroid Build Coastguard Worker {
51*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 nplh[32];
52*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 nplv[32];
53*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *node = 00;
54*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *l_parent_node = 00;
55*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *l_parent_node0 = 00;
56*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_tree_t *tree = 00;
57*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 i;
58*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 j, k;
59*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 numlvls;
60*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 n;
61*3ac0a46fSAndroid Build Coastguard Worker
62*3ac0a46fSAndroid Build Coastguard Worker tree = (opj_tgt_tree_t *) opj_calloc(1, sizeof(opj_tgt_tree_t));
63*3ac0a46fSAndroid Build Coastguard Worker if (!tree) {
64*3ac0a46fSAndroid Build Coastguard Worker opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to create Tag-tree\n");
65*3ac0a46fSAndroid Build Coastguard Worker return 00;
66*3ac0a46fSAndroid Build Coastguard Worker }
67*3ac0a46fSAndroid Build Coastguard Worker
68*3ac0a46fSAndroid Build Coastguard Worker tree->numleafsh = numleafsh;
69*3ac0a46fSAndroid Build Coastguard Worker tree->numleafsv = numleafsv;
70*3ac0a46fSAndroid Build Coastguard Worker
71*3ac0a46fSAndroid Build Coastguard Worker numlvls = 0;
72*3ac0a46fSAndroid Build Coastguard Worker nplh[0] = (OPJ_INT32)numleafsh;
73*3ac0a46fSAndroid Build Coastguard Worker nplv[0] = (OPJ_INT32)numleafsv;
74*3ac0a46fSAndroid Build Coastguard Worker tree->numnodes = 0;
75*3ac0a46fSAndroid Build Coastguard Worker do {
76*3ac0a46fSAndroid Build Coastguard Worker n = (OPJ_UINT32)(nplh[numlvls] * nplv[numlvls]);
77*3ac0a46fSAndroid Build Coastguard Worker nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
78*3ac0a46fSAndroid Build Coastguard Worker nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
79*3ac0a46fSAndroid Build Coastguard Worker tree->numnodes += n;
80*3ac0a46fSAndroid Build Coastguard Worker ++numlvls;
81*3ac0a46fSAndroid Build Coastguard Worker } while (n > 1);
82*3ac0a46fSAndroid Build Coastguard Worker
83*3ac0a46fSAndroid Build Coastguard Worker /* ADD */
84*3ac0a46fSAndroid Build Coastguard Worker if (tree->numnodes == 0) {
85*3ac0a46fSAndroid Build Coastguard Worker opj_free(tree);
86*3ac0a46fSAndroid Build Coastguard Worker return 00;
87*3ac0a46fSAndroid Build Coastguard Worker }
88*3ac0a46fSAndroid Build Coastguard Worker
89*3ac0a46fSAndroid Build Coastguard Worker tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes,
90*3ac0a46fSAndroid Build Coastguard Worker sizeof(opj_tgt_node_t));
91*3ac0a46fSAndroid Build Coastguard Worker if (!tree->nodes) {
92*3ac0a46fSAndroid Build Coastguard Worker opj_event_msg(p_manager, EVT_ERROR,
93*3ac0a46fSAndroid Build Coastguard Worker "Not enough memory to create Tag-tree nodes\n");
94*3ac0a46fSAndroid Build Coastguard Worker opj_free(tree);
95*3ac0a46fSAndroid Build Coastguard Worker return 00;
96*3ac0a46fSAndroid Build Coastguard Worker }
97*3ac0a46fSAndroid Build Coastguard Worker tree->nodes_size = tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
98*3ac0a46fSAndroid Build Coastguard Worker
99*3ac0a46fSAndroid Build Coastguard Worker node = tree->nodes;
100*3ac0a46fSAndroid Build Coastguard Worker l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv];
101*3ac0a46fSAndroid Build Coastguard Worker l_parent_node0 = l_parent_node;
102*3ac0a46fSAndroid Build Coastguard Worker
103*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < numlvls - 1; ++i) {
104*3ac0a46fSAndroid Build Coastguard Worker for (j = 0; j < nplv[i]; ++j) {
105*3ac0a46fSAndroid Build Coastguard Worker k = nplh[i];
106*3ac0a46fSAndroid Build Coastguard Worker while (--k >= 0) {
107*3ac0a46fSAndroid Build Coastguard Worker node->parent = l_parent_node;
108*3ac0a46fSAndroid Build Coastguard Worker ++node;
109*3ac0a46fSAndroid Build Coastguard Worker if (--k >= 0) {
110*3ac0a46fSAndroid Build Coastguard Worker node->parent = l_parent_node;
111*3ac0a46fSAndroid Build Coastguard Worker ++node;
112*3ac0a46fSAndroid Build Coastguard Worker }
113*3ac0a46fSAndroid Build Coastguard Worker ++l_parent_node;
114*3ac0a46fSAndroid Build Coastguard Worker }
115*3ac0a46fSAndroid Build Coastguard Worker if ((j & 1) || j == nplv[i] - 1) {
116*3ac0a46fSAndroid Build Coastguard Worker l_parent_node0 = l_parent_node;
117*3ac0a46fSAndroid Build Coastguard Worker } else {
118*3ac0a46fSAndroid Build Coastguard Worker l_parent_node = l_parent_node0;
119*3ac0a46fSAndroid Build Coastguard Worker l_parent_node0 += nplh[i];
120*3ac0a46fSAndroid Build Coastguard Worker }
121*3ac0a46fSAndroid Build Coastguard Worker }
122*3ac0a46fSAndroid Build Coastguard Worker }
123*3ac0a46fSAndroid Build Coastguard Worker node->parent = 0;
124*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_reset(tree);
125*3ac0a46fSAndroid Build Coastguard Worker return tree;
126*3ac0a46fSAndroid Build Coastguard Worker }
127*3ac0a46fSAndroid Build Coastguard Worker
128*3ac0a46fSAndroid Build Coastguard Worker /**
129*3ac0a46fSAndroid Build Coastguard Worker * Reinitialises a tag-tree from an existing one.
130*3ac0a46fSAndroid Build Coastguard Worker *
131*3ac0a46fSAndroid Build Coastguard Worker * @param p_tree the tree to reinitialize.
132*3ac0a46fSAndroid Build Coastguard Worker * @param p_num_leafs_h the width of the array of leafs of the tree
133*3ac0a46fSAndroid Build Coastguard Worker * @param p_num_leafs_v the height of the array of leafs of the tree
134*3ac0a46fSAndroid Build Coastguard Worker * @return a new tag-tree if successful, NULL otherwise
135*3ac0a46fSAndroid Build Coastguard Worker */
opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h,OPJ_UINT32 p_num_leafs_v,opj_event_mgr_t * p_manager)136*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree, OPJ_UINT32 p_num_leafs_h,
137*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 p_num_leafs_v, opj_event_mgr_t *p_manager)
138*3ac0a46fSAndroid Build Coastguard Worker {
139*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 l_nplh[32];
140*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 l_nplv[32];
141*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *l_node = 00;
142*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *l_parent_node = 00;
143*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *l_parent_node0 = 00;
144*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 i;
145*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 j, k;
146*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 l_num_levels;
147*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 n;
148*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 l_node_size;
149*3ac0a46fSAndroid Build Coastguard Worker
150*3ac0a46fSAndroid Build Coastguard Worker if (! p_tree) {
151*3ac0a46fSAndroid Build Coastguard Worker return 00;
152*3ac0a46fSAndroid Build Coastguard Worker }
153*3ac0a46fSAndroid Build Coastguard Worker
154*3ac0a46fSAndroid Build Coastguard Worker if ((p_tree->numleafsh != p_num_leafs_h) ||
155*3ac0a46fSAndroid Build Coastguard Worker (p_tree->numleafsv != p_num_leafs_v)) {
156*3ac0a46fSAndroid Build Coastguard Worker p_tree->numleafsh = p_num_leafs_h;
157*3ac0a46fSAndroid Build Coastguard Worker p_tree->numleafsv = p_num_leafs_v;
158*3ac0a46fSAndroid Build Coastguard Worker
159*3ac0a46fSAndroid Build Coastguard Worker l_num_levels = 0;
160*3ac0a46fSAndroid Build Coastguard Worker l_nplh[0] = (OPJ_INT32)p_num_leafs_h;
161*3ac0a46fSAndroid Build Coastguard Worker l_nplv[0] = (OPJ_INT32)p_num_leafs_v;
162*3ac0a46fSAndroid Build Coastguard Worker p_tree->numnodes = 0;
163*3ac0a46fSAndroid Build Coastguard Worker do {
164*3ac0a46fSAndroid Build Coastguard Worker n = (OPJ_UINT32)(l_nplh[l_num_levels] * l_nplv[l_num_levels]);
165*3ac0a46fSAndroid Build Coastguard Worker l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2;
166*3ac0a46fSAndroid Build Coastguard Worker l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2;
167*3ac0a46fSAndroid Build Coastguard Worker p_tree->numnodes += n;
168*3ac0a46fSAndroid Build Coastguard Worker ++l_num_levels;
169*3ac0a46fSAndroid Build Coastguard Worker } while (n > 1);
170*3ac0a46fSAndroid Build Coastguard Worker
171*3ac0a46fSAndroid Build Coastguard Worker /* ADD */
172*3ac0a46fSAndroid Build Coastguard Worker if (p_tree->numnodes == 0) {
173*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_destroy(p_tree);
174*3ac0a46fSAndroid Build Coastguard Worker return 00;
175*3ac0a46fSAndroid Build Coastguard Worker }
176*3ac0a46fSAndroid Build Coastguard Worker l_node_size = p_tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
177*3ac0a46fSAndroid Build Coastguard Worker
178*3ac0a46fSAndroid Build Coastguard Worker if (l_node_size > p_tree->nodes_size) {
179*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t* new_nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes,
180*3ac0a46fSAndroid Build Coastguard Worker l_node_size);
181*3ac0a46fSAndroid Build Coastguard Worker if (! new_nodes) {
182*3ac0a46fSAndroid Build Coastguard Worker opj_event_msg(p_manager, EVT_ERROR,
183*3ac0a46fSAndroid Build Coastguard Worker "Not enough memory to reinitialize the tag tree\n");
184*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_destroy(p_tree);
185*3ac0a46fSAndroid Build Coastguard Worker return 00;
186*3ac0a46fSAndroid Build Coastguard Worker }
187*3ac0a46fSAndroid Build Coastguard Worker p_tree->nodes = new_nodes;
188*3ac0a46fSAndroid Build Coastguard Worker memset(((char *) p_tree->nodes) + p_tree->nodes_size, 0,
189*3ac0a46fSAndroid Build Coastguard Worker l_node_size - p_tree->nodes_size);
190*3ac0a46fSAndroid Build Coastguard Worker p_tree->nodes_size = l_node_size;
191*3ac0a46fSAndroid Build Coastguard Worker }
192*3ac0a46fSAndroid Build Coastguard Worker l_node = p_tree->nodes;
193*3ac0a46fSAndroid Build Coastguard Worker l_parent_node = &p_tree->nodes[p_tree->numleafsh * p_tree->numleafsv];
194*3ac0a46fSAndroid Build Coastguard Worker l_parent_node0 = l_parent_node;
195*3ac0a46fSAndroid Build Coastguard Worker
196*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < l_num_levels - 1; ++i) {
197*3ac0a46fSAndroid Build Coastguard Worker for (j = 0; j < l_nplv[i]; ++j) {
198*3ac0a46fSAndroid Build Coastguard Worker k = l_nplh[i];
199*3ac0a46fSAndroid Build Coastguard Worker while (--k >= 0) {
200*3ac0a46fSAndroid Build Coastguard Worker l_node->parent = l_parent_node;
201*3ac0a46fSAndroid Build Coastguard Worker ++l_node;
202*3ac0a46fSAndroid Build Coastguard Worker if (--k >= 0) {
203*3ac0a46fSAndroid Build Coastguard Worker l_node->parent = l_parent_node;
204*3ac0a46fSAndroid Build Coastguard Worker ++l_node;
205*3ac0a46fSAndroid Build Coastguard Worker }
206*3ac0a46fSAndroid Build Coastguard Worker ++l_parent_node;
207*3ac0a46fSAndroid Build Coastguard Worker }
208*3ac0a46fSAndroid Build Coastguard Worker if ((j & 1) || j == l_nplv[i] - 1) {
209*3ac0a46fSAndroid Build Coastguard Worker l_parent_node0 = l_parent_node;
210*3ac0a46fSAndroid Build Coastguard Worker } else {
211*3ac0a46fSAndroid Build Coastguard Worker l_parent_node = l_parent_node0;
212*3ac0a46fSAndroid Build Coastguard Worker l_parent_node0 += l_nplh[i];
213*3ac0a46fSAndroid Build Coastguard Worker }
214*3ac0a46fSAndroid Build Coastguard Worker }
215*3ac0a46fSAndroid Build Coastguard Worker }
216*3ac0a46fSAndroid Build Coastguard Worker l_node->parent = 0;
217*3ac0a46fSAndroid Build Coastguard Worker }
218*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_reset(p_tree);
219*3ac0a46fSAndroid Build Coastguard Worker
220*3ac0a46fSAndroid Build Coastguard Worker return p_tree;
221*3ac0a46fSAndroid Build Coastguard Worker }
222*3ac0a46fSAndroid Build Coastguard Worker
opj_tgt_destroy(opj_tgt_tree_t * p_tree)223*3ac0a46fSAndroid Build Coastguard Worker void opj_tgt_destroy(opj_tgt_tree_t *p_tree)
224*3ac0a46fSAndroid Build Coastguard Worker {
225*3ac0a46fSAndroid Build Coastguard Worker if (! p_tree) {
226*3ac0a46fSAndroid Build Coastguard Worker return;
227*3ac0a46fSAndroid Build Coastguard Worker }
228*3ac0a46fSAndroid Build Coastguard Worker
229*3ac0a46fSAndroid Build Coastguard Worker if (p_tree->nodes) {
230*3ac0a46fSAndroid Build Coastguard Worker opj_free(p_tree->nodes);
231*3ac0a46fSAndroid Build Coastguard Worker p_tree->nodes = 00;
232*3ac0a46fSAndroid Build Coastguard Worker }
233*3ac0a46fSAndroid Build Coastguard Worker opj_free(p_tree);
234*3ac0a46fSAndroid Build Coastguard Worker }
235*3ac0a46fSAndroid Build Coastguard Worker
opj_tgt_reset(opj_tgt_tree_t * p_tree)236*3ac0a46fSAndroid Build Coastguard Worker void opj_tgt_reset(opj_tgt_tree_t *p_tree)
237*3ac0a46fSAndroid Build Coastguard Worker {
238*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 i;
239*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t * l_current_node = 00;;
240*3ac0a46fSAndroid Build Coastguard Worker
241*3ac0a46fSAndroid Build Coastguard Worker if (! p_tree) {
242*3ac0a46fSAndroid Build Coastguard Worker return;
243*3ac0a46fSAndroid Build Coastguard Worker }
244*3ac0a46fSAndroid Build Coastguard Worker
245*3ac0a46fSAndroid Build Coastguard Worker l_current_node = p_tree->nodes;
246*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < p_tree->numnodes; ++i) {
247*3ac0a46fSAndroid Build Coastguard Worker l_current_node->value = 999;
248*3ac0a46fSAndroid Build Coastguard Worker l_current_node->low = 0;
249*3ac0a46fSAndroid Build Coastguard Worker l_current_node->known = 0;
250*3ac0a46fSAndroid Build Coastguard Worker ++l_current_node;
251*3ac0a46fSAndroid Build Coastguard Worker }
252*3ac0a46fSAndroid Build Coastguard Worker }
253*3ac0a46fSAndroid Build Coastguard Worker
opj_tgt_setvalue(opj_tgt_tree_t * tree,OPJ_UINT32 leafno,OPJ_INT32 value)254*3ac0a46fSAndroid Build Coastguard Worker void opj_tgt_setvalue(opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 value)
255*3ac0a46fSAndroid Build Coastguard Worker {
256*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *node;
257*3ac0a46fSAndroid Build Coastguard Worker node = &tree->nodes[leafno];
258*3ac0a46fSAndroid Build Coastguard Worker while (node && node->value > value) {
259*3ac0a46fSAndroid Build Coastguard Worker node->value = value;
260*3ac0a46fSAndroid Build Coastguard Worker node = node->parent;
261*3ac0a46fSAndroid Build Coastguard Worker }
262*3ac0a46fSAndroid Build Coastguard Worker }
263*3ac0a46fSAndroid Build Coastguard Worker
opj_tgt_encode(opj_bio_t * bio,opj_tgt_tree_t * tree,OPJ_UINT32 leafno,OPJ_INT32 threshold)264*3ac0a46fSAndroid Build Coastguard Worker void opj_tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno,
265*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 threshold)
266*3ac0a46fSAndroid Build Coastguard Worker {
267*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *stk[31];
268*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t **stkptr;
269*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *node;
270*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 low;
271*3ac0a46fSAndroid Build Coastguard Worker
272*3ac0a46fSAndroid Build Coastguard Worker stkptr = stk;
273*3ac0a46fSAndroid Build Coastguard Worker node = &tree->nodes[leafno];
274*3ac0a46fSAndroid Build Coastguard Worker while (node->parent) {
275*3ac0a46fSAndroid Build Coastguard Worker *stkptr++ = node;
276*3ac0a46fSAndroid Build Coastguard Worker node = node->parent;
277*3ac0a46fSAndroid Build Coastguard Worker }
278*3ac0a46fSAndroid Build Coastguard Worker
279*3ac0a46fSAndroid Build Coastguard Worker low = 0;
280*3ac0a46fSAndroid Build Coastguard Worker for (;;) {
281*3ac0a46fSAndroid Build Coastguard Worker if (low > node->low) {
282*3ac0a46fSAndroid Build Coastguard Worker node->low = low;
283*3ac0a46fSAndroid Build Coastguard Worker } else {
284*3ac0a46fSAndroid Build Coastguard Worker low = node->low;
285*3ac0a46fSAndroid Build Coastguard Worker }
286*3ac0a46fSAndroid Build Coastguard Worker
287*3ac0a46fSAndroid Build Coastguard Worker while (low < threshold) {
288*3ac0a46fSAndroid Build Coastguard Worker if (low >= node->value) {
289*3ac0a46fSAndroid Build Coastguard Worker if (!node->known) {
290*3ac0a46fSAndroid Build Coastguard Worker opj_bio_write(bio, 1, 1);
291*3ac0a46fSAndroid Build Coastguard Worker node->known = 1;
292*3ac0a46fSAndroid Build Coastguard Worker }
293*3ac0a46fSAndroid Build Coastguard Worker break;
294*3ac0a46fSAndroid Build Coastguard Worker }
295*3ac0a46fSAndroid Build Coastguard Worker opj_bio_write(bio, 0, 1);
296*3ac0a46fSAndroid Build Coastguard Worker ++low;
297*3ac0a46fSAndroid Build Coastguard Worker }
298*3ac0a46fSAndroid Build Coastguard Worker
299*3ac0a46fSAndroid Build Coastguard Worker node->low = low;
300*3ac0a46fSAndroid Build Coastguard Worker if (stkptr == stk) {
301*3ac0a46fSAndroid Build Coastguard Worker break;
302*3ac0a46fSAndroid Build Coastguard Worker }
303*3ac0a46fSAndroid Build Coastguard Worker node = *--stkptr;
304*3ac0a46fSAndroid Build Coastguard Worker }
305*3ac0a46fSAndroid Build Coastguard Worker }
306*3ac0a46fSAndroid Build Coastguard Worker
opj_tgt_decode(opj_bio_t * bio,opj_tgt_tree_t * tree,OPJ_UINT32 leafno,OPJ_INT32 threshold)307*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 opj_tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree,
308*3ac0a46fSAndroid Build Coastguard Worker OPJ_UINT32 leafno, OPJ_INT32 threshold)
309*3ac0a46fSAndroid Build Coastguard Worker {
310*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *stk[31];
311*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t **stkptr;
312*3ac0a46fSAndroid Build Coastguard Worker opj_tgt_node_t *node;
313*3ac0a46fSAndroid Build Coastguard Worker OPJ_INT32 low;
314*3ac0a46fSAndroid Build Coastguard Worker
315*3ac0a46fSAndroid Build Coastguard Worker stkptr = stk;
316*3ac0a46fSAndroid Build Coastguard Worker node = &tree->nodes[leafno];
317*3ac0a46fSAndroid Build Coastguard Worker while (node->parent) {
318*3ac0a46fSAndroid Build Coastguard Worker *stkptr++ = node;
319*3ac0a46fSAndroid Build Coastguard Worker node = node->parent;
320*3ac0a46fSAndroid Build Coastguard Worker }
321*3ac0a46fSAndroid Build Coastguard Worker
322*3ac0a46fSAndroid Build Coastguard Worker low = 0;
323*3ac0a46fSAndroid Build Coastguard Worker for (;;) {
324*3ac0a46fSAndroid Build Coastguard Worker if (low > node->low) {
325*3ac0a46fSAndroid Build Coastguard Worker node->low = low;
326*3ac0a46fSAndroid Build Coastguard Worker } else {
327*3ac0a46fSAndroid Build Coastguard Worker low = node->low;
328*3ac0a46fSAndroid Build Coastguard Worker }
329*3ac0a46fSAndroid Build Coastguard Worker while (low < threshold && low < node->value) {
330*3ac0a46fSAndroid Build Coastguard Worker if (opj_bio_read(bio, 1)) {
331*3ac0a46fSAndroid Build Coastguard Worker node->value = low;
332*3ac0a46fSAndroid Build Coastguard Worker } else {
333*3ac0a46fSAndroid Build Coastguard Worker ++low;
334*3ac0a46fSAndroid Build Coastguard Worker }
335*3ac0a46fSAndroid Build Coastguard Worker }
336*3ac0a46fSAndroid Build Coastguard Worker node->low = low;
337*3ac0a46fSAndroid Build Coastguard Worker if (stkptr == stk) {
338*3ac0a46fSAndroid Build Coastguard Worker break;
339*3ac0a46fSAndroid Build Coastguard Worker }
340*3ac0a46fSAndroid Build Coastguard Worker node = *--stkptr;
341*3ac0a46fSAndroid Build Coastguard Worker }
342*3ac0a46fSAndroid Build Coastguard Worker
343*3ac0a46fSAndroid Build Coastguard Worker return (node->value < threshold) ? 1 : 0;
344*3ac0a46fSAndroid Build Coastguard Worker }
345