// ----------------------------------------------------------------------------- // Alpha Decode. static int DecompressZlibTCoder(VP8BitReader* br, int width, byte* output, uint output_size) { int ok = 1; uint MAX_DIST = 3 * width; uint MAX_LEN = 2 * width; TCoder* coder = TCoderNew(MAX_SYMBOLS); TCoder* coderd = TCoderNew(MAX_DIST); TCoder* coderl = TCoderNew(MAX_LEN - MIN_LEN); if (coder == null || coderd == null || coderl == null) { goto End; } { uint pos = 0; assert(br != null); while (pos < output_size && !br.eof_) { uint dist = TCoderDecode(coderd, br); if (dist == 0) { output[pos] = TCoderDecode(coder, br); ++pos; } else { uint len = MIN_LEN + TCoderDecode(coderl, br); uint k; if (pos + len > output_size || pos < dist) goto End; for (k = 0; k < len; ++k) { output[pos + k] = output[pos + k - dist]; } pos += len; } } ok = !br.eof_; } End: if (coder) TCoderDelete(coder); if (coderl) TCoderDelete(coderl); if (coderd) TCoderDelete(coderd); return ok; }
// Paragraph 9.4 static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* dec) { VP8FilterHeader* hdr = &dec.filter_hdr_; hdr.simple_ = VP8Get(br); hdr.level_ = VP8GetValue(br, 6); hdr.sharpness_ = VP8GetValue(br, 3); hdr.use_lf_delta_ = VP8Get(br); if (hdr.use_lf_delta_) { if (VP8Get(br)) { // update lf-delta? int i; for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { if (VP8Get(br)) { hdr.ref_lf_delta_[i] = VP8GetSignedValue(br, 6); } } for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { if (VP8Get(br)) { hdr.mode_lf_delta_[i] = VP8GetSignedValue(br, 6); } } } } dec.filter_type_ = (hdr.level_ == 0) ? 0 : hdr.simple_ ? 1 : 2; if (dec.filter_type_ > 0) { // precompute filter levels per segment if (dec.segment_hdr_.use_segment_) { int s; for (s = 0; s < NUM_MB_SEGMENTS; ++s) { int strength = dec.segment_hdr_.filter_strength_[s]; if (!dec.segment_hdr_.absolute_delta_) { strength += hdr.level_; } dec.filter_levels_[s] = strength; } } else { dec.filter_levels_[0] = hdr.level_; } } return !br.eof_; }
// Paragraph 9.3 static int ParseSegmentHeader(VP8BitReader* br, VP8SegmentHeader* hdr, VP8Proba* proba) { assert(br); assert(hdr); hdr.use_segment_ = VP8Get(br); if (hdr.use_segment_) { hdr.update_map_ = VP8Get(br); if (VP8Get(br)) { // update data int s; hdr.absolute_delta_ = VP8Get(br); for (s = 0; s < NUM_MB_SEGMENTS; ++s) { hdr.quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; } for (s = 0; s < NUM_MB_SEGMENTS; ++s) { hdr.filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; } } if (hdr.update_map_) { int s; for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { proba.segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u; } } } else { hdr.update_map_ = 0; } return !br.eof_; }