Reformat whole codebase with astyle.options (#128)
[openjpeg.git] / src / lib / openjp3d / tgt.c
1 /*
2  * The copyright in this software is being made available under the 2-clauses
3  * BSD License, included below. This software may be subject to other third
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2001-2003, David Janssens
8  * Copyright (c) 2002-2003, Yannick Verschueren
9  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
10  * Copyright (c) 2005, Herve Drolon, FreeImage Team
11  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include "opj_includes.h"
37
38 /*
39 ==========================================================
40    Tag-tree coder interface
41 ==========================================================
42 */
43 void tgt_tree_dump(FILE *fd, opj_tgt_tree_t * tree)
44 {
45     int nodesno;
46
47     fprintf(fd, "TGT_TREE {\n");
48     fprintf(fd, "  numnodes: %d \n", tree->numnodes);
49     fprintf(fd, "  numleafsh: %d, numleafsv: %d, numleafsz: %d,\n", tree->numleafsh,
50             tree->numleafsv, tree->numleafsz);
51
52     for (nodesno = 0; nodesno < tree->numnodes; nodesno++) {
53         fprintf(fd, "tgt_node %d {\n", nodesno);
54         fprintf(fd, "  value: %d \n", tree->nodes[nodesno].value);
55         fprintf(fd, "  low: %d \n", tree->nodes[nodesno].low);
56         fprintf(fd, "  known: %d \n", tree->nodes[nodesno].known);
57         if (tree->nodes[nodesno].parent) {
58             fprintf(fd, "  parent.value: %d \n", tree->nodes[nodesno].parent->value);
59             fprintf(fd, "  parent.low: %d \n", tree->nodes[nodesno].parent->low);
60             fprintf(fd, "  parent.known: %d \n", tree->nodes[nodesno].parent->known);
61         }
62         fprintf(fd, "}\n");
63
64     }
65     fprintf(fd, "}\n");
66
67 }
68
69
70 opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz)
71 {
72
73     int nplh[32];
74     int nplv[32];
75     int nplz[32];
76     opj_tgt_node_t *node = NULL;
77     opj_tgt_node_t *parentnode = NULL;
78     opj_tgt_node_t *parentnode0 = NULL;
79     opj_tgt_node_t *parentnode1 = NULL;
80     opj_tgt_tree_t *tree = NULL;
81     int i, j, k, p, p0;
82     int numlvls;
83     int n, z = 0;
84
85     tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
86     if (!tree) {
87         return NULL;
88     }
89     tree->numleafsh = numleafsh;
90     tree->numleafsv = numleafsv;
91     tree->numleafsz = numleafsz;
92
93     numlvls = 0;
94     nplh[0] = numleafsh;
95     nplv[0] = numleafsv;
96     nplz[0] = numleafsz;
97     tree->numnodes = 0;
98     do {
99         n = nplh[numlvls] * nplv[numlvls] * nplz[numlvls];
100         nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
101         nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
102         nplz[numlvls + 1] = (nplz[numlvls] + 1) / 2;
103         tree->numnodes += n;
104         ++numlvls;
105     } while (n > 1);
106
107     if (tree->numnodes == 0) {
108         opj_free(tree);
109         return NULL;
110     }
111
112     tree->nodes = (opj_tgt_node_t *) opj_malloc(tree->numnodes * sizeof(
113                       opj_tgt_node_t));
114     if (!tree->nodes) {
115         opj_free(tree);
116         return NULL;
117     }
118
119     node = tree->nodes;
120     parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv * tree->numleafsz];
121     parentnode0 = parentnode;
122     parentnode1 = parentnode;
123     /*fprintf(stdout,"\nH %d V %d Z %d numlvls %d nodes %d\n",tree->numleafsh,tree->numleafsv,tree->numleafsz,numlvls,tree->numnodes);*/
124     for (i = 0; i < numlvls - 1; ++i) {
125         for (z = 0; z < nplz[i]; ++z) {
126             for (j = 0; j < nplv[i]; ++j) {
127                 k = nplh[i];
128                 while (--k >= 0) {
129                     node->parent =
130                         parentnode;      /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/
131                     ++node;
132                     if (--k >= 0) {
133                         node->parent =
134                             parentnode;  /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/
135                         ++node;
136                     }
137                     ++parentnode;
138                 }
139                 if ((j & 1) || j == nplv[i] - 1) {
140                     parentnode0 = parentnode;
141                 } else {
142                     parentnode = parentnode0;
143                 }
144             }
145             if ((z & 1) || z == nplz[i] - 1) {
146                 parentnode1 = parentnode;
147             } else {
148                 parentnode0 = parentnode1;
149                 parentnode = parentnode1;
150             }
151         }
152     }
153     node->parent = 0;
154
155
156     tgt_reset(tree);
157
158     return tree;
159 }
160
161 void tgt_destroy(opj_tgt_tree_t *tree)
162 {
163     opj_free(tree->nodes);
164     opj_free(tree);
165 }
166
167 void tgt_reset(opj_tgt_tree_t *tree)
168 {
169     int i;
170
171     if (NULL == tree) {
172         return;
173     }
174
175     for (i = 0; i < tree->numnodes; i++) {
176         tree->nodes[i].value = 999;
177         tree->nodes[i].low = 0;
178         tree->nodes[i].known = 0;
179     }
180 }
181
182 void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value)
183 {
184     opj_tgt_node_t *node;
185     node = &tree->nodes[leafno];
186     while (node && node->value > value) {
187         node->value = value;
188         node = node->parent;
189     }
190 }
191
192 void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno,
193                 int threshold)
194 {
195     opj_tgt_node_t *stk[31];
196     opj_tgt_node_t **stkptr;
197     opj_tgt_node_t *node;
198     int low;
199
200     stkptr = stk;
201     node = &tree->nodes[leafno];
202     while (node->parent) {
203         *stkptr++ = node;
204         node = node->parent;
205     }
206
207     low = 0;
208     for (;;) {
209         if (low > node->low) {
210             node->low = low;
211         } else {
212             low = node->low;
213         }
214
215         while (low < threshold) {
216             if (low >= node->value) {
217                 if (!node->known) {
218                     bio_write(bio, 1, 1);
219                     node->known = 1;
220                 }
221                 break;
222             }
223             bio_write(bio, 0, 1);
224             ++low;
225         }
226
227         node->low = low;
228         if (stkptr == stk) {
229             break;
230         }
231         node = *--stkptr;
232     }
233 }
234
235 int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold)
236 {
237     opj_tgt_node_t *stk[31];
238     opj_tgt_node_t **stkptr;
239     opj_tgt_node_t *node;
240     int low;
241
242     stkptr = stk;
243     node = &tree->nodes[leafno];
244     while (node->parent) {
245         *stkptr++ = node;
246         node = node->parent;
247     }
248
249     low = 0;
250     for (;;) {
251         if (low > node->low) {
252             node->low = low;
253         } else {
254             low = node->low;
255         }
256         while (low < threshold && low < node->value) {
257             if (bio_read(bio, 1)) {
258                 node->value = low;
259             } else {
260                 ++low;
261             }
262         }
263         node->low = low;
264         if (stkptr == stk) {
265             break;
266         }
267         node = *--stkptr;
268     }
269
270     return (node->value < threshold) ? 1 : 0;
271 }