OLD | NEW |
---|---|
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "JBig2_HuffmanTable.h" | 7 #include "core/src/fxcodec/jbig2/JBig2_HuffmanTable.h" |
8 | 8 |
9 #include <string.h> | 9 #include <algorithm> |
10 | |
11 #include <vector> | 10 #include <vector> |
12 | 11 |
13 #include "JBig2_BitStream.h" | |
14 #include "JBig2_Define.h" | |
15 #include "core/include/fxcrt/fx_memory.h" | 12 #include "core/include/fxcrt/fx_memory.h" |
13 #include "core/src/fxcodec/jbig2/JBig2_BitStream.h" | |
14 #include "core/src/fxcodec/jbig2/JBig2_Define.h" | |
15 #include "core/src/fxcodec/jbig2/JBig2_HuffmanTable_Standard.h" | |
16 | 16 |
17 CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine* pTable, | 17 CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine* pTable, |
18 int nLines, | 18 FX_DWORD nLines, |
19 FX_BOOL bHTOOB) { | 19 bool bHTOOB) |
20 init(); | 20 : HTOOB(bHTOOB), NTEMP(nLines), m_bOK(true) { |
21 m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB); | 21 ParseFromStandardTable(pTable); |
22 } | 22 } |
23 | 23 |
24 CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream* pStream) { | 24 CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream* pStream) |
25 init(); | 25 : HTOOB(false), NTEMP(0) { |
26 m_bOK = parseFromCodedBuffer(pStream); | 26 m_bOK = ParseFromCodedBuffer(pStream); |
27 } | 27 } |
28 | 28 |
29 CJBig2_HuffmanTable::~CJBig2_HuffmanTable() { | 29 CJBig2_HuffmanTable::~CJBig2_HuffmanTable() { |
30 FX_Free(CODES); | |
31 FX_Free(PREFLEN); | |
32 FX_Free(RANGELEN); | |
33 FX_Free(RANGELOW); | |
34 } | 30 } |
35 void CJBig2_HuffmanTable::init() { | 31 |
36 HTOOB = FALSE; | 32 void CJBig2_HuffmanTable::ParseFromStandardTable(const JBig2TableLine* pTable) { |
37 NTEMP = 0; | 33 PREFLEN.resize(NTEMP); |
38 CODES = nullptr; | 34 RANGELEN.resize(NTEMP); |
39 PREFLEN = nullptr; | 35 RANGELOW.resize(NTEMP); |
40 RANGELEN = nullptr; | |
41 RANGELOW = nullptr; | |
42 } | |
43 int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine* pTable, | |
44 int nLines, | |
45 FX_BOOL bHTOOB) { | |
46 HTOOB = bHTOOB; | |
47 NTEMP = nLines; | |
48 CODES = FX_Alloc(int, NTEMP); | |
49 PREFLEN = FX_Alloc(int, NTEMP); | |
50 RANGELEN = FX_Alloc(int, NTEMP); | |
51 RANGELOW = FX_Alloc(int, NTEMP); | |
52 int LENMAX = 0; | |
53 for (FX_DWORD i = 0; i < NTEMP; ++i) { | 36 for (FX_DWORD i = 0; i < NTEMP; ++i) { |
54 PREFLEN[i] = pTable[i].PREFLEN; | 37 PREFLEN[i] = pTable[i].PREFLEN; |
55 RANGELEN[i] = pTable[i].RANDELEN; | 38 RANGELEN[i] = pTable[i].RANDELEN; |
56 RANGELOW[i] = pTable[i].RANGELOW; | 39 RANGELOW[i] = pTable[i].RANGELOW; |
57 if (PREFLEN[i] > LENMAX) { | |
58 LENMAX = PREFLEN[i]; | |
59 } | |
60 } | 40 } |
61 int* LENCOUNT = FX_Alloc(int, LENMAX + 1); | 41 InitCodes(); |
62 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); | |
63 int* FIRSTCODE = FX_Alloc(int, LENMAX + 1); | |
64 for (FX_DWORD i = 0; i < NTEMP; ++i) | |
65 ++LENCOUNT[PREFLEN[i]]; | |
66 | |
Tom Sepez
2015/12/18 23:48:54
what happened to this block?
Lei Zhang
2015/12/19 00:17:22
The line 67-82 block was initially refactored into
| |
67 int CURLEN = 1; | |
68 FIRSTCODE[0] = 0; | |
69 LENCOUNT[0] = 0; | |
70 while (CURLEN <= LENMAX) { | |
71 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; | |
72 int CURCODE = FIRSTCODE[CURLEN]; | |
73 FX_DWORD CURTEMP = 0; | |
74 while (CURTEMP < NTEMP) { | |
75 if (PREFLEN[CURTEMP] == CURLEN) { | |
76 CODES[CURTEMP] = CURCODE; | |
77 CURCODE = CURCODE + 1; | |
78 } | |
79 CURTEMP = CURTEMP + 1; | |
80 } | |
81 CURLEN = CURLEN + 1; | |
82 } | |
83 FX_Free(LENCOUNT); | |
84 FX_Free(FIRSTCODE); | |
85 return 1; | |
86 } | 42 } |
87 | 43 |
88 #define HT_CHECK_MEMORY_ADJUST \ | 44 bool CJBig2_HuffmanTable::ParseFromCodedBuffer(CJBig2_BitStream* pStream) { |
89 if (NTEMP >= nSize) { \ | |
90 nSize += 16; \ | |
91 PREFLEN = FX_Realloc(int, PREFLEN, nSize); \ | |
92 RANGELEN = FX_Realloc(int, RANGELEN, nSize); \ | |
93 RANGELOW = FX_Realloc(int, RANGELOW, nSize); \ | |
94 } | |
95 int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream* pStream) { | |
96 unsigned char cTemp; | 45 unsigned char cTemp; |
97 if (pStream->read1Byte(&cTemp) == -1) | 46 if (pStream->read1Byte(&cTemp) == -1) |
98 return FALSE; | 47 return false; |
99 | 48 |
100 HTOOB = cTemp & 0x01; | 49 HTOOB = !!(cTemp & 0x01); |
101 unsigned char HTPS = ((cTemp >> 1) & 0x07) + 1; | 50 unsigned char HTPS = ((cTemp >> 1) & 0x07) + 1; |
102 unsigned char HTRS = ((cTemp >> 4) & 0x07) + 1; | 51 unsigned char HTRS = ((cTemp >> 4) & 0x07) + 1; |
103 FX_DWORD HTLOW; | 52 FX_DWORD HTLOW; |
104 FX_DWORD HTHIGH; | 53 FX_DWORD HTHIGH; |
105 if (pStream->readInteger(&HTLOW) == -1 || | 54 if (pStream->readInteger(&HTLOW) == -1 || |
106 pStream->readInteger(&HTHIGH) == -1) { | 55 pStream->readInteger(&HTHIGH) == -1) { |
107 return FALSE; | 56 return false; |
108 } | 57 } |
109 | 58 |
110 const int low = static_cast<int>(HTLOW); | 59 const int low = static_cast<int>(HTLOW); |
111 const int high = static_cast<int>(HTHIGH); | 60 const int high = static_cast<int>(HTHIGH); |
112 if (low > high) | 61 if (low > high) |
113 return false; | 62 return false; |
114 | 63 |
115 FX_DWORD nSize = 16; | 64 ExtendBuffers(); |
116 PREFLEN = FX_Alloc(int, nSize); | |
117 RANGELEN = FX_Alloc(int, nSize); | |
118 RANGELOW = FX_Alloc(int, nSize); | |
119 int cur_low = low; | 65 int cur_low = low; |
120 NTEMP = 0; | |
Tom Sepez
2015/12/18 23:48:54
I'm guessing the ctor did this initialization, but
Lei Zhang
2015/12/19 00:17:22
ParseFromCodedBuffer() is a private method. It's p
| |
121 do { | 66 do { |
122 HT_CHECK_MEMORY_ADJUST | 67 ExtendBuffers(); |
123 if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) || | 68 if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) || |
124 (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) { | 69 (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) { |
125 return FALSE; | 70 return false; |
126 } | 71 } |
127 RANGELOW[NTEMP] = cur_low; | 72 RANGELOW[NTEMP] = cur_low; |
128 cur_low += (1 << RANGELEN[NTEMP]); | 73 cur_low += (1 << RANGELEN[NTEMP]); |
129 NTEMP = NTEMP + 1; | 74 ++NTEMP; |
Tom Sepez
2015/12/18 23:48:54
I'd like to see the ++NTEMP/ExtendBuffers() folded
Lei Zhang
2015/12/19 00:17:22
Well, here's something...
| |
130 } while (cur_low < high); | 75 } while (cur_low < high); |
131 HT_CHECK_MEMORY_ADJUST | 76 |
77 ExtendBuffers(); | |
132 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) | 78 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) |
133 return FALSE; | 79 return false; |
134 | 80 |
135 RANGELEN[NTEMP] = 32; | 81 RANGELEN[NTEMP] = 32; |
136 RANGELOW[NTEMP] = low - 1; | 82 RANGELOW[NTEMP] = low - 1; |
137 ++NTEMP; | 83 ++NTEMP; |
138 HT_CHECK_MEMORY_ADJUST | 84 |
85 ExtendBuffers(); | |
139 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) | 86 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) |
140 return FALSE; | 87 return false; |
141 | 88 |
142 RANGELEN[NTEMP] = 32; | 89 RANGELEN[NTEMP] = 32; |
143 RANGELOW[NTEMP] = high; | 90 RANGELOW[NTEMP] = high; |
144 NTEMP = NTEMP + 1; | 91 ++NTEMP; |
92 | |
145 if (HTOOB) { | 93 if (HTOOB) { |
146 HT_CHECK_MEMORY_ADJUST | 94 ExtendBuffers(); |
147 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) | 95 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) |
148 return FALSE; | 96 return false; |
149 | 97 |
150 ++NTEMP; | 98 ++NTEMP; |
151 } | 99 } |
152 CODES = FX_Alloc(int, NTEMP); | 100 |
153 int LENMAX = 0; | 101 InitCodes(); |
102 return true; | |
103 } | |
104 | |
105 void CJBig2_HuffmanTable::InitCodes() { | |
106 int lenmax = 0; | |
154 for (FX_DWORD i = 0; i < NTEMP; ++i) | 107 for (FX_DWORD i = 0; i < NTEMP; ++i) |
155 LENMAX = std::max(PREFLEN[i], LENMAX); | 108 lenmax = std::max(PREFLEN[i], lenmax); |
156 | 109 |
157 std::vector<int> LENCOUNT(LENMAX + 1); | 110 CODES.resize(NTEMP); |
158 for (FX_DWORD i = 0; i < NTEMP; ++i) | 111 std::vector<int> LENCOUNT(lenmax + 1); |
159 LENCOUNT[PREFLEN[i]]++; | 112 std::vector<int> FIRSTCODE(lenmax + 1); |
113 for (int len : PREFLEN) | |
114 ++LENCOUNT[len]; | |
115 | |
116 FIRSTCODE[0] = 0; | |
160 LENCOUNT[0] = 0; | 117 LENCOUNT[0] = 0; |
161 | 118 for (int i = 1; i <= lenmax; ++i) { |
162 std::vector<int> FIRSTCODE(LENMAX + 1); | |
163 FIRSTCODE[0] = 0; | |
164 for (int i = 1; i <= LENMAX; ++i) { | |
165 FIRSTCODE[i] = (FIRSTCODE[i - 1] + LENCOUNT[i - 1]) << 1; | 119 FIRSTCODE[i] = (FIRSTCODE[i - 1] + LENCOUNT[i - 1]) << 1; |
166 int CURCODE = FIRSTCODE[i]; | 120 int CURCODE = FIRSTCODE[i]; |
167 for (FX_DWORD j = 0; j < NTEMP; ++j) { | 121 for (FX_DWORD j = 0; j < NTEMP; ++j) { |
168 if (PREFLEN[j] == i) | 122 if (PREFLEN[j] == i) |
169 CODES[j] = CURCODE++; | 123 CODES[j] = CURCODE++; |
170 } | 124 } |
171 } | 125 } |
172 return TRUE; | |
173 } | 126 } |
127 | |
128 void CJBig2_HuffmanTable::ExtendBuffers() { | |
129 size_t size = PREFLEN.size(); | |
130 if (NTEMP < size) | |
131 return; | |
132 | |
133 size += 16; | |
134 PREFLEN.resize(size); | |
135 RANGELEN.resize(size); | |
136 RANGELOW.resize(size); | |
137 } | |
Tom Sepez
2015/12/18 23:48:54
nit: can we assert that it's big enough here? I k
Lei Zhang
2015/12/19 00:17:22
Done.
| |
OLD | NEW |