/*
 * The copyright in this software is being made available under the 2-clauses 
 * BSD License, included below. This software may be subject to other third 
 * party and contributor rights, including patent rights, and no such rights
 * are granted under this license.
 *
 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
 * Copyright (c) 2002-2014, Professor Benoit Macq
 * Copyright (c) 2001-2003, David Janssens
 * Copyright (c) 2002-2003, Yannick Verschueren
 * Copyright (c) 2003-2007, Francois-Olivier Devaux 
 * Copyright (c) 2003-2014, Antonin Descampe
 * Copyright (c) 2005, Herve Drolon, FreeImage Team
 * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR 
 * Copyright (c) 2012, CS Systemes d'Information, France
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "opj_includes.h"

/* 
==========================================================
   Tag-tree coder interface
==========================================================
*/

opj_tgt_tree_t *opj_tgt_create(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 while allocating tree\n");
                return 00;
        }
        memset(tree,0,sizeof(opj_tgt_tree_t));

        tree->numleafsh = numleafsh;
        tree->numleafsv = numleafsv;

        numlvls = 0;
        nplh[0] = (OPJ_INT32)numleafsh;
        nplv[0] = (OPJ_INT32)numleafsv;
        tree->numnodes = 0;
        do {
                n = (OPJ_UINT32)(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 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 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 * (OPJ_UINT32)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;
        opj_tgt_reset(tree);
        return tree;
}

/**
 * Reinitialises a tag-tree from an existing one.
 *
 * @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 *opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v)
{
        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] = (OPJ_INT32)p_num_leafs_h;
                l_nplv[0] = (OPJ_INT32)p_num_leafs_v;
                p_tree->numnodes = 0;
                do
                {
                        n = (OPJ_UINT32)(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) {
                        opj_tgt_destroy(p_tree);
                        return 00;
                }
                l_node_size = p_tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t);
                
                if (l_node_size > p_tree->nodes_size) {
                        opj_tgt_node_t* new_nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size);
                        if (! new_nodes) {
                                fprintf(stderr, "ERROR Not enough memory to reinitialize the tag tree\n");
                                opj_tgt_destroy(p_tree);
                                return 00;
                        }
                        p_tree->nodes = new_nodes;
                        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;
        }
        opj_tgt_reset(p_tree);

        return p_tree;
}

void opj_tgt_destroy(opj_tgt_tree_t *p_tree)
{
        if (! p_tree) {
                return;
        }

        if (p_tree->nodes) {
                opj_free(p_tree->nodes);
                p_tree->nodes = 00;
        }
        opj_free(p_tree);
}

void opj_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 opj_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;
                node = node->parent;
        }
}

void opj_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];
        while (node->parent) {
                *stkptr++ = node;
                node = node->parent;
        }
        
        low = 0;
        for (;;) {
                if (low > node->low) {
                        node->low = low;
                } else {
                        low = node->low;
                }
                
                while (low < threshold) {
                        if (low >= node->value) {
                                if (!node->known) {
                                        opj_bio_write(bio, 1, 1);
                                        node->known = 1;
                                }
                                break;
                        }
                        opj_bio_write(bio, 0, 1);
                        ++low;
                }
                
                node->low = low;
                if (stkptr == stk)
                        break;
                node = *--stkptr;
        }
}

OPJ_UINT32 opj_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];
        while (node->parent) {
                *stkptr++ = node;
                node = node->parent;
        }
        
        low = 0;
        for (;;) {
                if (low > node->low) {
                        node->low = low;
                } else {
                        low = node->low;
                }
                while (low < threshold && low < node->value) {
                        if (opj_bio_read(bio, 1)) {
                                node->value = low;
                        } else {
                                ++low;
                        }
                }
                node->low = low;
                if (stkptr == stk) {
                        break;
                }
                node = *--stkptr;
        }
        
        return (node->value < threshold) ? 1 : 0;
}
