inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/
| 1261 | |
| 1262 | /*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/ |
| 1263 | static unsigned inflateHuffmanBlock(ucvector* out, LodePNGBitReader* reader, |
| 1264 | unsigned btype, size_t max_output_size) { |
| 1265 | unsigned error = 0; |
| 1266 | HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ |
| 1267 | HuffmanTree tree_d; /*the huffman tree for distance codes*/ |
| 1268 | |
| 1269 | HuffmanTree_init(&tree_ll); |
| 1270 | HuffmanTree_init(&tree_d); |
| 1271 | |
| 1272 | if(btype == 1) error = getTreeInflateFixed(&tree_ll, &tree_d); |
| 1273 | else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader); |
| 1274 | |
| 1275 | while(!error) /*decode all symbols until end reached, breaks at end code*/ { |
| 1276 | /*code_ll is literal, length or end code*/ |
| 1277 | unsigned code_ll; |
| 1278 | ensureBits25(reader, 20); /* up to 15 for the huffman symbol, up to 5 for the length extra bits */ |
| 1279 | code_ll = huffmanDecodeSymbol(reader, &tree_ll); |
| 1280 | if(code_ll <= 255) /*literal symbol*/ { |
| 1281 | if(!ucvector_resize(out, out->size + 1)) ERROR_BREAK(83 /*alloc fail*/); |
| 1282 | out->data[out->size - 1] = (unsigned char)code_ll; |
| 1283 | } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ { |
| 1284 | unsigned code_d, distance; |
| 1285 | unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ |
| 1286 | size_t start, backward, length; |
| 1287 | |
| 1288 | /*part 1: get length base*/ |
| 1289 | length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; |
| 1290 | |
| 1291 | /*part 2: get extra bits and add the value of that to length*/ |
| 1292 | numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; |
| 1293 | if(numextrabits_l != 0) { |
| 1294 | /* bits already ensured above */ |
| 1295 | length += readBits(reader, numextrabits_l); |
| 1296 | } |
| 1297 | |
| 1298 | /*part 3: get distance code*/ |
| 1299 | ensureBits32(reader, 28); /* up to 15 for the huffman symbol, up to 13 for the extra bits */ |
| 1300 | code_d = huffmanDecodeSymbol(reader, &tree_d); |
| 1301 | if(code_d > 29) { |
| 1302 | if(code_d <= 31) { |
| 1303 | ERROR_BREAK(18); /*error: invalid distance code (30-31 are never used)*/ |
| 1304 | } else /* if(code_d == INVALIDSYMBOL) */{ |
| 1305 | ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ |
| 1306 | } |
| 1307 | } |
| 1308 | distance = DISTANCEBASE[code_d]; |
| 1309 | |
| 1310 | /*part 4: get extra bits from distance*/ |
| 1311 | numextrabits_d = DISTANCEEXTRA[code_d]; |
| 1312 | if(numextrabits_d != 0) { |
| 1313 | /* bits already ensured above */ |
| 1314 | distance += readBits(reader, numextrabits_d); |
| 1315 | } |
| 1316 | |
| 1317 | /*part 5: fill in all the out[n] values based on the length and dist*/ |
| 1318 | start = out->size; |
| 1319 | if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ |
| 1320 | backward = start - distance; |
no test coverage detected