in Extended/libwebp/src/dec/vp8l_dec.c [1005:1088]
static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
int width, int height, int last_row) {
int ok = 1;
int row = dec->last_pixel_ / width;
int col = dec->last_pixel_ % width;
VP8LBitReader* const br = &dec->br_;
VP8LMetadata* const hdr = &dec->hdr_;
int pos = dec->last_pixel_; // current position
const int end = width * height; // End of data
const int last = width * last_row; // Last pixel to decode
const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
const int mask = hdr->huffman_mask_;
const HTreeGroup* htree_group =
(pos < last) ? GetHtreeGroupForPos(hdr, col, row) : NULL;
assert(pos <= end);
assert(last_row <= height);
assert(Is8bOptimizable(hdr));
while (!br->eos_ && pos < last) {
int code;
// Only update when changing tile.
if ((col & mask) == 0) {
htree_group = GetHtreeGroupForPos(hdr, col, row);
}
assert(htree_group != NULL);
VP8LFillBitWindow(br);
code = ReadSymbol(htree_group->htrees[GREEN], br);
if (code < NUM_LITERAL_CODES) { // Literal
data[pos] = code;
++pos;
++col;
if (col >= width) {
col = 0;
++row;
if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
ExtractPalettedAlphaRows(dec, row);
}
}
} else if (code < len_code_limit) { // Backward reference
int dist_code, dist;
const int length_sym = code - NUM_LITERAL_CODES;
const int length = GetCopyLength(length_sym, br);
const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
VP8LFillBitWindow(br);
dist_code = GetCopyDistance(dist_symbol, br);
dist = PlaneCodeToDistance(width, dist_code);
if (pos >= dist && end - pos >= length) {
CopyBlock8b(data + pos, dist, length);
} else {
ok = 0;
goto End;
}
pos += length;
col += length;
while (col >= width) {
col -= width;
++row;
if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
ExtractPalettedAlphaRows(dec, row);
}
}
if (pos < last && (col & mask)) {
htree_group = GetHtreeGroupForPos(hdr, col, row);
}
} else { // Not reached
ok = 0;
goto End;
}
br->eos_ = VP8LIsEndOfStream(br);
}
// Process the remaining rows corresponding to last row-block.
ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row);
End:
br->eos_ = VP8LIsEndOfStream(br);
if (!ok || (br->eos_ && pos < end)) {
ok = 0;
dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
: VP8_STATUS_BITSTREAM_ERROR;
} else {
dec->last_pixel_ = pos;
}
return ok;
}