MCPcopy Create free account
hub / github.com/ValveSoftware/openvr / inflateHuffmanBlock

Function inflateHuffmanBlock

samples/shared/lodepng.cpp:1103–1194  ·  view source on GitHub ↗

inflate a block with dynamic of fixed Huffman tree*/

Source from the content-addressed store, hash-verified

1101
1102/*inflate a block with dynamic of fixed Huffman tree*/
1103static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp,
1104 size_t* pos, size_t inlength, unsigned btype)
1105{
1106 unsigned error = 0;
1107 HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/
1108 HuffmanTree tree_d; /*the huffman tree for distance codes*/
1109 size_t inbitlength = inlength * 8;
1110
1111 HuffmanTree_init(&tree_ll);
1112 HuffmanTree_init(&tree_d);
1113
1114 if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d);
1115 else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength);
1116
1117 while(!error) /*decode all symbols until end reached, breaks at end code*/
1118 {
1119 /*code_ll is literal, length or end code*/
1120 unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength);
1121 if(code_ll <= 255) /*literal symbol*/
1122 {
1123 /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/
1124 if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/);
1125 out->data[*pos] = (unsigned char)code_ll;
1126 (*pos)++;
1127 }
1128 else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/
1129 {
1130 unsigned code_d, distance;
1131 unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/
1132 size_t start, forward, backward, length;
1133
1134 /*part 1: get length base*/
1135 length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX];
1136
1137 /*part 2: get extra bits and add the value of that to length*/
1138 numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX];
1139 if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/
1140 length += readBitsFromStream(bp, in, numextrabits_l);
1141
1142 /*part 3: get distance code*/
1143 code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength);
1144 if(code_d > 29)
1145 {
1146 if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/
1147 {
1148 /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol
1149 (10=no endcode, 11=wrong jump outside of tree)*/
1150 error = (*bp) > inlength * 8 ? 10 : 11;
1151 }
1152 else error = 18; /*error: invalid distance code (30-31 are never used)*/
1153 break;
1154 }
1155 distance = DISTANCEBASE[code_d];
1156
1157 /*part 4: get extra bits from distance*/
1158 numextrabits_d = DISTANCEEXTRA[code_d];
1159 if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/
1160

Callers 1

lodepng_inflatevFunction · 0.85

Calls 7

HuffmanTree_initFunction · 0.85
getTreeInflateFixedFunction · 0.85
getTreeInflateDynamicFunction · 0.85
huffmanDecodeSymbolFunction · 0.85
ucvector_resizeFunction · 0.85
readBitsFromStreamFunction · 0.85
HuffmanTree_cleanupFunction · 0.85

Tested by

no test coverage detected