| 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 : m_bOK(true), HTOOB(bHTOOB), NTEMP(nLines) { |
| 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 | |
| 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(false); |
| 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; | |
| 121 do { | 66 do { |
| 122 HT_CHECK_MEMORY_ADJUST | |
| 123 if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) || | 67 if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) || |
| 124 (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) { | 68 (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) { |
| 125 return FALSE; | 69 return false; |
| 126 } | 70 } |
| 127 RANGELOW[NTEMP] = cur_low; | 71 RANGELOW[NTEMP] = cur_low; |
| 128 cur_low += (1 << RANGELEN[NTEMP]); | 72 cur_low += (1 << RANGELEN[NTEMP]); |
| 129 NTEMP = NTEMP + 1; | 73 ExtendBuffers(true); |
| 130 } while (cur_low < high); | 74 } while (cur_low < high); |
| 131 HT_CHECK_MEMORY_ADJUST | 75 |
| 132 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) | 76 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) |
| 133 return FALSE; | 77 return false; |
| 134 | 78 |
| 135 RANGELEN[NTEMP] = 32; | 79 RANGELEN[NTEMP] = 32; |
| 136 RANGELOW[NTEMP] = low - 1; | 80 RANGELOW[NTEMP] = low - 1; |
| 137 ++NTEMP; | 81 ExtendBuffers(true); |
| 138 HT_CHECK_MEMORY_ADJUST | 82 |
| 139 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) | 83 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) |
| 140 return FALSE; | 84 return false; |
| 141 | 85 |
| 142 RANGELEN[NTEMP] = 32; | 86 RANGELEN[NTEMP] = 32; |
| 143 RANGELOW[NTEMP] = high; | 87 RANGELOW[NTEMP] = high; |
| 144 NTEMP = NTEMP + 1; | 88 ExtendBuffers(true); |
| 89 |
| 145 if (HTOOB) { | 90 if (HTOOB) { |
| 146 HT_CHECK_MEMORY_ADJUST | |
| 147 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) | 91 if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) |
| 148 return FALSE; | 92 return false; |
| 149 | 93 |
| 150 ++NTEMP; | 94 ++NTEMP; |
| 151 } | 95 } |
| 152 CODES = FX_Alloc(int, NTEMP); | 96 |
| 153 int LENMAX = 0; | 97 InitCodes(); |
| 98 return true; |
| 99 } |
| 100 |
| 101 void CJBig2_HuffmanTable::InitCodes() { |
| 102 int lenmax = 0; |
| 154 for (FX_DWORD i = 0; i < NTEMP; ++i) | 103 for (FX_DWORD i = 0; i < NTEMP; ++i) |
| 155 LENMAX = std::max(PREFLEN[i], LENMAX); | 104 lenmax = std::max(PREFLEN[i], lenmax); |
| 156 | 105 |
| 157 std::vector<int> LENCOUNT(LENMAX + 1); | 106 CODES.resize(NTEMP); |
| 158 for (FX_DWORD i = 0; i < NTEMP; ++i) | 107 std::vector<int> LENCOUNT(lenmax + 1); |
| 159 LENCOUNT[PREFLEN[i]]++; | 108 std::vector<int> FIRSTCODE(lenmax + 1); |
| 109 for (int len : PREFLEN) |
| 110 ++LENCOUNT[len]; |
| 111 |
| 112 FIRSTCODE[0] = 0; |
| 160 LENCOUNT[0] = 0; | 113 LENCOUNT[0] = 0; |
| 161 | 114 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; | 115 FIRSTCODE[i] = (FIRSTCODE[i - 1] + LENCOUNT[i - 1]) << 1; |
| 166 int CURCODE = FIRSTCODE[i]; | 116 int CURCODE = FIRSTCODE[i]; |
| 167 for (FX_DWORD j = 0; j < NTEMP; ++j) { | 117 for (FX_DWORD j = 0; j < NTEMP; ++j) { |
| 168 if (PREFLEN[j] == i) | 118 if (PREFLEN[j] == i) |
| 169 CODES[j] = CURCODE++; | 119 CODES[j] = CURCODE++; |
| 170 } | 120 } |
| 171 } | 121 } |
| 172 return TRUE; | |
| 173 } | 122 } |
| 123 |
| 124 void CJBig2_HuffmanTable::ExtendBuffers(bool increment) { |
| 125 if (increment) |
| 126 ++NTEMP; |
| 127 |
| 128 size_t size = PREFLEN.size(); |
| 129 if (NTEMP < size) |
| 130 return; |
| 131 |
| 132 size += 16; |
| 133 ASSERT(NTEMP < size); |
| 134 PREFLEN.resize(size); |
| 135 RANGELEN.resize(size); |
| 136 RANGELOW.resize(size); |
| 137 } |
| OLD | NEW |