[trunk] clean jp2_read_ihdr_v2 interface
[openjpeg.git] / libopenjpeg / tgt.c
index 4d4e2beb970cae5998dfc41be152136d268475f4..a663e85f568da409947a7f45876193ece75f05ea 100644 (file)
@@ -1,5 +1,10 @@
 /*
- * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "tgt.h"
-#include "bio.h"
-#include <stdlib.h>
-#include <stdio.h>
+#include "opj_includes.h"
 
-/* <summary> */
-/* Reset tag-tree. */
-/* </summary> */
-void tgt_reset(tgt_tree_t * tree)
-{
-       int i;
-       /* new */
-       if (!tree || tree == NULL)
-               return;
-
-       for (i = 0; i < tree->numnodes; i++) {
-               tree->nodes[i].value = 999;
-               tree->nodes[i].low = 0;
-               tree->nodes[i].known = 0;
-       }
-}
+/* 
+==========================================================
+   Tag-tree coder interface
+==========================================================
+*/
 
-/* <summary> */
-/* Create tag-tree. */
-/* </summary> */
-tgt_tree_t *tgt_create(int numleafsh, int numleafsv)
-{
+opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) {
        int nplh[32];
        int nplv[32];
-       tgt_node_t *node;
-       tgt_node_t *parentnode;
-       tgt_node_t *parentnode0;
-       tgt_tree_t *tree;
+       opj_tgt_node_t *node = NULL;
+       opj_tgt_node_t *parentnode = NULL;
+       opj_tgt_node_t *parentnode0 = NULL;
+       opj_tgt_tree_t *tree = NULL;
        int i, j, k;
        int numlvls;
        int n;
 
-       tree = (tgt_tree_t *) malloc(sizeof(tgt_tree_t));
+       tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
+       if(!tree) return NULL;
        tree->numleafsh = numleafsh;
        tree->numleafsv = numleafsv;
 
@@ -76,19 +64,23 @@ tgt_tree_t *tgt_create(int numleafsh, int numleafsv)
                tree->numnodes += n;
                ++numlvls;
        } while (n > 1);
-
+       
        /* ADD */
        if (tree->numnodes == 0) {
-               free(tree);
+               opj_free(tree);
                return NULL;
        }
 
-       tree->nodes = (tgt_node_t *) malloc(tree->numnodes * sizeof(tgt_node_t));
+       tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t));
+       if(!tree->nodes) {
+               opj_free(tree);
+               return NULL;
+       }
 
        node = tree->nodes;
        parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv];
        parentnode0 = parentnode;
-
+       
        for (i = 0; i < numlvls - 1; ++i) {
                for (j = 0; j < nplv[i]; ++j) {
                        k = nplh[i];
@@ -110,27 +102,250 @@ tgt_tree_t *tgt_create(int numleafsh, int numleafsv)
                }
        }
        node->parent = 0;
-
+       
        tgt_reset(tree);
+       
+       return tree;
+}
+
+opj_tgt_tree_t *tgt_create_v2(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) {
+       OPJ_INT32 nplh[32];
+       OPJ_INT32 nplv[32];
+       opj_tgt_node_t *node = 00;
+       opj_tgt_node_t *l_parent_node = 00;
+       opj_tgt_node_t *l_parent_node0 = 00;
+       opj_tgt_tree_t *tree = 00;
+       OPJ_UINT32 i;
+       OPJ_INT32  j,k;
+       OPJ_UINT32 numlvls;
+       OPJ_UINT32 n;
+
+       tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
+       if(!tree) {
+               fprintf(stderr, "ERROR in tgt_create_v2 while allocating tree\n");
+               return 00;
+       }
+       memset(tree,0,sizeof(opj_tgt_tree_t));
+
+       tree->numleafsh = numleafsh;
+       tree->numleafsv = numleafsv;
+
+       numlvls = 0;
+       nplh[0] = numleafsh;
+       nplv[0] = numleafsv;
+       tree->numnodes = 0;
+       do {
+               n = nplh[numlvls] * nplv[numlvls];
+               nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
+               nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
+               tree->numnodes += n;
+               ++numlvls;
+       } while (n > 1);
 
+       /* ADD */
+       if (tree->numnodes == 0) {
+               opj_free(tree);
+               fprintf(stderr, "WARNING in tgt_create_v2 tree->numnodes == 0, no tree created.\n");
+               return 00;
+       }
+
+       tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t));
+       if(!tree->nodes) {
+               fprintf(stderr, "ERROR in tgt_create_v2 while allocating node of the tree\n");
+               opj_free(tree);
+               return 00;
+       }
+       memset(tree->nodes,0,tree->numnodes * sizeof(opj_tgt_node_t));
+       tree->nodes_size = tree->numnodes * sizeof(opj_tgt_node_t);
+
+       node = tree->nodes;
+       l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv];
+       l_parent_node0 = l_parent_node;
+
+       for (i = 0; i < numlvls - 1; ++i) {
+               for (j = 0; j < nplv[i]; ++j) {
+                       k = nplh[i];
+                       while (--k >= 0) {
+                               node->parent = l_parent_node;
+                               ++node;
+                               if (--k >= 0) {
+                                       node->parent = l_parent_node;
+                                       ++node;
+                               }
+                               ++l_parent_node;
+                       }
+                       if ((j & 1) || j == nplv[i] - 1) {
+                               l_parent_node0 = l_parent_node;
+                       } else {
+                               l_parent_node = l_parent_node0;
+                               l_parent_node0 += nplh[i];
+                       }
+               }
+       }
+       node->parent = 0;
+       tgt_reset(tree);
        return tree;
 }
 
-/* <summary> */
-/* Destroy tag-tree. */
-/* </summary> */
-void tgt_destroy(tgt_tree_t * t)
+/**
+ * Reinitialises a tag-tree from an exixting one. (V2 framevork)
+ *
+ * @param      p_tree                          the tree to reinitialize.
+ * @param      p_num_leafs_h           the width of the array of leafs of the tree
+ * @param      p_num_leafs_v           the height of the array of leafs of the tree
+ * @return     a new tag-tree if successful, NULL otherwise
+*/
+opj_tgt_tree_t *tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v)
 {
-       free(t->nodes);
-       free(t);
+       OPJ_INT32 l_nplh[32];
+       OPJ_INT32 l_nplv[32];
+       opj_tgt_node_t *l_node = 00;
+       opj_tgt_node_t *l_parent_node = 00;
+       opj_tgt_node_t *l_parent_node0 = 00;
+       OPJ_UINT32 i;
+       OPJ_INT32 j,k;
+       OPJ_UINT32 l_num_levels;
+       OPJ_UINT32 n;
+       OPJ_UINT32 l_node_size;
+
+       if
+               (! p_tree)
+       {
+               return 00;
+       }
+       if
+               ((p_tree->numleafsh != p_num_leafs_h) || (p_tree->numleafsv != p_num_leafs_v))
+       {
+               p_tree->numleafsh = p_num_leafs_h;
+               p_tree->numleafsv = p_num_leafs_v;
+
+               l_num_levels = 0;
+               l_nplh[0] = p_num_leafs_h;
+               l_nplv[0] = p_num_leafs_v;
+               p_tree->numnodes = 0;
+               do
+               {
+                       n = l_nplh[l_num_levels] * l_nplv[l_num_levels];
+                       l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2;
+                       l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2;
+                       p_tree->numnodes += n;
+                       ++l_num_levels;
+               }
+               while (n > 1);
+
+               /* ADD */
+               if
+                       (p_tree->numnodes == 0)
+               {
+                       tgt_destroy(p_tree);
+            return 00;
+               }
+               l_node_size = p_tree->numnodes * sizeof(opj_tgt_node_t);
+               if
+                       (l_node_size > p_tree->nodes_size)
+               {
+                       p_tree->nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size);
+                       if
+                               (! p_tree->nodes)
+                       {
+                               tgt_destroy(p_tree);
+                               return 00;
+                       }
+                       memset(((char *) p_tree->nodes) + p_tree->nodes_size, 0 , l_node_size - p_tree->nodes_size);
+                       p_tree->nodes_size = l_node_size;
+               }
+               l_node = p_tree->nodes;
+               l_parent_node = &p_tree->nodes[p_tree->numleafsh * p_tree->numleafsv];
+               l_parent_node0 = l_parent_node;
+
+               for
+                       (i = 0; i < l_num_levels - 1; ++i)
+               {
+                       for
+                               (j = 0; j < l_nplv[i]; ++j)
+                       {
+                               k = l_nplh[i];
+                               while
+                                       (--k >= 0)
+                               {
+                                       l_node->parent = l_parent_node;
+                                       ++l_node;
+                                       if (--k >= 0)
+                                       {
+                                               l_node->parent = l_parent_node;
+                                               ++l_node;
+                                       }
+                                       ++l_parent_node;
+                               }
+                               if ((j & 1) || j == l_nplv[i] - 1)
+                               {
+                                       l_parent_node0 = l_parent_node;
+                               }
+                               else
+                               {
+                                       l_parent_node = l_parent_node0;
+                                       l_parent_node0 += l_nplh[i];
+                               }
+                       }
+               }
+               l_node->parent = 0;
+       }
+       tgt_reset(p_tree);
+
+       return p_tree;
 }
 
-/* <summary> */
-/* Set the value of a leaf of the tag-tree. */
-/* </summary> */
-void tgt_setvalue(tgt_tree_t * tree, int leafno, int value)
+/*void tgt_destroy(opj_tgt_tree_t *tree) {
+       opj_free(tree->nodes);
+       opj_free(tree);
+}*/
+
+void tgt_destroy(opj_tgt_tree_t *p_tree)
 {
-       tgt_node_t *node;
+       if (! p_tree) {
+               return;
+       }
+
+       if (p_tree->nodes) {
+               opj_free(p_tree->nodes);
+               p_tree->nodes = 00;
+       }
+       opj_free(p_tree);
+}
+
+/*void tgt_reset(opj_tgt_tree_t *tree) {
+       int i;
+
+       if (NULL == tree)
+               return;
+       
+       for (i = 0; i < tree->numnodes; i++) {
+               tree->nodes[i].value = 999;
+               tree->nodes[i].low = 0;
+               tree->nodes[i].known = 0;
+       }
+}*/
+
+void tgt_reset(opj_tgt_tree_t *p_tree) {
+       OPJ_UINT32 i;
+       opj_tgt_node_t * l_current_node = 00;;
+
+       if (! p_tree) {
+               return;
+       }
+
+       l_current_node = p_tree->nodes;
+       for     (i = 0; i < p_tree->numnodes; ++i)
+       {
+               l_current_node->value = 999;
+               l_current_node->low = 0;
+               l_current_node->known = 0;
+               ++l_current_node;
+       }
+}
+
+void tgt_setvalue(opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 value) {
+       opj_tgt_node_t *node;
        node = &tree->nodes[leafno];
        while (node && node->value > value) {
                node->value = value;
@@ -138,15 +353,11 @@ void tgt_setvalue(tgt_tree_t * tree, int leafno, int value)
        }
 }
 
-/* <summary> */
-/* Encode the value of a leaf of the tag-tree. */
-/* </summary> */
-void tgt_encode(tgt_tree_t * tree, int leafno, int threshold)
-{
-       tgt_node_t *stk[31];
-       tgt_node_t **stkptr;
-       tgt_node_t *node;
-       int low;
+void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) {
+       opj_tgt_node_t *stk[31];
+       opj_tgt_node_t **stkptr;
+       opj_tgt_node_t *node;
+       OPJ_INT32 low;
 
        stkptr = stk;
        node = &tree->nodes[leafno];
@@ -154,7 +365,7 @@ void tgt_encode(tgt_tree_t * tree, int leafno, int threshold)
                *stkptr++ = node;
                node = node->parent;
        }
-
+       
        low = 0;
        for (;;) {
                if (low > node->low) {
@@ -162,36 +373,31 @@ void tgt_encode(tgt_tree_t * tree, int leafno, int threshold)
                } else {
                        low = node->low;
                }
-
+               
                while (low < threshold) {
                        if (low >= node->value) {
                                if (!node->known) {
-                                       bio_write(1, 1);
+                                       bio_write(bio, 1, 1);
                                        node->known = 1;
                                }
                                break;
                        }
-                       bio_write(0, 1);
+                       bio_write(bio, 0, 1);
                        ++low;
                }
-
+               
                node->low = low;
                if (stkptr == stk)
                        break;
                node = *--stkptr;
        }
-
 }
 
-/* <summary> */
-/* Decode the value of a leaf of the tag-tree. */
-/* </summary> */
-int tgt_decode(tgt_tree_t * tree, int leafno, int threshold)
-{
-       tgt_node_t *stk[31];
-       tgt_node_t **stkptr;
-       tgt_node_t *node;
-       int low;
+OPJ_UINT32 tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) {
+       opj_tgt_node_t *stk[31];
+       opj_tgt_node_t **stkptr;
+       opj_tgt_node_t *node;
+       OPJ_INT32 low;
 
        stkptr = stk;
        node = &tree->nodes[leafno];
@@ -199,7 +405,7 @@ int tgt_decode(tgt_tree_t * tree, int leafno, int threshold)
                *stkptr++ = node;
                node = node->parent;
        }
-
+       
        low = 0;
        for (;;) {
                if (low > node->low) {
@@ -208,7 +414,7 @@ int tgt_decode(tgt_tree_t * tree, int leafno, int threshold)
                        low = node->low;
                }
                while (low < threshold && low < node->value) {
-                       if (bio_read(1)) {
+                       if (bio_read(bio, 1)) {
                                node->value = low;
                        } else {
                                ++low;
@@ -220,6 +426,6 @@ int tgt_decode(tgt_tree_t * tree, int leafno, int threshold)
                }
                node = *--stkptr;
        }
-
+       
        return (node->value < threshold) ? 1 : 0;
 }