diff options
author | bwzuk <ben.potton@gmail.com> | 2014-02-11 12:53:33 +0000 |
---|---|---|
committer | bwzuk <ben.potton@gmail.com> | 2014-02-11 12:53:33 +0000 |
commit | ef80fffd197e2d03b7bddd3f8da1272452357c6c (patch) | |
tree | 58bf7a95a580b6705c92cc1d35418d9aa262dfb8 /drivers/webp/enc/token.c | |
parent | 5a65a6cb2b9134fbdd6e39fe3106b7a90df0cb1b (diff) | |
parent | abb985e755ccf858149294868eff8a9a9feca67e (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'drivers/webp/enc/token.c')
-rw-r--r-- | drivers/webp/enc/token.c | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/drivers/webp/enc/token.c b/drivers/webp/enc/token.c deleted file mode 100644 index e696642f16..0000000000 --- a/drivers/webp/enc/token.c +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2011 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Paginated token buffer -// -// A 'token' is a bit value associated with a probability, either fixed -// or a later-to-be-determined after statistics have been collected. -// For dynamic probability, we just record the slot id (idx) for the probability -// value in the final probability array (uint8_t* probas in VP8EmitTokens). -// -// Author: Skal (pascal.massimino@gmail.com) - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include "./cost.h" -#include "./vp8enci.h" - -#if !defined(DISABLE_TOKEN_BUFFER) - -// we use pages to reduce the number of memcpy() -#define MAX_NUM_TOKEN 8192 // max number of token per page -#define FIXED_PROBA_BIT (1u << 14) - -struct VP8Tokens { - uint16_t tokens_[MAX_NUM_TOKEN]; // bit#15: bit - // bit #14: constant proba or idx - // bits 0..13: slot or constant proba - VP8Tokens* next_; -}; - -//------------------------------------------------------------------------------ - -void VP8TBufferInit(VP8TBuffer* const b) { - b->tokens_ = NULL; - b->pages_ = NULL; - b->last_page_ = &b->pages_; - b->left_ = 0; - b->error_ = 0; -} - -void VP8TBufferClear(VP8TBuffer* const b) { - if (b != NULL) { - const VP8Tokens* p = b->pages_; - while (p != NULL) { - const VP8Tokens* const next = p->next_; - free((void*)p); - p = next; - } - VP8TBufferInit(b); - } -} - -static int TBufferNewPage(VP8TBuffer* const b) { - VP8Tokens* const page = b->error_ ? NULL : (VP8Tokens*)malloc(sizeof(*page)); - if (page == NULL) { - b->error_ = 1; - return 0; - } - *b->last_page_ = page; - b->last_page_ = &page->next_; - b->left_ = MAX_NUM_TOKEN; - b->tokens_ = page->tokens_; - page->next_ = NULL; - return 1; -} - -//------------------------------------------------------------------------------ - -#define TOKEN_ID(t, b, ctx, p) \ - ((p) + NUM_PROBAS * ((ctx) + NUM_CTX * ((b) + NUM_BANDS * (t)))) - -static WEBP_INLINE int AddToken(VP8TBuffer* const b, - int bit, uint32_t proba_idx) { - assert(proba_idx < FIXED_PROBA_BIT); - assert(bit == 0 || bit == 1); - if (b->left_ > 0 || TBufferNewPage(b)) { - const int slot = --b->left_; - b->tokens_[slot] = (bit << 15) | proba_idx; - } - return bit; -} - -static WEBP_INLINE void AddConstantToken(VP8TBuffer* const b, - int bit, int proba) { - assert(proba < 256); - assert(bit == 0 || bit == 1); - if (b->left_ > 0 || TBufferNewPage(b)) { - const int slot = --b->left_; - b->tokens_[slot] = (bit << 15) | FIXED_PROBA_BIT | proba; - } -} - -int VP8RecordCoeffTokens(int ctx, int coeff_type, int first, int last, - const int16_t* const coeffs, - VP8TBuffer* const tokens) { - int n = first; - uint32_t base_id = TOKEN_ID(coeff_type, n, ctx, 0); - if (!AddToken(tokens, last >= 0, base_id + 0)) { - return 0; - } - - while (n < 16) { - const int c = coeffs[n++]; - const int sign = c < 0; - int v = sign ? -c : c; - if (!AddToken(tokens, v != 0, base_id + 1)) { - ctx = 0; - base_id = TOKEN_ID(coeff_type, VP8EncBands[n], ctx, 0); - continue; - } - if (!AddToken(tokens, v > 1, base_id + 2)) { - ctx = 1; - } else { - if (!AddToken(tokens, v > 4, base_id + 3)) { - if (AddToken(tokens, v != 2, base_id + 4)) - AddToken(tokens, v == 4, base_id + 5); - } else if (!AddToken(tokens, v > 10, base_id + 6)) { - if (!AddToken(tokens, v > 6, base_id + 7)) { - AddConstantToken(tokens, v == 6, 159); - } else { - AddConstantToken(tokens, v >= 9, 165); - AddConstantToken(tokens, !(v & 1), 145); - } - } else { - int mask; - const uint8_t* tab; - if (v < 3 + (8 << 1)) { // VP8Cat3 (3b) - AddToken(tokens, 0, base_id + 8); - AddToken(tokens, 0, base_id + 9); - v -= 3 + (8 << 0); - mask = 1 << 2; - tab = VP8Cat3; - } else if (v < 3 + (8 << 2)) { // VP8Cat4 (4b) - AddToken(tokens, 0, base_id + 8); - AddToken(tokens, 1, base_id + 9); - v -= 3 + (8 << 1); - mask = 1 << 3; - tab = VP8Cat4; - } else if (v < 3 + (8 << 3)) { // VP8Cat5 (5b) - AddToken(tokens, 1, base_id + 8); - AddToken(tokens, 0, base_id + 10); - v -= 3 + (8 << 2); - mask = 1 << 4; - tab = VP8Cat5; - } else { // VP8Cat6 (11b) - AddToken(tokens, 1, base_id + 8); - AddToken(tokens, 1, base_id + 10); - v -= 3 + (8 << 3); - mask = 1 << 10; - tab = VP8Cat6; - } - while (mask) { - AddConstantToken(tokens, !!(v & mask), *tab++); - mask >>= 1; - } - } - ctx = 2; - } - AddConstantToken(tokens, sign, 128); - base_id = TOKEN_ID(coeff_type, VP8EncBands[n], ctx, 0); - if (n == 16 || !AddToken(tokens, n <= last, base_id + 0)) { - return 1; // EOB - } - } - return 1; -} - -#undef TOKEN_ID - -//------------------------------------------------------------------------------ -// This function works, but isn't currently used. Saved for later. - -#if 0 - -static void Record(int bit, proba_t* const stats) { - proba_t p = *stats; - if (p >= 0xffff0000u) { // an overflow is inbound. - p = ((p + 1u) >> 1) & 0x7fff7fffu; // -> divide the stats by 2. - } - // record bit count (lower 16 bits) and increment total count (upper 16 bits). - p += 0x00010000u + bit; - *stats = p; -} - -void VP8TokenToStats(const VP8TBuffer* const b, proba_t* const stats) { - const VP8Tokens* p = b->pages_; - while (p != NULL) { - const int N = (p->next_ == NULL) ? b->left_ : 0; - int n = MAX_NUM_TOKEN; - while (n-- > N) { - const uint16_t token = p->tokens_[n]; - if (!(token & FIXED_PROBA_BIT)) { - Record((token >> 15) & 1, stats + (token & 0x3fffu)); - } - } - p = p->next_; - } -} - -#endif // 0 - -//------------------------------------------------------------------------------ -// Final coding pass, with known probabilities - -int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw, - const uint8_t* const probas, int final_pass) { - const VP8Tokens* p = b->pages_; - (void)final_pass; - if (b->error_) return 0; - while (p != NULL) { - const VP8Tokens* const next = p->next_; - const int N = (next == NULL) ? b->left_ : 0; - int n = MAX_NUM_TOKEN; - while (n-- > N) { - const uint16_t token = p->tokens_[n]; - const int bit = (token >> 15) & 1; - if (token & FIXED_PROBA_BIT) { - VP8PutBit(bw, bit, token & 0xffu); // constant proba - } else { - VP8PutBit(bw, bit, probas[token & 0x3fffu]); - } - } - if (final_pass) free((void*)p); - p = next; - } - if (final_pass) b->pages_ = NULL; - return 1; -} - -// Size estimation -size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas) { - size_t size = 0; - const VP8Tokens* p = b->pages_; - if (b->error_) return 0; - while (p != NULL) { - const VP8Tokens* const next = p->next_; - const int N = (next == NULL) ? b->left_ : 0; - int n = MAX_NUM_TOKEN; - while (n-- > N) { - const uint16_t token = p->tokens_[n]; - const int bit = token & (1 << 15); - if (token & FIXED_PROBA_BIT) { - size += VP8BitCost(bit, token & 0xffu); - } else { - size += VP8BitCost(bit, probas[token & 0x3fffu]); - } - } - p = next; - } - return size; -} - -//------------------------------------------------------------------------------ - -#else // DISABLE_TOKEN_BUFFER - -void VP8TBufferInit(VP8TBuffer* const b) { - (void)b; -} -void VP8TBufferClear(VP8TBuffer* const b) { - (void)b; -} - -#endif // !DISABLE_TOKEN_BUFFER - |