xref: /aosp_15_r20/external/pdfium/third_party/libopenjpeg/tgt.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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