Home | History | Annotate | Download | only in jbig2
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "JBig2_HuffmanTable.h"
      8 #include "JBig2_BitStream.h"
      9 #include <string.h>
     10 
     11 CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine *pTable, int nLines,
     12         FX_BOOL bHTOOB)
     13 {
     14     init();
     15     m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB);
     16 }
     17 
     18 CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream *pStream)
     19 {
     20     init();
     21     m_bOK = parseFromCodedBuffer(pStream);
     22 }
     23 
     24 CJBig2_HuffmanTable::~CJBig2_HuffmanTable()
     25 {
     26     if(CODES) {
     27         m_pModule->JBig2_Free(CODES);
     28     }
     29     if(PREFLEN) {
     30         m_pModule->JBig2_Free(PREFLEN);
     31     }
     32     if(RANGELEN) {
     33         m_pModule->JBig2_Free(RANGELEN);
     34     }
     35     if(RANGELOW) {
     36         m_pModule->JBig2_Free(RANGELOW);
     37     }
     38 }
     39 void CJBig2_HuffmanTable::init()
     40 {
     41     HTOOB = FALSE;
     42     NTEMP = 0;
     43     CODES = NULL;
     44     PREFLEN = NULL;
     45     RANGELEN = NULL;
     46     RANGELOW = NULL;
     47 }
     48 int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine *pTable, int nLines, FX_BOOL bHTOOB)
     49 {
     50     int CURLEN, LENMAX, CURCODE, CURTEMP, i;
     51     int *LENCOUNT;
     52     int *FIRSTCODE;
     53     HTOOB = bHTOOB;
     54     NTEMP = nLines;
     55     CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
     56     PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
     57     RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
     58     RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
     59     LENMAX = 0;
     60     for(i = 0; i < NTEMP; i++) {
     61         PREFLEN[i] = pTable[i].PREFLEN;
     62         RANGELEN[i] = pTable[i].RANDELEN;
     63         RANGELOW[i] = pTable[i].RANGELOW;
     64         if(PREFLEN[i] > LENMAX) {
     65             LENMAX = PREFLEN[i];
     66         }
     67     }
     68     LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
     69     JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
     70     FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
     71     for(i = 0; i < NTEMP; i++) {
     72         LENCOUNT[PREFLEN[i]] ++;
     73     }
     74     CURLEN = 1;
     75     FIRSTCODE[0] = 0;
     76     LENCOUNT[0]  = 0;
     77     while(CURLEN <= LENMAX) {
     78         FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
     79         CURCODE = FIRSTCODE[CURLEN];
     80         CURTEMP = 0;
     81         while(CURTEMP < NTEMP) {
     82             if(PREFLEN[CURTEMP] == CURLEN) {
     83                 CODES[CURTEMP] = CURCODE;
     84                 CURCODE = CURCODE + 1;
     85             }
     86             CURTEMP = CURTEMP + 1;
     87         }
     88         CURLEN = CURLEN + 1;
     89     }
     90     m_pModule->JBig2_Free(LENCOUNT);
     91     m_pModule->JBig2_Free(FIRSTCODE);
     92     return 1;
     93 }
     94 
     95 #define HT_CHECK_MEMORY_ADJUST			\
     96     if(NTEMP >= nSize)	\
     97     {	\
     98         nSize += 16;	\
     99         PREFLEN  = (int*)m_pModule->JBig2_Realloc(PREFLEN,sizeof(int)*nSize);	\
    100         RANGELEN = (int*)m_pModule->JBig2_Realloc(RANGELEN,sizeof(int)*nSize);	\
    101         RANGELOW = (int*)m_pModule->JBig2_Realloc(RANGELOW,sizeof(int)*nSize);	\
    102     }
    103 int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream *pStream)
    104 {
    105     unsigned char HTPS, HTRS;
    106     int HTLOW, HTHIGH;
    107     int CURRANGELOW;
    108     int nSize = 16;
    109     int CURLEN, LENMAX, CURCODE, CURTEMP, i;
    110     int *LENCOUNT;
    111     int *FIRSTCODE;
    112     unsigned char cTemp;
    113     if(pStream->read1Byte(&cTemp) == -1) {
    114         goto failed;
    115     }
    116     HTOOB = cTemp & 0x01;
    117     HTPS  = ((cTemp >> 1) & 0x07) + 1;
    118     HTRS  = ((cTemp >> 4) & 0x07) + 1;
    119     if(pStream->readInteger((FX_DWORD*)&HTLOW) == -1 ||
    120             pStream->readInteger((FX_DWORD*)&HTHIGH) == -1) {
    121         goto failed;
    122     }
    123     PREFLEN  = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
    124     RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
    125     RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
    126     CURRANGELOW = HTLOW;
    127     NTEMP = 0;
    128     do {
    129         HT_CHECK_MEMORY_ADJUST
    130         if((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
    131                 || (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
    132             goto failed;
    133         }
    134         RANGELOW[NTEMP] = CURRANGELOW;
    135         CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]);
    136         NTEMP = NTEMP + 1;
    137     } while(CURRANGELOW < HTHIGH);
    138     HT_CHECK_MEMORY_ADJUST
    139     if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
    140         goto failed;
    141     }
    142     RANGELEN[NTEMP] = 32;
    143     RANGELOW[NTEMP] = HTLOW - 1;
    144     NTEMP = NTEMP + 1;
    145     HT_CHECK_MEMORY_ADJUST
    146     if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
    147         goto failed;
    148     }
    149     RANGELEN[NTEMP] = 32;
    150     RANGELOW[NTEMP] = HTHIGH;
    151     NTEMP = NTEMP + 1;
    152     if(HTOOB) {
    153         HT_CHECK_MEMORY_ADJUST
    154         if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
    155             goto failed;
    156         }
    157         NTEMP = NTEMP + 1;
    158     }
    159     CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
    160     LENMAX = 0;
    161     for(i = 0; i < NTEMP; i++) {
    162         if(PREFLEN[i] > LENMAX) {
    163             LENMAX = PREFLEN[i];
    164         }
    165     }
    166     LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
    167     JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
    168     FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
    169     for(i = 0; i < NTEMP; i++) {
    170         LENCOUNT[PREFLEN[i]] ++;
    171     }
    172     CURLEN = 1;
    173     FIRSTCODE[0] = 0;
    174     LENCOUNT[0]  = 0;
    175     while(CURLEN <= LENMAX) {
    176         FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
    177         CURCODE = FIRSTCODE[CURLEN];
    178         CURTEMP = 0;
    179         while(CURTEMP < NTEMP) {
    180             if(PREFLEN[CURTEMP] == CURLEN) {
    181                 CODES[CURTEMP] = CURCODE;
    182                 CURCODE = CURCODE + 1;
    183             }
    184             CURTEMP = CURTEMP + 1;
    185         }
    186         CURLEN = CURLEN + 1;
    187     }
    188     m_pModule->JBig2_Free(LENCOUNT);
    189     m_pModule->JBig2_Free(FIRSTCODE);
    190     return TRUE;
    191 failed:
    192     return FALSE;
    193 }
    194