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