/*
 * Copyright (c) 2006 Konstantin Shishkov
 * Copyright (c) 2007 Loren Merritt
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * huffman tree builder and VLC generator
 */

#include <stdint.h>

#include "libavutil/qsort.h"
#include"libavutil/common.h"

#include "avcodec.h"
#include "huffman.h"
#include "vlc.h"

/* symbol for Huffman tree node */
#define HNODE -1

typedef struct HeapElem {
    uint64_t val;
    int name;
} HeapElem;

static void heap_sift(HeapElem *h, int root, int size)
{
    while (root * 2 + 1 < size) {
        int child = root * 2 + 1;
        if (child < size - 1 && h[child].val > h[child+1].val)
            child++;
        if (h[root].val > h[child].val) {
            FFSWAP(HeapElem, h[root], h[child]);
            root = child;
        } else
            break;
    }
}

int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int stats_size, int skip0)
{
    HeapElem *h  = av_malloc_array(sizeof(*h), stats_size);
    int *up      = av_malloc_array(sizeof(*up) * 2, stats_size);
    uint8_t *len = av_malloc_array(sizeof(*len) * 2, stats_size);
    uint16_t *map= av_malloc_array(sizeof(*map), stats_size);
    int offset, i, next;
    int size = 0;
    int ret = 0;

    if (!h || !up || !len || !map) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    for (i = 0; i<stats_size; i++) {
        dst[i] = 255;
        if (stats[i] || !skip0)
            map[size++] = i;
    }

    for (offset = 1; ; offset <<= 1) {
        for (i=0; i < size; i++) {
            h[i].name = i;
            h[i].val = (stats[map[i]] << 14) + offset;
        }
        for (i = size / 2 - 1; i >= 0; i--)
            heap_sift(h, i, size);

        for (next = size; next < size * 2 - 1; next++) {
            // merge the two smallest entries, and put it back in the heap
            uint64_t min1v = h[0].val;
            up[h[0].name] = next;
            h[0].val = INT64_MAX;
            heap_sift(h, 0, size);
            up[h[0].name] = next;
            h[0].name = next;
            h[0].val += min1v;
            heap_sift(h, 0, size);
        }

        len[2 * size - 2] = 0;
        for (i = 2 * size - 3; i >= size; i--)
            len[i] = len[up[i]] + 1;
        for (i = 0; i < size; i++) {
            dst[map[i]] = len[up[i]] + 1;
            if (dst[map[i]] >= 32) break;
        }
        if (i==size) break;
    }
end:
    av_free(h);
    av_free(up);
    av_free(len);
    av_free(map);
    return ret;
}

static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,
                           Node *nodes, int node,
                           uint32_t pfx, int pl, int *pos, int no_zero_count)
{
    int s;

    s = nodes[node].sym;
    if (s != HNODE || (no_zero_count && !nodes[node].count)) {
        bits[*pos] = pfx;
        lens[*pos] = pl;
        xlat[*pos] = s;
        (*pos)++;
    } else {
        pfx <<= 1;
        pl++;
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl,
                       pos, no_zero_count);
        pfx |= 1;
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0 + 1, pfx, pl,
                       pos, no_zero_count);
    }
}

static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags, int nb_bits)
{
    int no_zero_count = !(flags & FF_HUFFMAN_FLAG_ZERO_COUNT);
    uint32_t bits[256];
    int16_t lens[256];
    uint8_t xlat[256];
    int pos = 0;

    get_tree_codes(bits, lens, xlat, nodes, head, 0, 0,
                   &pos, no_zero_count);
    return ff_init_vlc_sparse(vlc, nb_bits, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
}


/**
 * nodes size must be 2*nb_codes
 * first nb_codes nodes.count must be set
 */
int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, int nb_bits,
                       Node *nodes, HuffCmp cmp, int flags)
{
    int i, j;
    int cur_node;
    int64_t sum = 0;

    for (i = 0; i < nb_codes; i++) {
        nodes[i].sym = i;
        nodes[i].n0 = -2;
        sum += nodes[i].count;
    }

    if (sum >> 31) {
        av_log(avctx, AV_LOG_ERROR,
               "Too high symbol frequencies. "
               "Tree construction is not possible\n");
        return -1;
    }
    AV_QSORT(nodes, nb_codes, Node, cmp);
    cur_node = nb_codes;
    nodes[nb_codes*2-1].count = 0;
    for (i = 0; i < nb_codes * 2 - 1; i += 2) {
        uint32_t cur_count = nodes[i].count + nodes[i+1].count;
        // find correct place to insert new node, and
        // make space for the new node while at it
        for(j = cur_node; j > i + 2; j--){
            if(cur_count > nodes[j-1].count ||
               (cur_count == nodes[j-1].count &&
                !(flags & FF_HUFFMAN_FLAG_HNODE_FIRST)))
                break;
            nodes[j] = nodes[j - 1];
        }
        nodes[j].sym = HNODE;
        nodes[j].count = cur_count;
        nodes[j].n0 = i;
        cur_node++;
    }
    if (build_huff_tree(vlc, nodes, nb_codes * 2 - 2, flags, nb_bits) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Error building tree\n");
        return -1;
    }
    return 0;
}
