Sigrid Solveig HaflínudóttirPlan 9 portf19cd855 years agoHistory
615 lines · 14.8 KB · C
RawDownload
/****************************************************************************    Huffman coding     Copyright (C) 2017 Krzysztof Nikiel     This program is free software: you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or    (at your option) any later version.     This program 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 General Public License for more details.     You should have received a copy of the GNU General Public License    along with this program.  If not, see <http://www.gnu.org/licenses/>.****************************************************************************/ #include "util.h"#include "coder.h"#include "huffdata.h"#include "huff2.h"#include "bitstream.h" #ifdef DRMstatic int vcb11;#endif static int escape(int x, int *code){    int preflen = 0;    int base = 32;     if (x >= 8192)    {        fprintf(stderr, "%s(%d): x_quant >= 8192\n", __FILE__, __LINE__);        return 0;    }     *code = 0;    while (base <= x)    {        base <<= 1;        *code <<= 1;        *code |= 1;        preflen++;    }    base >>= 1;     // separator    *code <<= 1;     *code <<= (preflen + 4);    *code |= (x - base);     return (preflen << 1) + 5;} #ifdef DRM# define DRMDATA if(coder){coder->num_data_cw[coder->cur_cw++]=1;\    coder->iLenReordSpData+=blen;if(coder->iLenLongestCW<blen)\    coder->iLenLongestCW=blen;}#else# define DRMDATA#endif #define arrlen(array) (sizeof(array) / sizeof(*array)) static int huffcode(int *qs /* quantized spectrum */,                    int len,                    int bnum,                    CoderInfo *coder){    static hcode16_t * const hmap[12] = {0, book01, book02, book03, book04,      book05, book06, book07, book08, book09, book10, book11};    hcode16_t *book;    int cnt;    int bits = 0, blen;    int ofs, *qp;    int data;    int idx;    int datacnt;#ifdef DRM    int drmbits = 0;    int maxesc = 0;#endif     if (coder)        datacnt = coder->datacnt;    else        datacnt = 0;     book = hmap[bnum];    switch (bnum)    {#ifdef DRM    case HCB_ZERO:    case HCB_INTENSITY:    case HCB_INTENSITY2:        for(ofs = 0; ofs < len; ofs += 4)        {            coder->s[datacnt].data = 0;            coder->s[datacnt++].len = 0;            coder->num_data_cw[coder->cur_cw++] = 1;        }        break;#endif    case 1:    case 2:        for(ofs = 0; ofs < len; ofs += 4)        {            qp = qs+ofs;            idx = 27 * qp[0] + 9 * qp[1] + 3 * qp[2] + qp[3] + 40;            if (idx < 0 || idx >= arrlen(book01))            {                return -1;            }            blen = book[idx].len;            if (coder)            {                data = book[idx].data;                coder->s[datacnt].data = data;                coder->s[datacnt++].len = blen;                DRMDATA;            }            bits += blen;        }        break;    case 3:    case 4:        for(ofs = 0; ofs < len; ofs += 4)        {            qp = qs+ofs;            idx = 27 * abs(qp[0]) + 9 * abs(qp[1]) + 3 * abs(qp[2]) + abs(qp[3]);            if (idx < 0 || idx >= arrlen(book03))            {                return -1;            }            blen = book[idx].len;            if (!coder)            {                // add sign bits                for(cnt = 0; cnt < 4; cnt++)                    if(qp[cnt])                        blen++;            }            else            {                data = book[idx].data;                // add sign bits                for(cnt = 0; cnt < 4; cnt++)                {                    if(qp[cnt])                    {                        blen++;                        data <<= 1;                        if (qp[cnt] < 0)                            data |= 1;                    }                }                coder->s[datacnt].data = data;                coder->s[datacnt++].len = blen;                DRMDATA;            }            bits += blen;        }        break;    case 5:    case 6:        for(ofs = 0; ofs < len; ofs += 2)        {            qp = qs+ofs;            idx = 9 * qp[0] + qp[1] + 40;            if (idx < 0 || idx >= arrlen(book05))            {                return -1;            }            blen = book[idx].len;            if (coder)            {                data = book[idx].data;                coder->s[datacnt].data = data;                coder->s[datacnt++].len = blen;                DRMDATA;            }            bits += blen;        }        break;    case 7:    case 8:        for(ofs = 0; ofs < len; ofs += 2)        {            qp = qs+ofs;            idx = 8 * abs(qp[0]) + abs(qp[1]);            if (idx < 0 || idx >= arrlen(book07))            {                return -1;            }            blen = book[idx].len;            if (!coder)            {                for(cnt = 0; cnt < 2; cnt++)                    if(qp[cnt])                        blen++;            }            else            {                data = book[idx].data;                for(cnt = 0; cnt < 2; cnt++)                {                    if(qp[cnt])                    {                        blen++;                        data <<= 1;                        if (qp[cnt] < 0)                            data |= 1;                    }                }                coder->s[datacnt].data = data;                coder->s[datacnt++].len = blen;                DRMDATA;            }            bits += blen;        }        break;    case 9:    case 10:        for(ofs = 0; ofs < len; ofs += 2)        {            qp = qs+ofs;            idx = 13 * abs(qp[0]) + abs(qp[1]);            if (idx < 0 || idx >= arrlen(book09))            {                return -1;            }            blen = book[idx].len;            if (!coder)            {                for(cnt = 0; cnt < 2; cnt++)                    if(qp[cnt])                        blen++;            }            else            {                data = book[idx].data;                for(cnt = 0; cnt < 2; cnt++)                {                    if(qp[cnt])                    {                        blen++;                        data <<= 1;                        if (qp[cnt] < 0)                            data |= 1;                    }                }                coder->s[datacnt].data = data;                coder->s[datacnt++].len = blen;                DRMDATA;            }            bits += blen;        }        break;    case HCB_ESC:        for(ofs = 0; ofs < len; ofs += 2)        {            int x0, x1;             qp = qs+ofs;             x0 = abs(qp[0]);            x1 = abs(qp[1]);            if (x0 > 16)                x0 = 16;            if (x1 > 16)                x1 = 16;            idx = 17 * x0 + x1;            if (idx < 0 || idx >= arrlen(book11))            {                return -1;            }             blen = book[idx].len;            if (!coder)            {                for(cnt = 0; cnt < 2; cnt++)                    if(qp[cnt])                        blen++;            }            else            {                data = book[idx].data;                for(cnt = 0; cnt < 2; cnt++)                {                    if(qp[cnt])                    {                        blen++;                        data <<= 1;                        if (qp[cnt] < 0)                            data |= 1;                    }                }                coder->s[datacnt].data = data;                coder->s[datacnt++].len = blen;#ifdef DRM                coder->num_data_cw[coder->cur_cw] = 1;                drmbits = blen;#endif            }            bits += blen;             if (x0 >= 16)            {                blen = escape(abs(qp[0]), &data);                if (coder)                {                    coder->s[datacnt].data = data;                    coder->s[datacnt++].len = blen;#ifdef DRM                    coder->num_data_cw[coder->cur_cw]++;                    drmbits += blen;                     if (maxesc < data)                        maxesc = data;#endif                }                bits += blen;            }             if (x1 >= 16)            {                blen = escape(abs(qp[1]), &data);                if (coder)                {                    coder->s[datacnt].data = data;                    coder->s[datacnt++].len = blen;#ifdef DRM                    coder->num_data_cw[coder->cur_cw]++;                    drmbits += blen;                     if (maxesc < data)                        maxesc = data;#endif                }                bits += blen;            }#ifdef DRM            coder->iLenReordSpData += drmbits;            if (coder->iLenLongestCW < drmbits)                coder->iLenLongestCW = drmbits;             coder->cur_cw++;#endif        }#ifdef DRM        /* VCB11: check which codebook should be used using max escape sequence */        /* 8.5.3.1.3, table 157 */        if (maxesc <= 15)            vcb11 = 16;        else if (maxesc <= 31)            vcb11 = 17;        else if (maxesc <= 47)            vcb11 = 18;        else if (maxesc <= 63)            vcb11 = 19;        else if (maxesc <= 95)            vcb11 = 20;        else if (maxesc <= 127)            vcb11 = 21;        else if (maxesc <= 159)            vcb11 = 22;        else if (maxesc <= 191)            vcb11 = 23;        else if (maxesc <= 223)            vcb11 = 24;        else if (maxesc <= 255)            vcb11 = 25;        else if (maxesc <= 319)            vcb11 = 26;        else if (maxesc <= 383)            vcb11 = 27;        else if (maxesc <= 511)            vcb11 = 28;        else if (maxesc <= 767)            vcb11 = 29;        else if (maxesc <= 1023)            vcb11 = 30;        else if (maxesc <= 2047)            vcb11 = 31;        /* else: codebook 11 -> it is already 11 */#endif        break;    default:        fprintf(stderr, "%s(%d) book %d out of range\n", __FILE__, __LINE__, bnum);        return -1;    }     if (coder)        coder->datacnt = datacnt;     return bits;}  int huffbook(CoderInfo *coder,             int *qs /* quantized spectrum */,             int len){    int cnt;    int maxq = 0;    int bookmin, lenmin;     for (cnt = 0; cnt < len; cnt++)    {        int q = abs(qs[cnt]);        if (maxq < q)            maxq = q;    } #define BOOKMIN(n)bookmin=n;lenmin=huffcode(qs,len,bookmin,0);if(huffcode(qs,len,bookmin+1,0)<lenmin)bookmin++;     if (maxq < 1)    {        bookmin = HCB_ZERO;        lenmin = 0;    }    else if (maxq < 2)    {        BOOKMIN(1);    }    else if (maxq < 3)    {        BOOKMIN(3);    }    else if (maxq < 5)    {        BOOKMIN(5);    }    else if (maxq < 8)    {        BOOKMIN(7);    }    else if (maxq < 13)    {        BOOKMIN(9);    }    else    {        bookmin = HCB_ESC;    } #ifdef DRM    vcb11 = 0;    huffcode(qs, len, bookmin, coder);    if (vcb11)        bookmin = vcb11;#else    if (bookmin > HCB_ZERO)        huffcode(qs, len, bookmin, coder);#endif    coder->book[coder->bandcnt] = bookmin;     return 0;} int writebooks(CoderInfo *coder, BitStream *stream, int write){    int bits = 0;    int maxcnt, cntbits;    int group;    int bookbits = 4; #ifdef DRM    bookbits = 5; /* 5 bits in case of VCB11 */#endif     if (coder->block_type == ONLY_SHORT_WINDOW){        maxcnt = 7;        cntbits = 3;    } else {        maxcnt = 31;        cntbits = 5;    }     for (group = 0; group < coder->groups.n; group++)    {        int band = group * coder->sfbn;        int maxband = band + coder->sfbn;         while (band < maxband)        {            int book = coder->book[band++];            int bookcnt = 1;            if (write) {                PutBit(stream, book, bookbits);            }            bits += bookbits; #ifdef DRM            /* sect_len is not transmitted in case the codebook for a */

Lines 1–500 of 615.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t