1a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Copyright 2010 Google Inc. All Rights Reserved. 29aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// 30406ce1417f76f2034833414dcecc9f56253640cVikas Arora// Use of this source code is governed by a BSD-style license 40406ce1417f76f2034833414dcecc9f56253640cVikas Arora// that can be found in the COPYING file in the root of the source 50406ce1417f76f2034833414dcecc9f56253640cVikas Arora// tree. An additional intellectual property rights grant can be found 60406ce1417f76f2034833414dcecc9f56253640cVikas Arora// in the file PATENTS. All contributing project authors may 70406ce1417f76f2034833414dcecc9f56253640cVikas Arora// be found in the AUTHORS file in the root of the source tree. 89aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// ----------------------------------------------------------------------------- 99aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// 109aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// main entry for the decoder 119aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// 129aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Author: Skal (pascal.massimino@gmail.com) 139aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 149aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#include <stdlib.h> 15a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 16a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include "./vp8i.h" 17a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include "./vp8li.h" 18a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include "./webpi.h" 19a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include "../utils/bit_reader.h" 209aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 2103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#if defined(__cplusplus) || defined(c_plusplus) 2203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroraextern "C" { 2303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#endif 2403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 25a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 2603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 2703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroraint WebPGetDecoderVersion(void) { 2803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION; 2903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora} 3003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 31a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 329aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// VP8Decoder 339aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 349aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic void SetOk(VP8Decoder* const dec) { 3503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora dec->status_ = VP8_STATUS_OK; 369aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->error_msg_ = "OK"; 379aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 389aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 3903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroraint VP8InitIoInternal(VP8Io* const io, int version) { 40a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { 4103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return 0; // mismatch error 42a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 43a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (io != NULL) { 449aea642eefa7a641ab8b89d953251939221d2719Eric Hassold memset(io, 0, sizeof(*io)); 459aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 4603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return 1; 479aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 489aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 4903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas AroraVP8Decoder* VP8New(void) { 50a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(*dec)); 51a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (dec != NULL) { 529aea642eefa7a641ab8b89d953251939221d2719Eric Hassold SetOk(dec); 53a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora WebPWorkerInit(&dec->worker_); 549aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->ready_ = 0; 55a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora dec->num_parts_ = 1; 569aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 579aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return dec; 589aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 599aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 6003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas AroraVP8StatusCode VP8Status(VP8Decoder* const dec) { 6103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (!dec) return VP8_STATUS_INVALID_PARAM; 629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return dec->status_; 639aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 649aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 659aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldconst char* VP8StatusMessage(VP8Decoder* const dec) { 66a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (dec == NULL) return "no object"; 679aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!dec->error_msg_) return "OK"; 689aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return dec->error_msg_; 699aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 709aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 719aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldvoid VP8Delete(VP8Decoder* const dec) { 72a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (dec != NULL) { 739aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8Clear(dec); 749aea642eefa7a641ab8b89d953251939221d2719Eric Hassold free(dec); 759aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 769aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 779aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 7803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroraint VP8SetError(VP8Decoder* const dec, 79a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora VP8StatusCode error, const char* const msg) { 80a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // TODO This check would be unnecessary if alpha decompression was separated 81a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // from VP8ProcessRow/FinishRow. This avoids setting 'dec->status_' to 82a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // something other than VP8_STATUS_BITSTREAM_ERROR on alpha decompression 83a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // failure. 84a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (dec->status_ == VP8_STATUS_OK) { 85a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora dec->status_ = error; 86a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora dec->error_msg_ = msg; 87a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora dec->ready_ = 0; 88a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 899aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return 0; 909aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 919aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 92a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 93a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 94a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8CheckSignature(const uint8_t* const data, size_t data_size) { 95a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return (data_size >= 3 && 96a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a); 97a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora} 98466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 99a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size, 100a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora int* const width, int* const height) { 101a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) { 102466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; // not enough data 103466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 104466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora // check signature 105a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (!VP8CheckSignature(data + 3, data_size - 3)) { 106466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; // Wrong signature. 107466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } else { 108466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); 109466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora const int key_frame = !(bits & 1); 110466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora const int w = ((data[7] << 8) | data[6]) & 0x3fff; 111466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora const int h = ((data[9] << 8) | data[8]) & 0x3fff; 112466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 113466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (!key_frame) { // Not a keyframe. 114466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; 115466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 116466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 117466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (((bits >> 1) & 7) > 3) { 118466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; // unknown profile 119466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 120466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (!((bits >> 4) & 1)) { 121466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; // first frame is invisible! 122466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 123466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (((bits >> 5)) >= chunk_size) { // partition_length 124466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; // inconsistent size information. 125466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 126466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 127466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (width) { 128466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora *width = w; 129466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 130466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (height) { 131466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora *height = h; 132466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 133466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 134466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 1; 135466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 136466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora} 137466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 138a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 1399aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Header parsing 1409aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 1419aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic void ResetSegmentHeader(VP8SegmentHeader* const hdr) { 142a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora assert(hdr != NULL); 1439aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->use_segment_ = 0; 1449aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->update_map_ = 0; 1459aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->absolute_delta_ = 1; 1469aea642eefa7a641ab8b89d953251939221d2719Eric Hassold memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_)); 1479aea642eefa7a641ab8b89d953251939221d2719Eric Hassold memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_)); 1489aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 1499aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 1509aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Paragraph 9.3 1519aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic int ParseSegmentHeader(VP8BitReader* br, 1529aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8SegmentHeader* hdr, VP8Proba* proba) { 153a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora assert(br != NULL); 154a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora assert(hdr != NULL); 1559aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->use_segment_ = VP8Get(br); 1569aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (hdr->use_segment_) { 1579aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->update_map_ = VP8Get(br); 1589aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (VP8Get(br)) { // update data 1599aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int s; 1609aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->absolute_delta_ = VP8Get(br); 1619aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 1629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; 1639aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 1649aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 1659aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0; 1669aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 1679aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 1689aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (hdr->update_map_) { 1699aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int s; 1709aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { 1719aea642eefa7a641ab8b89d953251939221d2719Eric Hassold proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u; 1729aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 1739aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 1749aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } else { 1759aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->update_map_ = 0; 1769aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 17703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return !br->eof_; 1789aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 1799aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 1809aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Paragraph 9.5 18103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// This function returns VP8_STATUS_SUSPENDED if we don't have all the 18203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// necessary data in 'buf'. 18303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// This case is not necessarily an error (for incremental decoding). 18403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// Still, no bitreader is ever initialized to make it possible to read 18503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// unavailable memory. 18603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA 18703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// is returned, and this is an unrecoverable error. 18803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// If the partitions were positioned ok, VP8_STATUS_OK is returned. 18903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arorastatic VP8StatusCode ParsePartitions(VP8Decoder* const dec, 190a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora const uint8_t* buf, size_t size) { 1919aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8BitReader* const br = &dec->br_; 1929aea642eefa7a641ab8b89d953251939221d2719Eric Hassold const uint8_t* sz = buf; 19303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora const uint8_t* buf_end = buf + size; 19403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora const uint8_t* part_start; 1959aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int last_part; 1969aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int p; 1979aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 1989aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->num_parts_ = 1 << VP8GetValue(br, 2); 1999aea642eefa7a641ab8b89d953251939221d2719Eric Hassold last_part = dec->num_parts_ - 1; 20003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora part_start = buf + last_part * 3; 20103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (buf_end < part_start) { 20203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora // we can't even read the sizes with sz[]! That's a failure. 20303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8_STATUS_NOT_ENOUGH_DATA; 2049aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2059aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (p = 0; p < last_part; ++p) { 2069aea642eefa7a641ab8b89d953251939221d2719Eric Hassold const uint32_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); 20703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora const uint8_t* part_end = part_start + psize; 20803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (part_end > buf_end) part_end = buf_end; 20903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8InitBitReader(dec->parts_ + p, part_start, part_end); 21003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora part_start = part_end; 2119aea642eefa7a641ab8b89d953251939221d2719Eric Hassold sz += 3; 2129aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 21303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8InitBitReader(dec->parts_ + last_part, part_start, buf_end); 21403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return (part_start < buf_end) ? VP8_STATUS_OK : 21503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8_STATUS_SUSPENDED; // Init is ok, but there's not enough data 2169aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 2179aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 2189aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Paragraph 9.4 2199aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { 2209aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8FilterHeader* const hdr = &dec->filter_hdr_; 2219aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->simple_ = VP8Get(br); 2229aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->level_ = VP8GetValue(br, 6); 2239aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->sharpness_ = VP8GetValue(br, 3); 2249aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->use_lf_delta_ = VP8Get(br); 2259aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (hdr->use_lf_delta_) { 2269aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (VP8Get(br)) { // update lf-delta? 2279aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int i; 2289aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { 2299aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (VP8Get(br)) { 2309aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6); 2319aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2329aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2339aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { 2349aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (VP8Get(br)) { 2359aea642eefa7a641ab8b89d953251939221d2719Eric Hassold hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6); 2369aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2379aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2389aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2399aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2409aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->filter_type_ = (hdr->level_ == 0) ? 0 : hdr->simple_ ? 1 : 2; 24103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return !br->eof_; 2429aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 2439aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 2449aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Topmost call 2459aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldint VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { 246a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora const uint8_t* buf; 247a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora size_t buf_size; 2489aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8FrameHeader* frm_hdr; 2499aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8PictureHeader* pic_hdr; 2509aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8BitReader* br; 25103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8StatusCode status; 252a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora WebPHeaderStructure headers; 2539aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 2549aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (dec == NULL) { 2559aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return 0; 2569aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2579aea642eefa7a641ab8b89d953251939221d2719Eric Hassold SetOk(dec); 2589aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (io == NULL) { 25903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, 26003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "null VP8Io passed to VP8GetHeaders()"); 2619aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 263a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // Process Pre-VP8 chunks. 264a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora headers.data = io->data; 265a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora headers.data_size = io->data_size; 266a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora status = WebPParseHeaders(&headers); 267a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (status != VP8_STATUS_OK) { 268a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return VP8SetError(dec, status, "Incorrect/incomplete header."); 269a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 270a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (headers.is_lossless) { 271a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 272a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora "Unexpected lossless format encountered."); 2739aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2749aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 275a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (dec->alpha_data_ == NULL) { 276a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora assert(dec->alpha_data_size_ == 0); 277a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // We have NOT set alpha data yet. Set it now. 278a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // (This is to ensure that dec->alpha_data_ is NOT reset to NULL if 279a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // WebPParseHeaders() is called more than once, as in incremental decoding 280a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // case.) 281a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora dec->alpha_data_ = headers.alpha_data; 282a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora dec->alpha_data_size_ = headers.alpha_data_size; 283a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 284a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 285a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // Process the VP8 frame header. 286a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora buf = headers.data + headers.offset; 287a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora buf_size = headers.data_size - headers.offset; 288a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora assert(headers.data_size >= headers.offset); // WebPParseHeaders' guarantee 289a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (buf_size < 4) { 290a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 291a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora "Truncated header."); 2929aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 2939aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 2949aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // Paragraph 9.1 2959aea642eefa7a641ab8b89d953251939221d2719Eric Hassold { 2969aea642eefa7a641ab8b89d953251939221d2719Eric Hassold const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); 2979aea642eefa7a641ab8b89d953251939221d2719Eric Hassold frm_hdr = &dec->frm_hdr_; 2989aea642eefa7a641ab8b89d953251939221d2719Eric Hassold frm_hdr->key_frame_ = !(bits & 1); 2999aea642eefa7a641ab8b89d953251939221d2719Eric Hassold frm_hdr->profile_ = (bits >> 1) & 7; 3009aea642eefa7a641ab8b89d953251939221d2719Eric Hassold frm_hdr->show_ = (bits >> 4) & 1; 3019aea642eefa7a641ab8b89d953251939221d2719Eric Hassold frm_hdr->partition_length_ = (bits >> 5); 30203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (frm_hdr->profile_ > 3) 30303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 30403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "Incorrect keyframe parameters."); 30503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (!frm_hdr->show_) 30603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, 30703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "Frame not displayable."); 3089aea642eefa7a641ab8b89d953251939221d2719Eric Hassold buf += 3; 3099aea642eefa7a641ab8b89d953251939221d2719Eric Hassold buf_size -= 3; 3109aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3119aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 3129aea642eefa7a641ab8b89d953251939221d2719Eric Hassold pic_hdr = &dec->pic_hdr_; 3139aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (frm_hdr->key_frame_) { 3149aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // Paragraph 9.2 3159aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (buf_size < 7) { 31603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 31703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "cannot parse picture header"); 3189aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 319a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (!VP8CheckSignature(buf, buf_size)) { 32003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 32103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "Bad code word"); 3229aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3239aea642eefa7a641ab8b89d953251939221d2719Eric Hassold pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff; 3249aea642eefa7a641ab8b89d953251939221d2719Eric Hassold pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2 3259aea642eefa7a641ab8b89d953251939221d2719Eric Hassold pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff; 3269aea642eefa7a641ab8b89d953251939221d2719Eric Hassold pic_hdr->yscale_ = buf[6] >> 6; 3279aea642eefa7a641ab8b89d953251939221d2719Eric Hassold buf += 7; 3289aea642eefa7a641ab8b89d953251939221d2719Eric Hassold buf_size -= 7; 3299aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 3309aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->mb_w_ = (pic_hdr->width_ + 15) >> 4; 3319aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->mb_h_ = (pic_hdr->height_ + 15) >> 4; 332466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora // Setup default output area (can be later modified during io->setup()) 3339aea642eefa7a641ab8b89d953251939221d2719Eric Hassold io->width = pic_hdr->width_; 3349aea642eefa7a641ab8b89d953251939221d2719Eric Hassold io->height = pic_hdr->height_; 335466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->use_scaling = 0; 336466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->use_cropping = 0; 337466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->crop_top = 0; 338466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->crop_left = 0; 339466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->crop_right = io->width; 340466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->crop_bottom = io->height; 341466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->mb_w = io->width; // sanity check 342466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora io->mb_h = io->height; // ditto 3439aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 3449aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8ResetProba(&dec->proba_); 3459aea642eefa7a641ab8b89d953251939221d2719Eric Hassold ResetSegmentHeader(&dec->segment_hdr_); 3469aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->segment_ = 0; // default for intra 3479aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3489aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 34903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora // Check if we have all the partition #0 available, and initialize dec->br_ 35003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora // to read this partition (and this partition only). 3519aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (frm_hdr->partition_length_ > buf_size) { 35203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 35303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "bad partition length"); 3549aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 355466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 35603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora br = &dec->br_; 35703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_); 3589aea642eefa7a641ab8b89d953251939221d2719Eric Hassold buf += frm_hdr->partition_length_; 3599aea642eefa7a641ab8b89d953251939221d2719Eric Hassold buf_size -= frm_hdr->partition_length_; 36003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 3619aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (frm_hdr->key_frame_) { 3629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold pic_hdr->colorspace_ = VP8Get(br); 3639aea642eefa7a641ab8b89d953251939221d2719Eric Hassold pic_hdr->clamp_type_ = VP8Get(br); 3649aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3659aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { 36603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 36703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "cannot parse segment header"); 3689aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3699aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // Filter specs 3709aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!ParseFilterHeader(br, dec)) { 37103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 37203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "cannot parse filter header"); 3739aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 37403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora status = ParsePartitions(dec, buf, buf_size); 37503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (status != VP8_STATUS_OK) { 37603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, status, "cannot parse partitions"); 3779aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3789aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 3799aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // quantizer change 3809aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8ParseQuant(dec); 3819aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 3829aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // Frame buffer marking 3839aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!frm_hdr->key_frame_) { 3849aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // Paragraph 9.7 3859aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#ifndef ONLY_KEYFRAME_CODE 3869aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ = VP8Get(br) << 0; // update golden 3879aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ |= VP8Get(br) << 1; // update alt ref 3889aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!(dec->buffer_flags_ & 1)) { 3899aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ |= VP8GetValue(br, 2) << 2; 3909aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3919aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!(dec->buffer_flags_ & 2)) { 3929aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ |= VP8GetValue(br, 2) << 4; 3939aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 3949aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ |= VP8Get(br) << 6; // sign bias golden 3959aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ |= VP8Get(br) << 7; // sign bias alt ref 3969aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#else 39703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, 39803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "Not a key frame."); 3999aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif 4009aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } else { 4019aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ = 0x003 | 0x100; 4029aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 4039aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 4049aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // Paragraph 9.8 4059aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#ifndef ONLY_KEYFRAME_CODE 4069aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->update_proba_ = VP8Get(br); 4079aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!dec->update_proba_) { // save for later restore 4089aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->proba_saved_ = dec->proba_; 4099aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 4109aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ &= 1 << 8; 4119aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->buffer_flags_ |= 4129aea642eefa7a641ab8b89d953251939221d2719Eric Hassold (frm_hdr->key_frame_ || VP8Get(br)) << 8; // refresh last frame 4139aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#else 4149aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8Get(br); // just ignore the value of update_proba_ 4159aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif 4169aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 4179aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8ParseProba(br, dec); 4189aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 419466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#ifdef WEBP_EXPERIMENTAL_FEATURES 420466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora // Extensions 421466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (dec->pic_hdr_.colorspace_) { 422466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora const size_t kTrailerSize = 8; 423466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora const uint8_t kTrailerMarker = 0x01; 424a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora const uint8_t* ext_buf = buf - kTrailerSize; 425466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora size_t size; 426466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 427466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (frm_hdr->partition_length_ < kTrailerSize || 428466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora ext_buf[kTrailerSize - 1] != kTrailerMarker) { 429466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 430466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora "RIFF: Inconsistent extra information."); 431466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 432466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 433466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora // Layer 434466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora size = (ext_buf[0] << 0) | (ext_buf[1] << 8) | (ext_buf[2] << 16); 435466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora dec->layer_data_size_ = size; 436466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora dec->layer_data_ = NULL; // will be set later 437466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora dec->layer_colorspace_ = ext_buf[3]; 438466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 439466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#endif 440466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 4419aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // sanitized state 4429aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->ready_ = 1; 4439aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return 1; 4449aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 4459aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 446a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 4479aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Residual decoding (Paragraph 13.2 / 13.3) 4489aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 4491e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic const int kBands[16 + 1] = { 4509aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 4519aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 0 // extra entry as sentinel 4529aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}; 4539aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 4549aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic const uint8_t kCat3[] = { 173, 148, 140, 0 }; 4559aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; 4569aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; 4579aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic const uint8_t kCat6[] = 4589aea642eefa7a641ab8b89d953251939221d2719Eric Hassold { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; 459466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; 4609aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic const uint8_t kZigzag[16] = { 4619aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 4629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}; 4639aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 4649aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldtypedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; // for const-casting 4651e7bf8805bd030c19924a5306837ecd72c295751Vikas Aroratypedef const uint8_t (*ProbaCtxArray)[NUM_PROBAS]; 4661e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora 4671e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 4681e7bf8805bd030c19924a5306837ecd72c295751Vikas Arorastatic int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { 4691e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora int v; 4701e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora if (!VP8GetBit(br, p[3])) { 4711e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora if (!VP8GetBit(br, p[4])) { 4721e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v = 2; 4731e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } else { 4741e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v = 3 + VP8GetBit(br, p[5]); 4751e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } 4761e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } else { 4771e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora if (!VP8GetBit(br, p[6])) { 4781e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora if (!VP8GetBit(br, p[7])) { 4791e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v = 5 + VP8GetBit(br, 159); 4801e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } else { 4811e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v = 7 + 2 * VP8GetBit(br, 165); 4821e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v += VP8GetBit(br, 145); 4831e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } 4841e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } else { 4851e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora const uint8_t* tab; 4861e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora const int bit1 = VP8GetBit(br, p[8]); 4871e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora const int bit0 = VP8GetBit(br, p[9 + bit1]); 4881e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora const int cat = 2 * bit1 + bit0; 4891e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v = 0; 4901e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora for (tab = kCat3456[cat]; *tab; ++tab) { 4911e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v += v + VP8GetBit(br, *tab); 4921e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } 4931e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v += 3 + (8 << cat); 4941e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } 4951e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } 4961e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora return v; 4971e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora} 4989aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 49903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// Returns the position of the last non-zero coeff plus one 50003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// (and 0 if there's no coeff at all) 5019aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldstatic int GetCoeffs(VP8BitReader* const br, ProbaArray prob, 502a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora int ctx, const quant_t dq, int n, int16_t* out) { 503a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'. 504a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora const uint8_t* p = prob[n][ctx]; 5059aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!VP8GetBit(br, p[0])) { // first EOB is more a 'CBP' bit. 5069aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return 0; 5079aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 5081e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora for (; n < 16; ++n) { 5091e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora const ProbaCtxArray p_ctx = prob[kBands[n + 1]]; 5109aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!VP8GetBit(br, p[1])) { 5111e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora p = p_ctx[0]; 5129aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } else { // non zero coeff 5131e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora int v; 5149aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!VP8GetBit(br, p[2])) { 5159aea642eefa7a641ab8b89d953251939221d2719Eric Hassold v = 1; 5161e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora p = p_ctx[1]; 5179aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } else { 5181e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora v = GetLargeValue(br, p); 5191e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora p = p_ctx[2]; 5209aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 5211e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; 5221e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora if (n < 15 && !VP8GetBit(br, p[0])) { // EOB 5231e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora return n + 1; 5249aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 5259aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 5269aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 5271e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora return 16; 5289aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 5299aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 53003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora// Alias-safe way of converting 4bytes to 32bits. 53103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroratypedef union { 53203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora uint8_t i8[4]; 53303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora uint32_t i32; 53403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora} PackedNz; 53503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 5369aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Table to unpack four bits into four bytes 53703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arorastatic const PackedNz kUnpackTab[16] = { 53803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora {{0, 0, 0, 0}}, {{1, 0, 0, 0}}, {{0, 1, 0, 0}}, {{1, 1, 0, 0}}, 53903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora {{0, 0, 1, 0}}, {{1, 0, 1, 0}}, {{0, 1, 1, 0}}, {{1, 1, 1, 0}}, 54003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora {{0, 0, 0, 1}}, {{1, 0, 0, 1}}, {{0, 1, 0, 1}}, {{1, 1, 0, 1}}, 54103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora {{0, 0, 1, 1}}, {{1, 0, 1, 1}}, {{0, 1, 1, 1}}, {{1, 1, 1, 1}} }; 5429aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 5439aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Macro to pack four LSB of four bytes into four bits. 5449aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#if defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || \ 5459aea642eefa7a641ab8b89d953251939221d2719Eric Hassold defined(__BIG_ENDIAN__) 5469aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#define PACK_CST 0x08040201U 5479aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#else 5489aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#define PACK_CST 0x01020408U 5499aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif 55003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#define PACK(X, S) ((((X).i32 * PACK_CST) & 0xff000000) >> (S)) 5519aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 55203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arorastatic void ParseResiduals(VP8Decoder* const dec, 55303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8MB* const mb, VP8BitReader* const token_br) { 5549aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int out_t_nz, out_l_nz, first; 5559aea642eefa7a641ab8b89d953251939221d2719Eric Hassold ProbaArray ac_prob; 5569aea642eefa7a641ab8b89d953251939221d2719Eric Hassold const VP8QuantMatrix* q = &dec->dqm_[dec->segment_]; 5579aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int16_t* dst = dec->coeffs_; 5589aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8MB* const left_mb = dec->mb_info_ - 1; 55903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora PackedNz nz_ac, nz_dc; 56003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora PackedNz tnz, lnz; 5619aea642eefa7a641ab8b89d953251939221d2719Eric Hassold uint32_t non_zero_ac = 0; 5629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold uint32_t non_zero_dc = 0; 5639aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int x, y, ch; 5649aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 565a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora nz_dc.i32 = nz_ac.i32 = 0; 5669aea642eefa7a641ab8b89d953251939221d2719Eric Hassold memset(dst, 0, 384 * sizeof(*dst)); 5679aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!dec->is_i4x4_) { // parse DC 5689aea642eefa7a641ab8b89d953251939221d2719Eric Hassold int16_t dc[16] = { 0 }; 5699aea642eefa7a641ab8b89d953251939221d2719Eric Hassold const int ctx = mb->dc_nz_ + left_mb->dc_nz_; 5709aea642eefa7a641ab8b89d953251939221d2719Eric Hassold mb->dc_nz_ = left_mb->dc_nz_ = 57103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora (GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[1], 57203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora ctx, q->y2_mat_, 0, dc) > 0); 5739aea642eefa7a641ab8b89d953251939221d2719Eric Hassold first = 1; 5749aea642eefa7a641ab8b89d953251939221d2719Eric Hassold ac_prob = (ProbaArray)dec->proba_.coeffs_[0]; 5759aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8TransformWHT(dc, dst); 5769aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } else { 5779aea642eefa7a641ab8b89d953251939221d2719Eric Hassold first = 0; 5789aea642eefa7a641ab8b89d953251939221d2719Eric Hassold ac_prob = (ProbaArray)dec->proba_.coeffs_[3]; 5799aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 5809aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 58103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora tnz = kUnpackTab[mb->nz_ & 0xf]; 58203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora lnz = kUnpackTab[left_mb->nz_ & 0xf]; 5839aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (y = 0; y < 4; ++y) { 58403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora int l = lnz.i8[y]; 5859aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (x = 0; x < 4; ++x) { 58603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora const int ctx = l + tnz.i8[x]; 58703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora const int nz = GetCoeffs(token_br, ac_prob, ctx, 58803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora q->y1_mat_, first, dst); 58903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora tnz.i8[x] = l = (nz > 0); 59003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora nz_dc.i8[x] = (dst[0] != 0); 59103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora nz_ac.i8[x] = (nz > 1); 5929aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dst += 16; 5939aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 59403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora lnz.i8[y] = l; 5959aea642eefa7a641ab8b89d953251939221d2719Eric Hassold non_zero_dc |= PACK(nz_dc, 24 - y * 4); 5969aea642eefa7a641ab8b89d953251939221d2719Eric Hassold non_zero_ac |= PACK(nz_ac, 24 - y * 4); 5979aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 5989aea642eefa7a641ab8b89d953251939221d2719Eric Hassold out_t_nz = PACK(tnz, 24); 5999aea642eefa7a641ab8b89d953251939221d2719Eric Hassold out_l_nz = PACK(lnz, 24); 6009aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 60103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora tnz = kUnpackTab[mb->nz_ >> 4]; 60203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora lnz = kUnpackTab[left_mb->nz_ >> 4]; 6039aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (ch = 0; ch < 4; ch += 2) { 6049aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (y = 0; y < 2; ++y) { 60503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora int l = lnz.i8[ch + y]; 6069aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (x = 0; x < 2; ++x) { 60703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora const int ctx = l + tnz.i8[ch + x]; 60803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora const int nz = 60903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[2], 6109aea642eefa7a641ab8b89d953251939221d2719Eric Hassold ctx, q->uv_mat_, 0, dst); 61103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora tnz.i8[ch + x] = l = (nz > 0); 61203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora nz_dc.i8[y * 2 + x] = (dst[0] != 0); 61303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora nz_ac.i8[y * 2 + x] = (nz > 1); 6149aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dst += 16; 6159aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 61603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora lnz.i8[ch + y] = l; 6179aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 6189aea642eefa7a641ab8b89d953251939221d2719Eric Hassold non_zero_dc |= PACK(nz_dc, 8 - ch * 2); 6199aea642eefa7a641ab8b89d953251939221d2719Eric Hassold non_zero_ac |= PACK(nz_ac, 8 - ch * 2); 6209aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 6219aea642eefa7a641ab8b89d953251939221d2719Eric Hassold out_t_nz |= PACK(tnz, 20); 6229aea642eefa7a641ab8b89d953251939221d2719Eric Hassold out_l_nz |= PACK(lnz, 20); 6239aea642eefa7a641ab8b89d953251939221d2719Eric Hassold mb->nz_ = out_t_nz; 6249aea642eefa7a641ab8b89d953251939221d2719Eric Hassold left_mb->nz_ = out_l_nz; 6259aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 6269aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->non_zero_ac_ = non_zero_ac; 6279aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->non_zero_ = non_zero_ac | non_zero_dc; 6289aea642eefa7a641ab8b89d953251939221d2719Eric Hassold mb->skip_ = !dec->non_zero_; 6299aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 6309aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#undef PACK 6319aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 632a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 6339aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Main loop 6349aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 63503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroraint VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) { 6369aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8BitReader* const br = &dec->br_; 63703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8MB* const left = dec->mb_info_ - 1; 63803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8MB* const info = dec->mb_info_ + dec->mb_x_; 63903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 64003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora // Note: we don't save segment map (yet), as we don't expect 64103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora // to decode more than 1 keyframe. 64203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (dec->segment_hdr_.update_map_) { 64303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora // Hardcoded tree parsing 64403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora dec->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) ? 64503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8GetBit(br, dec->proba_.segments_[1]) : 64603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 2 + VP8GetBit(br, dec->proba_.segments_[2]); 64703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora } 64803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora info->skip_ = dec->use_skip_proba_ ? VP8GetBit(br, dec->skip_p_) : 0; 64903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 65003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8ParseIntraMode(br, dec); 65103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (br->eof_) { 65203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return 0; 65303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora } 65403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 65503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (!info->skip_) { 65603d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora ParseResiduals(dec, info, token_br); 65703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora } else { 65803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora left->nz_ = info->nz_ = 0; 65903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (!dec->is_i4x4_) { 66003d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora left->dc_nz_ = info->dc_nz_ = 0; 66103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora } 66203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora dec->non_zero_ = 0; 66303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora dec->non_zero_ac_ = 0; 66403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora } 66503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 6661e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora if (dec->filter_type_ > 0) { // store filter info 6671e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora VP8FInfo* const finfo = dec->f_info_ + dec->mb_x_; 6681e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora *finfo = dec->fstrengths_[dec->segment_][dec->is_i4x4_]; 6691e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora finfo->f_inner_ = (!info->skip_ || dec->is_i4x4_); 6701e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora } 6711e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora 67203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return (!token_br->eof_); 67303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora} 6749aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 675a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8InitScanline(VP8Decoder* const dec) { 676a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora VP8MB* const left = dec->mb_info_ - 1; 677a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora left->nz_ = 0; 678a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora left->dc_nz_ = 0; 679a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); 680a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora dec->filter_row_ = 681a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora (dec->filter_type_ > 0) && 682a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora (dec->mb_y_ >= dec->tl_mb_y_) && (dec->mb_y_ <= dec->br_mb_y_); 683a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora} 684a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 68503d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arorastatic int ParseFrame(VP8Decoder* const dec, VP8Io* io) { 686466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) { 68703d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora VP8BitReader* const token_br = 68803d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; 689a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora VP8InitScanline(dec); 6909aea642eefa7a641ab8b89d953251939221d2719Eric Hassold for (dec->mb_x_ = 0; dec->mb_x_ < dec->mb_w_; dec->mb_x_++) { 69103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora if (!VP8DecodeMB(dec, token_br)) { 69203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 69303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "Premature end-of-file encountered."); 6949aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 6951e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora // Reconstruct and emit samples. 6969aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8ReconstructBlock(dec); 6979aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 698a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (!VP8ProcessRow(dec, io)) { 699466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted."); 7009aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7019aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 702a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (dec->use_threads_ && !WebPWorkerSync(&dec->worker_)) { 703a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return 0; 704a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 7059aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 7069aea642eefa7a641ab8b89d953251939221d2719Eric Hassold // Finish 7079aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#ifndef ONLY_KEYFRAME_CODE 7089aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!dec->update_proba_) { 7099aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->proba_ = dec->proba_saved_; 7109aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7119aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif 7129aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 713466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#ifdef WEBP_EXPERIMENTAL_FEATURES 714466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (dec->layer_data_size_ > 0) { 715466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora if (!VP8DecodeLayer(dec)) { 716466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; 717466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 718466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora } 719466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora#endif 720466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora 72103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return 1; 7229aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 7239aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 7249aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Main entry point 7259aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldint VP8Decode(VP8Decoder* const dec, VP8Io* const io) { 726a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora int ok = 0; 7279aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (dec == NULL) { 7289aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return 0; 7299aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7309aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (io == NULL) { 73103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, 73203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora "NULL VP8Io parameter in VP8Decode()."); 7339aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7349aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 7359aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!dec->ready_) { 7369aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (!VP8GetHeaders(dec, io)) { 7379aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return 0; 7389aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7399aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7409aea642eefa7a641ab8b89d953251939221d2719Eric Hassold assert(dec->ready_); 7419aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 742a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // Finish setting up the decoding parameter. Will call io->setup(). 743a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora ok = (VP8EnterCritical(dec, io) == VP8_STATUS_OK); 744a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (ok) { // good to go. 745a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // Will allocate memory and prepare everything. 746a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (ok) ok = VP8InitFrame(dec, io); 747a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 748a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // Main decoding loop 749a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (ok) ok = ParseFrame(dec, io); 750a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora 751a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora // Exit. 752a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora ok &= VP8ExitCritical(dec, io); 7539aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7549aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 755a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (!ok) { 7569aea642eefa7a641ab8b89d953251939221d2719Eric Hassold VP8Clear(dec); 757466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora return 0; 7589aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7599aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 7609aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->ready_ = 0; 761a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora return ok; 7629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 7639aea642eefa7a641ab8b89d953251939221d2719Eric Hassold 7649aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldvoid VP8Clear(VP8Decoder* const dec) { 7659aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (dec == NULL) { 7669aea642eefa7a641ab8b89d953251939221d2719Eric Hassold return; 7679aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 768a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora if (dec->use_threads_) { 769a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora WebPWorkerEnd(&dec->worker_); 770a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora } 7719aea642eefa7a641ab8b89d953251939221d2719Eric Hassold if (dec->mem_) { 7729aea642eefa7a641ab8b89d953251939221d2719Eric Hassold free(dec->mem_); 7739aea642eefa7a641ab8b89d953251939221d2719Eric Hassold } 7749aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->mem_ = NULL; 7759aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->mem_size_ = 0; 7769aea642eefa7a641ab8b89d953251939221d2719Eric Hassold memset(&dec->br_, 0, sizeof(dec->br_)); 7779aea642eefa7a641ab8b89d953251939221d2719Eric Hassold dec->ready_ = 0; 7789aea642eefa7a641ab8b89d953251939221d2719Eric Hassold} 77903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 780a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------ 78103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora 78203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#if defined(__cplusplus) || defined(c_plusplus) 78303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora} // extern "C" 78403d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#endif 785