2323#include " adt/Array1DRef.h"
2424#include " adt/Array1DRefExtras.h"
2525#include " adt/Array2DRef.h"
26+ #include " adt/Bit.h"
27+ #include " adt/Casts.h"
2628#include " adt/Point.h"
2729#include " bitstreams/BitStreams.h"
2830#include " common/BayerPhase.h"
@@ -187,18 +189,38 @@ populateHuffmanLUT(const TiffIFD& ifd) {
187189
188190 ByteStream stream = ifd.getEntry (TiffTag::PANASONIC_V8_HUF_TABLE)->getData ();
189191
192+ const auto numSymbols = stream.getU16 ();
193+ if (numSymbols < 1 || numSymbols > 17 )
194+ ThrowRDE (" Unexpected number of symbols: %u" , numSymbols);
195+
190196 struct HuffEntry {
191- uint16_t bitcount, symbol, mask;
197+ uint8_t bitcount;
198+ uint16_t symbol, mask;
199+ uint8_t codeValue;
192200 };
193- std::vector<HuffEntry> huffTable (stream.getU16 ());
194-
195- for (HuffEntry& entry : huffTable) {
196- entry.bitcount = stream.getU16 (); // Number of bits in symbol
197- entry.symbol = uint16_t (stream.getU16 () << (16U - entry.bitcount ));
201+ std::vector<HuffEntry> huffTable;
202+ huffTable.reserve (numSymbols);
203+
204+ for (unsigned symbolIndex = 0 ; symbolIndex != numSymbols; ++symbolIndex) {
205+ const auto len = stream.getU16 (); // Number of bits in symbol
206+ if (len < 1 || len > 16 )
207+ ThrowRDE (" Unexpected symbol length" );
208+ const auto code = stream.getU16 ();
209+ if (!isIntN<uint32_t >(code, len))
210+ ThrowRDE (" Bad symbol code" );
211+ HuffEntry entry;
212+ entry.bitcount = implicit_cast<uint8_t >(len);
213+ entry.symbol = uint16_t (code << (16U - entry.bitcount ));
214+ entry.codeValue = implicit_cast<uint8_t >(symbolIndex);
198215 entry.mask = uint16_t (
199216 0xffffU << (16U -
200217 entry.bitcount )); // mask of the bits overlapping symbol
218+ if (entry.bitcount == PanasonicV8Decompressor::HuffmanLUTEntry ().bitcount &&
219+ entry.codeValue == PanasonicV8Decompressor::HuffmanLUTEntry ().diffCat )
220+ ThrowRDE (" Sentinel symbol encountered" );
221+ huffTable.emplace_back (entry);
201222 }
223+ assert (table.size () == numSymbols);
202224
203225 // Cache of Huffman table results for all possible 16-bit values.
204226 mHuffmanLUT .resize (1 + UINT16_MAX);
@@ -207,11 +229,11 @@ populateHuffmanLUT(const TiffIFD& ifd) {
207229 // prefix codes recorded in the table.
208230 for (unsigned li = 0 ; li < mHuffmanLUT .size (); ++li) {
209231 PanasonicV8Decompressor::HuffmanLUTEntry& lutVal = mHuffmanLUT [li];
210- for (unsigned ti = 0 ; ti < huffTable. size (); ++ti ) {
211- if ((uint16_t (li) & huffTable[ti] .mask ) == huffTable[ti] .symbol ) {
212- lutVal.bitcount = uint8_t (huffTable[ti] .bitcount ) ;
213- lutVal.diffCat = uint8_t (ti) ;
214- break ;
232+ for (const auto & ti : huffTable) {
233+ if ((uint16_t (li) & ti .mask ) == ti .symbol ) {
234+ lutVal.bitcount = ti .bitcount ;
235+ lutVal.diffCat = ti. codeValue ;
236+ break ; // NOTE: not a prefix code!
215237 }
216238 }
217239 }
0 commit comments