inflate a block with dynamic of fixed Huffman tree*/
| 1084 | |
| 1085 | /*inflate a block with dynamic of fixed Huffman tree*/ |
| 1086 | static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, |
| 1087 | size_t* pos, size_t inlength, unsigned btype) |
| 1088 | { |
| 1089 | unsigned error = 0; |
| 1090 | HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ |
| 1091 | HuffmanTree tree_d; /*the huffman tree for distance codes*/ |
| 1092 | size_t inbitlength = inlength * 8; |
| 1093 | |
| 1094 | HuffmanTree_init(&tree_ll); |
| 1095 | HuffmanTree_init(&tree_d); |
| 1096 | |
| 1097 | if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d); |
| 1098 | else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength); |
| 1099 | |
| 1100 | while(!error) /*decode all symbols until end reached, breaks at end code*/ |
| 1101 | { |
| 1102 | /*code_ll is literal, length or end code*/ |
| 1103 | unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength); |
| 1104 | if(code_ll <= 255) /*literal symbol*/ |
| 1105 | { |
| 1106 | if((*pos) >= out->size) |
| 1107 | { |
| 1108 | /*reserve more room at once*/ |
| 1109 | if(!ucvector_resize(out, ((*pos) + 1) * 2)) ERROR_BREAK(83 /*alloc fail*/); |
| 1110 | } |
| 1111 | out->data[(*pos)] = (unsigned char)(code_ll); |
| 1112 | (*pos)++; |
| 1113 | } |
| 1114 | else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ |
| 1115 | { |
| 1116 | unsigned code_d, distance; |
| 1117 | unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ |
| 1118 | size_t start, forward, backward, length; |
| 1119 | |
| 1120 | /*part 1: get length base*/ |
| 1121 | length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; |
| 1122 | |
| 1123 | /*part 2: get extra bits and add the value of that to length*/ |
| 1124 | numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; |
| 1125 | if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ |
| 1126 | length += readBitsFromStream(bp, in, numextrabits_l); |
| 1127 | |
| 1128 | /*part 3: get distance code*/ |
| 1129 | code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); |
| 1130 | if(code_d > 29) |
| 1131 | { |
| 1132 | if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ |
| 1133 | { |
| 1134 | /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol |
| 1135 | (10=no endcode, 11=wrong jump outside of tree)*/ |
| 1136 | error = (*bp) > inlength * 8 ? 10 : 11; |
| 1137 | } |
| 1138 | else error = 18; /*error: invalid distance code (30-31 are never used)*/ |
| 1139 | break; |
| 1140 | } |
| 1141 | distance = DISTANCEBASE[code_d]; |
| 1142 | |
| 1143 | /*part 4: get extra bits from distance*/ |
no test coverage detected