1 // Copyright 2010 Google Inc. All Rights Reserved. 2 // 3 // Use of this source code is governed by a BSD-style license 4 // that can be found in the COPYING file in the root of the source 5 // tree. An additional intellectual property rights grant can be found 6 // in the file PATENTS. All contributing project authors may 7 // be found in the AUTHORS file in the root of the source tree. 8 // ----------------------------------------------------------------------------- 9 // 10 // main entry for the decoder 11 // 12 // Author: Skal (pascal.massimino (at) gmail.com) 13 14 #include <stdlib.h> 15 16 #include "src/dec/alphai_dec.h" 17 #include "src/dec/vp8i_dec.h" 18 #include "src/dec/vp8li_dec.h" 19 #include "src/dec/webpi_dec.h" 20 #include "src/utils/bit_reader_inl_utils.h" 21 #include "src/utils/utils.h" 22 23 //------------------------------------------------------------------------------ 24 25 int WebPGetDecoderVersion(void) { 26 return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION; 27 } 28 29 //------------------------------------------------------------------------------ 30 // Signature and pointer-to-function for GetCoeffs() variants below. 31 32 typedef int (*GetCoeffsFunc)(VP8BitReader* const br, 33 const VP8BandProbas* const prob[], 34 int ctx, const quant_t dq, int n, int16_t* out); 35 static volatile GetCoeffsFunc GetCoeffs = NULL; 36 37 static void InitGetCoeffs(void); 38 39 //------------------------------------------------------------------------------ 40 // VP8Decoder 41 42 static void SetOk(VP8Decoder* const dec) { 43 dec->status_ = VP8_STATUS_OK; 44 dec->error_msg_ = "OK"; 45 } 46 47 int VP8InitIoInternal(VP8Io* const io, int version) { 48 if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { 49 return 0; // mismatch error 50 } 51 if (io != NULL) { 52 memset(io, 0, sizeof(*io)); 53 } 54 return 1; 55 } 56 57 VP8Decoder* VP8New(void) { 58 VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); 59 if (dec != NULL) { 60 SetOk(dec); 61 WebPGetWorkerInterface()->Init(&dec->worker_); 62 dec->ready_ = 0; 63 dec->num_parts_minus_one_ = 0; 64 InitGetCoeffs(); 65 } 66 return dec; 67 } 68 69 VP8StatusCode VP8Status(VP8Decoder* const dec) { 70 if (!dec) return VP8_STATUS_INVALID_PARAM; 71 return dec->status_; 72 } 73 74 const char* VP8StatusMessage(VP8Decoder* const dec) { 75 if (dec == NULL) return "no object"; 76 if (!dec->error_msg_) return "OK"; 77 return dec->error_msg_; 78 } 79 80 void VP8Delete(VP8Decoder* const dec) { 81 if (dec != NULL) { 82 VP8Clear(dec); 83 WebPSafeFree(dec); 84 } 85 } 86 87 int VP8SetError(VP8Decoder* const dec, 88 VP8StatusCode error, const char* const msg) { 89 // The oldest error reported takes precedence over the new one. 90 if (dec->status_ == VP8_STATUS_OK) { 91 dec->status_ = error; 92 dec->error_msg_ = msg; 93 dec->ready_ = 0; 94 } 95 return 0; 96 } 97 98 //------------------------------------------------------------------------------ 99 100 int VP8CheckSignature(const uint8_t* const data, size_t data_size) { 101 return (data_size >= 3 && 102 data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a); 103 } 104 105 int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size, 106 int* const width, int* const height) { 107 if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) { 108 return 0; // not enough data 109 } 110 // check signature 111 if (!VP8CheckSignature(data + 3, data_size - 3)) { 112 return 0; // Wrong signature. 113 } else { 114 const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); 115 const int key_frame = !(bits & 1); 116 const int w = ((data[7] << 8) | data[6]) & 0x3fff; 117 const int h = ((data[9] << 8) | data[8]) & 0x3fff; 118 119 if (!key_frame) { // Not a keyframe. 120 return 0; 121 } 122 123 if (((bits >> 1) & 7) > 3) { 124 return 0; // unknown profile 125 } 126 if (!((bits >> 4) & 1)) { 127 return 0; // first frame is invisible! 128 } 129 if (((bits >> 5)) >= chunk_size) { // partition_length 130 return 0; // inconsistent size information. 131 } 132 if (w == 0 || h == 0) { 133 return 0; // We don't support both width and height to be zero. 134 } 135 136 if (width) { 137 *width = w; 138 } 139 if (height) { 140 *height = h; 141 } 142 143 return 1; 144 } 145 } 146 147 //------------------------------------------------------------------------------ 148 // Header parsing 149 150 static void ResetSegmentHeader(VP8SegmentHeader* const hdr) { 151 assert(hdr != NULL); 152 hdr->use_segment_ = 0; 153 hdr->update_map_ = 0; 154 hdr->absolute_delta_ = 1; 155 memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_)); 156 memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_)); 157 } 158 159 // Paragraph 9.3 160 static int ParseSegmentHeader(VP8BitReader* br, 161 VP8SegmentHeader* hdr, VP8Proba* proba) { 162 assert(br != NULL); 163 assert(hdr != NULL); 164 hdr->use_segment_ = VP8Get(br); 165 if (hdr->use_segment_) { 166 hdr->update_map_ = VP8Get(br); 167 if (VP8Get(br)) { // update data 168 int s; 169 hdr->absolute_delta_ = VP8Get(br); 170 for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 171 hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; 172 } 173 for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 174 hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; 175 } 176 } 177 if (hdr->update_map_) { 178 int s; 179 for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { 180 proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u; 181 } 182 } 183 } else { 184 hdr->update_map_ = 0; 185 } 186 return !br->eof_; 187 } 188 189 // Paragraph 9.5 190 // This function returns VP8_STATUS_SUSPENDED if we don't have all the 191 // necessary data in 'buf'. 192 // This case is not necessarily an error (for incremental decoding). 193 // Still, no bitreader is ever initialized to make it possible to read 194 // unavailable memory. 195 // If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA 196 // is returned, and this is an unrecoverable error. 197 // If the partitions were positioned ok, VP8_STATUS_OK is returned. 198 static VP8StatusCode ParsePartitions(VP8Decoder* const dec, 199 const uint8_t* buf, size_t size) { 200 VP8BitReader* const br = &dec->br_; 201 const uint8_t* sz = buf; 202 const uint8_t* buf_end = buf + size; 203 const uint8_t* part_start; 204 size_t size_left = size; 205 size_t last_part; 206 size_t p; 207 208 dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2)) - 1; 209 last_part = dec->num_parts_minus_one_; 210 if (size < 3 * last_part) { 211 // we can't even read the sizes with sz[]! That's a failure. 212 return VP8_STATUS_NOT_ENOUGH_DATA; 213 } 214 part_start = buf + last_part * 3; 215 size_left -= last_part * 3; 216 for (p = 0; p < last_part; ++p) { 217 size_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); 218 if (psize > size_left) psize = size_left; 219 VP8InitBitReader(dec->parts_ + p, part_start, psize); 220 part_start += psize; 221 size_left -= psize; 222 sz += 3; 223 } 224 VP8InitBitReader(dec->parts_ + last_part, part_start, size_left); 225 return (part_start < buf_end) ? VP8_STATUS_OK : 226 VP8_STATUS_SUSPENDED; // Init is ok, but there's not enough data 227 } 228 229 // Paragraph 9.4 230 static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { 231 VP8FilterHeader* const hdr = &dec->filter_hdr_; 232 hdr->simple_ = VP8Get(br); 233 hdr->level_ = VP8GetValue(br, 6); 234 hdr->sharpness_ = VP8GetValue(br, 3); 235 hdr->use_lf_delta_ = VP8Get(br); 236 if (hdr->use_lf_delta_) { 237 if (VP8Get(br)) { // update lf-delta? 238 int i; 239 for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { 240 if (VP8Get(br)) { 241 hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6); 242 } 243 } 244 for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { 245 if (VP8Get(br)) { 246 hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6); 247 } 248 } 249 } 250 } 251 dec->filter_type_ = (hdr->level_ == 0) ? 0 : hdr->simple_ ? 1 : 2; 252 return !br->eof_; 253 } 254 255 // Topmost call 256 int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { 257 const uint8_t* buf; 258 size_t buf_size; 259 VP8FrameHeader* frm_hdr; 260 VP8PictureHeader* pic_hdr; 261 VP8BitReader* br; 262 VP8StatusCode status; 263 264 if (dec == NULL) { 265 return 0; 266 } 267 SetOk(dec); 268 if (io == NULL) { 269 return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, 270 "null VP8Io passed to VP8GetHeaders()"); 271 } 272 buf = io->data; 273 buf_size = io->data_size; 274 if (buf_size < 4) { 275 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 276 "Truncated header."); 277 } 278 279 // Paragraph 9.1 280 { 281 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); 282 frm_hdr = &dec->frm_hdr_; 283 frm_hdr->key_frame_ = !(bits & 1); 284 frm_hdr->profile_ = (bits >> 1) & 7; 285 frm_hdr->show_ = (bits >> 4) & 1; 286 frm_hdr->partition_length_ = (bits >> 5); 287 if (frm_hdr->profile_ > 3) { 288 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 289 "Incorrect keyframe parameters."); 290 } 291 if (!frm_hdr->show_) { 292 return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, 293 "Frame not displayable."); 294 } 295 buf += 3; 296 buf_size -= 3; 297 } 298 299 pic_hdr = &dec->pic_hdr_; 300 if (frm_hdr->key_frame_) { 301 // Paragraph 9.2 302 if (buf_size < 7) { 303 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 304 "cannot parse picture header"); 305 } 306 if (!VP8CheckSignature(buf, buf_size)) { 307 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 308 "Bad code word"); 309 } 310 pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff; 311 pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2 312 pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff; 313 pic_hdr->yscale_ = buf[6] >> 6; 314 buf += 7; 315 buf_size -= 7; 316 317 dec->mb_w_ = (pic_hdr->width_ + 15) >> 4; 318 dec->mb_h_ = (pic_hdr->height_ + 15) >> 4; 319 320 // Setup default output area (can be later modified during io->setup()) 321 io->width = pic_hdr->width_; 322 io->height = pic_hdr->height_; 323 // IMPORTANT! use some sane dimensions in crop_* and scaled_* fields. 324 // So they can be used interchangeably without always testing for 325 // 'use_cropping'. 326 io->use_cropping = 0; 327 io->crop_top = 0; 328 io->crop_left = 0; 329 io->crop_right = io->width; 330 io->crop_bottom = io->height; 331 io->use_scaling = 0; 332 io->scaled_width = io->width; 333 io->scaled_height = io->height; 334 335 io->mb_w = io->width; // sanity check 336 io->mb_h = io->height; // ditto 337 338 VP8ResetProba(&dec->proba_); 339 ResetSegmentHeader(&dec->segment_hdr_); 340 } 341 342 // Check if we have all the partition #0 available, and initialize dec->br_ 343 // to read this partition (and this partition only). 344 if (frm_hdr->partition_length_ > buf_size) { 345 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 346 "bad partition length"); 347 } 348 349 br = &dec->br_; 350 VP8InitBitReader(br, buf, frm_hdr->partition_length_); 351 buf += frm_hdr->partition_length_; 352 buf_size -= frm_hdr->partition_length_; 353 354 if (frm_hdr->key_frame_) { 355 pic_hdr->colorspace_ = VP8Get(br); 356 pic_hdr->clamp_type_ = VP8Get(br); 357 } 358 if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { 359 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 360 "cannot parse segment header"); 361 } 362 // Filter specs 363 if (!ParseFilterHeader(br, dec)) { 364 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 365 "cannot parse filter header"); 366 } 367 status = ParsePartitions(dec, buf, buf_size); 368 if (status != VP8_STATUS_OK) { 369 return VP8SetError(dec, status, "cannot parse partitions"); 370 } 371 372 // quantizer change 373 VP8ParseQuant(dec); 374 375 // Frame buffer marking 376 if (!frm_hdr->key_frame_) { 377 return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, 378 "Not a key frame."); 379 } 380 381 VP8Get(br); // ignore the value of update_proba_ 382 383 VP8ParseProba(br, dec); 384 385 // sanitized state 386 dec->ready_ = 1; 387 return 1; 388 } 389 390 //------------------------------------------------------------------------------ 391 // Residual decoding (Paragraph 13.2 / 13.3) 392 393 static const uint8_t kCat3[] = { 173, 148, 140, 0 }; 394 static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; 395 static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; 396 static const uint8_t kCat6[] = 397 { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; 398 static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; 399 static const uint8_t kZigzag[16] = { 400 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 401 }; 402 403 // See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 404 static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { 405 int v; 406 if (!VP8GetBit(br, p[3])) { 407 if (!VP8GetBit(br, p[4])) { 408 v = 2; 409 } else { 410 v = 3 + VP8GetBit(br, p[5]); 411 } 412 } else { 413 if (!VP8GetBit(br, p[6])) { 414 if (!VP8GetBit(br, p[7])) { 415 v = 5 + VP8GetBit(br, 159); 416 } else { 417 v = 7 + 2 * VP8GetBit(br, 165); 418 v += VP8GetBit(br, 145); 419 } 420 } else { 421 const uint8_t* tab; 422 const int bit1 = VP8GetBit(br, p[8]); 423 const int bit0 = VP8GetBit(br, p[9 + bit1]); 424 const int cat = 2 * bit1 + bit0; 425 v = 0; 426 for (tab = kCat3456[cat]; *tab; ++tab) { 427 v += v + VP8GetBit(br, *tab); 428 } 429 v += 3 + (8 << cat); 430 } 431 } 432 return v; 433 } 434 435 // Returns the position of the last non-zero coeff plus one 436 static int GetCoeffsFast(VP8BitReader* const br, 437 const VP8BandProbas* const prob[], 438 int ctx, const quant_t dq, int n, int16_t* out) { 439 const uint8_t* p = prob[n]->probas_[ctx]; 440 for (; n < 16; ++n) { 441 if (!VP8GetBit(br, p[0])) { 442 return n; // previous coeff was last non-zero coeff 443 } 444 while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs 445 p = prob[++n]->probas_[0]; 446 if (n == 16) return 16; 447 } 448 { // non zero coeff 449 const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; 450 int v; 451 if (!VP8GetBit(br, p[2])) { 452 v = 1; 453 p = p_ctx[1]; 454 } else { 455 v = GetLargeValue(br, p); 456 p = p_ctx[2]; 457 } 458 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; 459 } 460 } 461 return 16; 462 } 463 464 // This version of GetCoeffs() uses VP8GetBitAlt() which is an alternate version 465 // of VP8GetBitAlt() targeting specific platforms. 466 static int GetCoeffsAlt(VP8BitReader* const br, 467 const VP8BandProbas* const prob[], 468 int ctx, const quant_t dq, int n, int16_t* out) { 469 const uint8_t* p = prob[n]->probas_[ctx]; 470 for (; n < 16; ++n) { 471 if (!VP8GetBitAlt(br, p[0])) { 472 return n; // previous coeff was last non-zero coeff 473 } 474 while (!VP8GetBitAlt(br, p[1])) { // sequence of zero coeffs 475 p = prob[++n]->probas_[0]; 476 if (n == 16) return 16; 477 } 478 { // non zero coeff 479 const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; 480 int v; 481 if (!VP8GetBitAlt(br, p[2])) { 482 v = 1; 483 p = p_ctx[1]; 484 } else { 485 v = GetLargeValue(br, p); 486 p = p_ctx[2]; 487 } 488 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; 489 } 490 } 491 return 16; 492 } 493 494 static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) { 495 if (GetCoeffs == NULL) { 496 if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) { 497 GetCoeffs = GetCoeffsAlt; 498 } else { 499 GetCoeffs = GetCoeffsFast; 500 } 501 } 502 } 503 504 static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) { 505 nz_coeffs <<= 2; 506 nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz; 507 return nz_coeffs; 508 } 509 510 static int ParseResiduals(VP8Decoder* const dec, 511 VP8MB* const mb, VP8BitReader* const token_br) { 512 const VP8BandProbas* (* const bands)[16 + 1] = dec->proba_.bands_ptr_; 513 const VP8BandProbas* const * ac_proba; 514 VP8MBData* const block = dec->mb_data_ + dec->mb_x_; 515 const VP8QuantMatrix* const q = &dec->dqm_[block->segment_]; 516 int16_t* dst = block->coeffs_; 517 VP8MB* const left_mb = dec->mb_info_ - 1; 518 uint8_t tnz, lnz; 519 uint32_t non_zero_y = 0; 520 uint32_t non_zero_uv = 0; 521 int x, y, ch; 522 uint32_t out_t_nz, out_l_nz; 523 int first; 524 525 memset(dst, 0, 384 * sizeof(*dst)); 526 if (!block->is_i4x4_) { // parse DC 527 int16_t dc[16] = { 0 }; 528 const int ctx = mb->nz_dc_ + left_mb->nz_dc_; 529 const int nz = GetCoeffs(token_br, bands[1], ctx, q->y2_mat_, 0, dc); 530 mb->nz_dc_ = left_mb->nz_dc_ = (nz > 0); 531 if (nz > 1) { // more than just the DC -> perform the full transform 532 VP8TransformWHT(dc, dst); 533 } else { // only DC is non-zero -> inlined simplified transform 534 int i; 535 const int dc0 = (dc[0] + 3) >> 3; 536 for (i = 0; i < 16 * 16; i += 16) dst[i] = dc0; 537 } 538 first = 1; 539 ac_proba = bands[0]; 540 } else { 541 first = 0; 542 ac_proba = bands[3]; 543 } 544 545 tnz = mb->nz_ & 0x0f; 546 lnz = left_mb->nz_ & 0x0f; 547 for (y = 0; y < 4; ++y) { 548 int l = lnz & 1; 549 uint32_t nz_coeffs = 0; 550 for (x = 0; x < 4; ++x) { 551 const int ctx = l + (tnz & 1); 552 const int nz = GetCoeffs(token_br, ac_proba, ctx, q->y1_mat_, first, dst); 553 l = (nz > first); 554 tnz = (tnz >> 1) | (l << 7); 555 nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0); 556 dst += 16; 557 } 558 tnz >>= 4; 559 lnz = (lnz >> 1) | (l << 7); 560 non_zero_y = (non_zero_y << 8) | nz_coeffs; 561 } 562 out_t_nz = tnz; 563 out_l_nz = lnz >> 4; 564 565 for (ch = 0; ch < 4; ch += 2) { 566 uint32_t nz_coeffs = 0; 567 tnz = mb->nz_ >> (4 + ch); 568 lnz = left_mb->nz_ >> (4 + ch); 569 for (y = 0; y < 2; ++y) { 570 int l = lnz & 1; 571 for (x = 0; x < 2; ++x) { 572 const int ctx = l + (tnz & 1); 573 const int nz = GetCoeffs(token_br, bands[2], ctx, q->uv_mat_, 0, dst); 574 l = (nz > 0); 575 tnz = (tnz >> 1) | (l << 3); 576 nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0); 577 dst += 16; 578 } 579 tnz >>= 2; 580 lnz = (lnz >> 1) | (l << 5); 581 } 582 // Note: we don't really need the per-4x4 details for U/V blocks. 583 non_zero_uv |= nz_coeffs << (4 * ch); 584 out_t_nz |= (tnz << 4) << ch; 585 out_l_nz |= (lnz & 0xf0) << ch; 586 } 587 mb->nz_ = out_t_nz; 588 left_mb->nz_ = out_l_nz; 589 590 block->non_zero_y_ = non_zero_y; 591 block->non_zero_uv_ = non_zero_uv; 592 593 // We look at the mode-code of each block and check if some blocks have less 594 // than three non-zero coeffs (code < 2). This is to avoid dithering flat and 595 // empty blocks. 596 block->dither_ = (non_zero_uv & 0xaaaa) ? 0 : q->dither_; 597 598 return !(non_zero_y | non_zero_uv); // will be used for further optimization 599 } 600 601 //------------------------------------------------------------------------------ 602 // Main loop 603 604 int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) { 605 VP8MB* const left = dec->mb_info_ - 1; 606 VP8MB* const mb = dec->mb_info_ + dec->mb_x_; 607 VP8MBData* const block = dec->mb_data_ + dec->mb_x_; 608 int skip = dec->use_skip_proba_ ? block->skip_ : 0; 609 610 if (!skip) { 611 skip = ParseResiduals(dec, mb, token_br); 612 } else { 613 left->nz_ = mb->nz_ = 0; 614 if (!block->is_i4x4_) { 615 left->nz_dc_ = mb->nz_dc_ = 0; 616 } 617 block->non_zero_y_ = 0; 618 block->non_zero_uv_ = 0; 619 block->dither_ = 0; 620 } 621 622 if (dec->filter_type_ > 0) { // store filter info 623 VP8FInfo* const finfo = dec->f_info_ + dec->mb_x_; 624 *finfo = dec->fstrengths_[block->segment_][block->is_i4x4_]; 625 finfo->f_inner_ |= !skip; 626 } 627 628 return !token_br->eof_; 629 } 630 631 void VP8InitScanline(VP8Decoder* const dec) { 632 VP8MB* const left = dec->mb_info_ - 1; 633 left->nz_ = 0; 634 left->nz_dc_ = 0; 635 memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); 636 dec->mb_x_ = 0; 637 } 638 639 static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { 640 for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) { 641 // Parse bitstream for this row. 642 VP8BitReader* const token_br = 643 &dec->parts_[dec->mb_y_ & dec->num_parts_minus_one_]; 644 if (!VP8ParseIntraModeRow(&dec->br_, dec)) { 645 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 646 "Premature end-of-partition0 encountered."); 647 } 648 for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) { 649 if (!VP8DecodeMB(dec, token_br)) { 650 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 651 "Premature end-of-file encountered."); 652 } 653 } 654 VP8InitScanline(dec); // Prepare for next scanline 655 656 // Reconstruct, filter and emit the row. 657 if (!VP8ProcessRow(dec, io)) { 658 return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted."); 659 } 660 } 661 if (dec->mt_method_ > 0) { 662 if (!WebPGetWorkerInterface()->Sync(&dec->worker_)) return 0; 663 } 664 665 return 1; 666 } 667 668 // Main entry point 669 int VP8Decode(VP8Decoder* const dec, VP8Io* const io) { 670 int ok = 0; 671 if (dec == NULL) { 672 return 0; 673 } 674 if (io == NULL) { 675 return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, 676 "NULL VP8Io parameter in VP8Decode()."); 677 } 678 679 if (!dec->ready_) { 680 if (!VP8GetHeaders(dec, io)) { 681 return 0; 682 } 683 } 684 assert(dec->ready_); 685 686 // Finish setting up the decoding parameter. Will call io->setup(). 687 ok = (VP8EnterCritical(dec, io) == VP8_STATUS_OK); 688 if (ok) { // good to go. 689 // Will allocate memory and prepare everything. 690 if (ok) ok = VP8InitFrame(dec, io); 691 692 // Main decoding loop 693 if (ok) ok = ParseFrame(dec, io); 694 695 // Exit. 696 ok &= VP8ExitCritical(dec, io); 697 } 698 699 if (!ok) { 700 VP8Clear(dec); 701 return 0; 702 } 703 704 dec->ready_ = 0; 705 return ok; 706 } 707 708 void VP8Clear(VP8Decoder* const dec) { 709 if (dec == NULL) { 710 return; 711 } 712 WebPGetWorkerInterface()->End(&dec->worker_); 713 WebPDeallocateAlphaMemory(dec); 714 WebPSafeFree(dec->mem_); 715 dec->mem_ = NULL; 716 dec->mem_size_ = 0; 717 memset(&dec->br_, 0, sizeof(dec->br_)); 718 dec->ready_ = 0; 719 } 720 721 //------------------------------------------------------------------------------ 722