Remove gotos in JBig2 code.
[pdfium.git] / core / src / fxcodec / jbig2 / JBig2_HuffmanTable.cpp
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
9 #include <string.h>
10
11 #include <vector>
12
13 #include "../../../include/fxcrt/fx_memory.h"
14 #include "JBig2_BitStream.h"
15
16 CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine* pTable,
17                                          int nLines,
18                                          FX_BOOL bHTOOB) {
19   init();
20   m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB);
21 }
22
23 CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream* pStream) {
24   init();
25   m_bOK = parseFromCodedBuffer(pStream);
26 }
27
28 CJBig2_HuffmanTable::~CJBig2_HuffmanTable() {
29   FX_Free(CODES);
30   FX_Free(PREFLEN);
31   FX_Free(RANGELEN);
32   FX_Free(RANGELOW);
33 }
34 void CJBig2_HuffmanTable::init() {
35   HTOOB = FALSE;
36   NTEMP = 0;
37   CODES = NULL;
38   PREFLEN = NULL;
39   RANGELEN = NULL;
40   RANGELOW = NULL;
41 }
42 int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine* pTable,
43                                                 int nLines,
44                                                 FX_BOOL bHTOOB) {
45   int CURLEN, LENMAX, CURCODE, CURTEMP;
46   int* LENCOUNT;
47   int* FIRSTCODE;
48   HTOOB = bHTOOB;
49   NTEMP = nLines;
50   CODES = FX_Alloc(int, NTEMP);
51   PREFLEN = FX_Alloc(int, NTEMP);
52   RANGELEN = FX_Alloc(int, NTEMP);
53   RANGELOW = FX_Alloc(int, NTEMP);
54   LENMAX = 0;
55   for (int i = 0; i < NTEMP; i++) {
56     PREFLEN[i] = pTable[i].PREFLEN;
57     RANGELEN[i] = pTable[i].RANDELEN;
58     RANGELOW[i] = pTable[i].RANGELOW;
59     if (PREFLEN[i] > LENMAX) {
60       LENMAX = PREFLEN[i];
61     }
62   }
63   LENCOUNT = FX_Alloc(int, LENMAX + 1);
64   JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
65   FIRSTCODE = FX_Alloc(int, LENMAX + 1);
66   for (int i = 0; i < NTEMP; i++) {
67     LENCOUNT[PREFLEN[i]]++;
68   }
69   CURLEN = 1;
70   FIRSTCODE[0] = 0;
71   LENCOUNT[0] = 0;
72   while (CURLEN <= LENMAX) {
73     FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
74     CURCODE = FIRSTCODE[CURLEN];
75     CURTEMP = 0;
76     while (CURTEMP < NTEMP) {
77       if (PREFLEN[CURTEMP] == CURLEN) {
78         CODES[CURTEMP] = CURCODE;
79         CURCODE = CURCODE + 1;
80       }
81       CURTEMP = CURTEMP + 1;
82     }
83     CURLEN = CURLEN + 1;
84   }
85   FX_Free(LENCOUNT);
86   FX_Free(FIRSTCODE);
87   return 1;
88 }
89
90 #define HT_CHECK_MEMORY_ADJUST                   \
91   if (NTEMP >= nSize) {                          \
92     nSize += 16;                                 \
93     PREFLEN = FX_Realloc(int, PREFLEN, nSize);   \
94     RANGELEN = FX_Realloc(int, RANGELEN, nSize); \
95     RANGELOW = FX_Realloc(int, RANGELOW, nSize); \
96   }
97 int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream* pStream) {
98   unsigned char cTemp;
99   if (pStream->read1Byte(&cTemp) == -1)
100     return FALSE;
101
102   HTOOB = cTemp & 0x01;
103   unsigned char HTPS = ((cTemp >> 1) & 0x07) + 1;
104   unsigned char HTRS = ((cTemp >> 4) & 0x07) + 1;
105   FX_DWORD HTLOW;
106   FX_DWORD HTHIGH;
107   if (pStream->readInteger(&HTLOW) == -1 ||
108       pStream->readInteger(&HTHIGH) == -1 || HTLOW > HTHIGH) {
109     return FALSE;
110   }
111   FX_DWORD nSize = 16;
112   PREFLEN = FX_Alloc(int, nSize);
113   RANGELEN = FX_Alloc(int, nSize);
114   RANGELOW = FX_Alloc(int, nSize);
115   FX_DWORD CURRANGELOW = HTLOW;
116   NTEMP = 0;
117   do {
118     HT_CHECK_MEMORY_ADJUST
119     if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) ||
120         (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
121       return FALSE;
122     }
123     RANGELOW[NTEMP] = CURRANGELOW;
124     CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]);
125     NTEMP = NTEMP + 1;
126   } while (CURRANGELOW < HTHIGH);
127   HT_CHECK_MEMORY_ADJUST
128   if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
129     return FALSE;
130
131   RANGELEN[NTEMP] = 32;
132   RANGELOW[NTEMP] = HTLOW - 1;
133   NTEMP = NTEMP + 1;
134   HT_CHECK_MEMORY_ADJUST
135   if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
136     return FALSE;
137
138   RANGELEN[NTEMP] = 32;
139   RANGELOW[NTEMP] = HTHIGH;
140   NTEMP = NTEMP + 1;
141   if (HTOOB) {
142     HT_CHECK_MEMORY_ADJUST
143     if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
144       return FALSE;
145     NTEMP = NTEMP + 1;
146   }
147   CODES = FX_Alloc(int, NTEMP);
148   int LENMAX = 0;
149   for (int i = 0; i < NTEMP; i++) {
150     if (PREFLEN[i] > LENMAX) {
151       LENMAX = PREFLEN[i];
152     }
153   }
154
155   std::vector<int> LENCOUNT(LENMAX + 1);
156   for (int i = 0; i < NTEMP; ++i)
157     LENCOUNT[PREFLEN[i]]++;
158   LENCOUNT[0] = 0;
159
160   std::vector<int> FIRSTCODE(LENMAX + 1);
161   FIRSTCODE[0] = 0;
162   for (int i = 0; i <= LENMAX; ++i) {
163     FIRSTCODE[i] = (FIRSTCODE[i - 1] + LENCOUNT[i - 1]) << 1;
164     int CURCODE = FIRSTCODE[i];
165     for (int j = 0; j < NTEMP; ++j) {
166       if (PREFLEN[j] == i)
167         CODES[j] = CURCODE++;
168     }
169   }
170   return TRUE;
171 }