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