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