Browse Source

Drop obsolete "webpold" backup of previous webp version

Fixes #5252
Rémi Verschelde 9 years ago
parent
commit
68fbb8f8ac
82 changed files with 0 additions and 30043 deletions
  1. 0 63
      drivers/webpold/SCsub
  2. 0 140
      drivers/webpold/dec/alpha.c
  3. 0 215
      drivers/webpold/dec/buffer.c
  4. 0 182
      drivers/webpold/dec/decode_vp8.h
  5. 0 679
      drivers/webpold/dec/frame.c
  6. 0 785
      drivers/webpold/dec/idec.c
  7. 0 633
      drivers/webpold/dec/io.c
  8. 0 35
      drivers/webpold/dec/layer.c
  9. 0 113
      drivers/webpold/dec/quant.c
  10. 0 589
      drivers/webpold/dec/tree.c
  11. 0 787
      drivers/webpold/dec/vp8.c
  12. 0 335
      drivers/webpold/dec/vp8i.h
  13. 0 1200
      drivers/webpold/dec/vp8l.c
  14. 0 121
      drivers/webpold/dec/vp8li.h
  15. 0 771
      drivers/webpold/dec/webp.c
  16. 0 114
      drivers/webpold/dec/webpi.h
  17. 0 454
      drivers/webpold/decode.h
  18. 0 85
      drivers/webpold/dsp/cpu.c
  19. 0 732
      drivers/webpold/dsp/dec.c
  20. 0 329
      drivers/webpold/dsp/dec_neon.c
  21. 0 903
      drivers/webpold/dsp/dec_sse2.c
  22. 0 210
      drivers/webpold/dsp/dsp.h
  23. 0 743
      drivers/webpold/dsp/enc.c
  24. 0 837
      drivers/webpold/dsp/enc_sse2.c
  25. 0 1138
      drivers/webpold/dsp/lossless.c
  26. 0 82
      drivers/webpold/dsp/lossless.h
  27. 0 357
      drivers/webpold/dsp/upsampling.c
  28. 0 209
      drivers/webpold/dsp/upsampling_sse2.c
  29. 0 52
      drivers/webpold/dsp/yuv.c
  30. 0 128
      drivers/webpold/dsp/yuv.h
  31. 0 330
      drivers/webpold/enc/alpha.c
  32. 0 364
      drivers/webpold/enc/analysis.c
  33. 0 874
      drivers/webpold/enc/backward_references.c
  34. 0 212
      drivers/webpold/enc/backward_references.h
  35. 0 132
      drivers/webpold/enc/config.c
  36. 0 494
      drivers/webpold/enc/cost.c
  37. 0 48
      drivers/webpold/enc/cost.h
  38. 0 409
      drivers/webpold/enc/filter.c
  39. 0 939
      drivers/webpold/enc/frame.c
  40. 0 406
      drivers/webpold/enc/histogram.c
  41. 0 115
      drivers/webpold/enc/histogram.h
  42. 0 422
      drivers/webpold/enc/iterator.c
  43. 0 49
      drivers/webpold/enc/layer.c
  44. 0 1041
      drivers/webpold/enc/picture.c
  45. 0 930
      drivers/webpold/enc/quant.c
  46. 0 437
      drivers/webpold/enc/syntax.c
  47. 0 510
      drivers/webpold/enc/tree.c
  48. 0 525
      drivers/webpold/enc/vp8enci.h
  49. 0 1150
      drivers/webpold/enc/vp8l.c
  50. 0 68
      drivers/webpold/enc/vp8li.h
  51. 0 389
      drivers/webpold/enc/webpenc.c
  52. 0 463
      drivers/webpold/encode.h
  53. 0 90
      drivers/webpold/format_constants.h
  54. 0 182
      drivers/webpold/image_loader_webp.cpp
  55. 0 49
      drivers/webpold/image_loader_webp.h
  56. 0 604
      drivers/webpold/mux.h
  57. 0 902
      drivers/webpold/mux/demux.c
  58. 0 712
      drivers/webpold/mux/muxedit.c
  59. 0 271
      drivers/webpold/mux/muxi.h
  60. 0 576
      drivers/webpold/mux/muxinternal.c
  61. 0 411
      drivers/webpold/mux/muxread.c
  62. 0 45
      drivers/webpold/types.h
  63. 0 229
      drivers/webpold/utils/bit_reader.c
  64. 0 198
      drivers/webpold/utils/bit_reader.h
  65. 0 284
      drivers/webpold/utils/bit_writer.c
  66. 0 123
      drivers/webpold/utils/bit_writer.h
  67. 0 44
      drivers/webpold/utils/color_cache.c
  68. 0 68
      drivers/webpold/utils/color_cache.h
  69. 0 229
      drivers/webpold/utils/filters.c
  70. 0 54
      drivers/webpold/utils/filters.h
  71. 0 238
      drivers/webpold/utils/huffman.c
  72. 0 78
      drivers/webpold/utils/huffman.h
  73. 0 439
      drivers/webpold/utils/huffman_encode.c
  74. 0 47
      drivers/webpold/utils/huffman_encode.h
  75. 0 154
      drivers/webpold/utils/quant_levels.c
  76. 0 39
      drivers/webpold/utils/quant_levels.h
  77. 0 152
      drivers/webpold/utils/rescaler.c
  78. 0 76
      drivers/webpold/utils/rescaler.h
  79. 0 247
      drivers/webpold/utils/thread.c
  80. 0 86
      drivers/webpold/utils/thread.h
  81. 0 44
      drivers/webpold/utils/utils.c
  82. 0 44
      drivers/webpold/utils/utils.h

+ 0 - 63
drivers/webpold/SCsub

@@ -1,63 +0,0 @@
-Import('env')
-
-
-webp_sources = [
-	"webp/mux/muxedit.c",
-	"webp/mux/muxread.c",
-	"webp/mux/muxinternal.c",
-	"webp/mux/demux.c",
-	"webp/enc/tree.c",
-	"webp/enc/analysis.c",
-	"webp/enc/backward_references.c",
-	"webp/enc/alpha.c",
-	"webp/enc/picture.c",
-	"webp/enc/frame.c",
-	"webp/enc/webpenc.c",
-	"webp/enc/cost.c",
-	"webp/enc/filter.c",
-	"webp/enc/vp8l.c",
-	"webp/enc/quant.c",
-	"webp/enc/histogram.c",
-	"webp/enc/syntax.c",
-	"webp/enc/config.c",
-	"webp/enc/layer.c",
-	"webp/enc/iterator.c",
-	"webp/dsp/dec_sse2.c",
-	"webp/dsp/upsampling_sse2.c",
-	"webp/dsp/dec_neon.c",
-	"webp/dsp/enc.c",
-	"webp/dsp/enc_sse2.c",
-	"webp/dsp/upsampling.c",
-	"webp/dsp/lossless.c",
-	"webp/dsp/cpu.c",
-	"webp/dsp/dec.c",
-	"webp/dsp/yuv.c",
-	"webp/utils/bit_reader.c",
-	"webp/utils/filters.c",
-	"webp/utils/bit_writer.c",
-	"webp/utils/thread.c",
-	"webp/utils/quant_levels.c",
-	"webp/utils/color_cache.c",
-	"webp/utils/rescaler.c",
-	"webp/utils/utils.c",
-	"webp/utils/huffman.c",
-	"webp/utils/huffman_encode.c",
-	"webp/dec/tree.c",
-	"webp/dec/alpha.c",
-	"webp/dec/frame.c",
-	"webp/dec/vp8l.c",
-	"webp/dec/vp8.c",
-	"webp/dec/quant.c",
-	"webp/dec/webp.c",
-	"webp/dec/buffer.c",
-	"webp/dec/io.c",
-	"webp/dec/layer.c",
-	"webp/dec/idec.c",
-	"webp/image_loader_webp.cpp"
-]
-
-env.drivers_sources+=webp_sources
-
-#env.add_source_files(env.drivers_sources, webp_sources)
-
-Export('env')

+ 0 - 140
drivers/webpold/dec/alpha.c

@@ -1,140 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Alpha-plane decompression.
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-#include "./vp8i.h"
-#include "./vp8li.h"
-#include "../utils/filters.h"
-#include "../utils/quant_levels.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// TODO(skal): move to dsp/ ?
-static void CopyPlane(const uint8_t* src, int src_stride,
-                      uint8_t* dst, int dst_stride, int width, int height) {
-  while (height-- > 0) {
-    memcpy(dst, src, width);
-    src += src_stride;
-    dst += dst_stride;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Decodes the compressed data 'data' of size 'data_size' into the 'output'.
-// The 'output' buffer should be pre-allocated and must be of the same
-// dimension 'height'x'stride', as that of the image.
-//
-// Returns 1 on successfully decoding the compressed alpha and
-//         0 if either:
-//           error in bit-stream header (invalid compression mode or filter), or
-//           error returned by appropriate compression method.
-
-static int DecodeAlpha(const uint8_t* data, size_t data_size,
-                       int width, int height, int stride, uint8_t* output) {
-  uint8_t* decoded_data = NULL;
-  const size_t decoded_size = height * width;
-  uint8_t* unfiltered_data = NULL;
-  WEBP_FILTER_TYPE filter;
-  int pre_processing;
-  int rsrv;
-  int ok = 0;
-  int method;
-
-  assert(width > 0 && height > 0 && stride >= width);
-  assert(data != NULL && output != NULL);
-
-  if (data_size <= ALPHA_HEADER_LEN) {
-    return 0;
-  }
-
-  method = (data[0] >> 0) & 0x03;
-  filter = (data[0] >> 2) & 0x03;
-  pre_processing = (data[0] >> 4) & 0x03;
-  rsrv = (data[0] >> 6) & 0x03;
-  if (method < ALPHA_NO_COMPRESSION ||
-      method > ALPHA_LOSSLESS_COMPRESSION ||
-      filter >= WEBP_FILTER_LAST ||
-      pre_processing > ALPHA_PREPROCESSED_LEVELS ||
-      rsrv != 0) {
-    return 0;
-  }
-
-  if (method == ALPHA_NO_COMPRESSION) {
-    ok = (data_size >= decoded_size);
-    decoded_data = (uint8_t*)data + ALPHA_HEADER_LEN;
-  } else {
-    decoded_data = (uint8_t*)malloc(decoded_size);
-    if (decoded_data == NULL) return 0;
-    ok = VP8LDecodeAlphaImageStream(width, height,
-                                    data + ALPHA_HEADER_LEN,
-                                    data_size - ALPHA_HEADER_LEN,
-                                    decoded_data);
-  }
-
-  if (ok) {
-    WebPFilterFunc unfilter_func = WebPUnfilters[filter];
-    if (unfilter_func != NULL) {
-      unfiltered_data = (uint8_t*)malloc(decoded_size);
-      if (unfiltered_data == NULL) {
-        ok = 0;
-        goto Error;
-      }
-      // TODO(vikas): Implement on-the-fly decoding & filter mechanism to decode
-      // and apply filter per image-row.
-      unfilter_func(decoded_data, width, height, 1, width, unfiltered_data);
-      // Construct raw_data (height x stride) from alpha data (height x width).
-      CopyPlane(unfiltered_data, width, output, stride, width, height);
-      free(unfiltered_data);
-    } else {
-      // Construct raw_data (height x stride) from alpha data (height x width).
-      CopyPlane(decoded_data, width, output, stride, width, height);
-    }
-    if (pre_processing == ALPHA_PREPROCESSED_LEVELS) {
-      ok = DequantizeLevels(decoded_data, width, height);
-    }
-  }
-
- Error:
-  if (method != ALPHA_NO_COMPRESSION) {
-    free(decoded_data);
-  }
-  return ok;
-}
-
-//------------------------------------------------------------------------------
-
-const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
-                                      int row, int num_rows) {
-  const int stride = dec->pic_hdr_.width_;
-
-  if (row < 0 || num_rows < 0 || row + num_rows > dec->pic_hdr_.height_) {
-    return NULL;    // sanity check.
-  }
-
-  if (row == 0) {
-    // Decode everything during the first call.
-    if (!DecodeAlpha(dec->alpha_data_, (size_t)dec->alpha_data_size_,
-                     dec->pic_hdr_.width_, dec->pic_hdr_.height_, stride,
-                     dec->alpha_plane_)) {
-      return NULL;  // Error.
-    }
-  }
-
-  // Return a pointer to the current decoded row.
-  return dec->alpha_plane_ + row * stride;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 215
drivers/webpold/dec/buffer.c

@@ -1,215 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Everything about WebPDecBuffer
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-
-#include "./vp8i.h"
-#include "./webpi.h"
-#include "../utils/utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// WebPDecBuffer
-
-// Number of bytes per pixel for the different color-spaces.
-static const int kModeBpp[MODE_LAST] = {
-  3, 4, 3, 4, 4, 2, 2,
-  4, 4, 4, 2,    // pre-multiplied modes
-  1, 1 };
-
-// Check that webp_csp_mode is within the bounds of WEBP_CSP_MODE.
-// Convert to an integer to handle both the unsigned/signed enum cases
-// without the need for casting to remove type limit warnings.
-static int IsValidColorspace(int webp_csp_mode) {
-  return (webp_csp_mode >= MODE_RGB && webp_csp_mode < MODE_LAST);
-}
-
-static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
-  int ok = 1;
-  const WEBP_CSP_MODE mode = buffer->colorspace;
-  const int width = buffer->width;
-  const int height = buffer->height;
-  if (!IsValidColorspace(mode)) {
-    ok = 0;
-  } else if (!WebPIsRGBMode(mode)) {   // YUV checks
-    const WebPYUVABuffer* const buf = &buffer->u.YUVA;
-    const uint64_t y_size = (uint64_t)buf->y_stride * height;
-    const uint64_t u_size = (uint64_t)buf->u_stride * ((height + 1) / 2);
-    const uint64_t v_size = (uint64_t)buf->v_stride * ((height + 1) / 2);
-    const uint64_t a_size = (uint64_t)buf->a_stride * height;
-    ok &= (y_size <= buf->y_size);
-    ok &= (u_size <= buf->u_size);
-    ok &= (v_size <= buf->v_size);
-    ok &= (buf->y_stride >= width);
-    ok &= (buf->u_stride >= (width + 1) / 2);
-    ok &= (buf->v_stride >= (width + 1) / 2);
-    ok &= (buf->y != NULL);
-    ok &= (buf->u != NULL);
-    ok &= (buf->v != NULL);
-    if (mode == MODE_YUVA) {
-      ok &= (buf->a_stride >= width);
-      ok &= (a_size <= buf->a_size);
-      ok &= (buf->a != NULL);
-    }
-  } else {    // RGB checks
-    const WebPRGBABuffer* const buf = &buffer->u.RGBA;
-    const uint64_t size = (uint64_t)buf->stride * height;
-    ok &= (size <= buf->size);
-    ok &= (buf->stride >= width * kModeBpp[mode]);
-    ok &= (buf->rgba != NULL);
-  }
-  return ok ? VP8_STATUS_OK : VP8_STATUS_INVALID_PARAM;
-}
-
-static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
-  const int w = buffer->width;
-  const int h = buffer->height;
-  const WEBP_CSP_MODE mode = buffer->colorspace;
-
-  if (w <= 0 || h <= 0 || !IsValidColorspace(mode)) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-
-  if (!buffer->is_external_memory && buffer->private_memory == NULL) {
-    uint8_t* output;
-    int uv_stride = 0, a_stride = 0;
-    uint64_t uv_size = 0, a_size = 0, total_size;
-    // We need memory and it hasn't been allocated yet.
-    // => initialize output buffer, now that dimensions are known.
-    const int stride = w * kModeBpp[mode];
-    const uint64_t size = (uint64_t)stride * h;
-
-    if (!WebPIsRGBMode(mode)) {
-      uv_stride = (w + 1) / 2;
-      uv_size = (uint64_t)uv_stride * ((h + 1) / 2);
-      if (mode == MODE_YUVA) {
-        a_stride = w;
-        a_size = (uint64_t)a_stride * h;
-      }
-    }
-    total_size = size + 2 * uv_size + a_size;
-
-    // Security/sanity checks
-    output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output));
-    if (output == NULL) {
-      return VP8_STATUS_OUT_OF_MEMORY;
-    }
-    buffer->private_memory = output;
-
-    if (!WebPIsRGBMode(mode)) {   // YUVA initialization
-      WebPYUVABuffer* const buf = &buffer->u.YUVA;
-      buf->y = output;
-      buf->y_stride = stride;
-      buf->y_size = (size_t)size;
-      buf->u = output + size;
-      buf->u_stride = uv_stride;
-      buf->u_size = (size_t)uv_size;
-      buf->v = output + size + uv_size;
-      buf->v_stride = uv_stride;
-      buf->v_size = (size_t)uv_size;
-      if (mode == MODE_YUVA) {
-        buf->a = output + size + 2 * uv_size;
-      }
-      buf->a_size = (size_t)a_size;
-      buf->a_stride = a_stride;
-    } else {  // RGBA initialization
-      WebPRGBABuffer* const buf = &buffer->u.RGBA;
-      buf->rgba = output;
-      buf->stride = stride;
-      buf->size = (size_t)size;
-    }
-  }
-  return CheckDecBuffer(buffer);
-}
-
-VP8StatusCode WebPAllocateDecBuffer(int w, int h,
-                                    const WebPDecoderOptions* const options,
-                                    WebPDecBuffer* const out) {
-  if (out == NULL || w <= 0 || h <= 0) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-  if (options != NULL) {    // First, apply options if there is any.
-    if (options->use_cropping) {
-      const int cw = options->crop_width;
-      const int ch = options->crop_height;
-      const int x = options->crop_left & ~1;
-      const int y = options->crop_top & ~1;
-      if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) {
-        return VP8_STATUS_INVALID_PARAM;   // out of frame boundary.
-      }
-      w = cw;
-      h = ch;
-    }
-    if (options->use_scaling) {
-      if (options->scaled_width <= 0 || options->scaled_height <= 0) {
-        return VP8_STATUS_INVALID_PARAM;
-      }
-      w = options->scaled_width;
-      h = options->scaled_height;
-    }
-  }
-  out->width = w;
-  out->height = h;
-
-  // Then, allocate buffer for real
-  return AllocateBuffer(out);
-}
-
-//------------------------------------------------------------------------------
-// constructors / destructors
-
-int WebPInitDecBufferInternal(WebPDecBuffer* buffer, int version) {
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
-    return 0;  // version mismatch
-  }
-  if (buffer == NULL) return 0;
-  memset(buffer, 0, sizeof(*buffer));
-  return 1;
-}
-
-void WebPFreeDecBuffer(WebPDecBuffer* buffer) {
-  if (buffer != NULL) {
-    if (!buffer->is_external_memory)
-      free(buffer->private_memory);
-    buffer->private_memory = NULL;
-  }
-}
-
-void WebPCopyDecBuffer(const WebPDecBuffer* const src,
-                       WebPDecBuffer* const dst) {
-  if (src != NULL && dst != NULL) {
-    *dst = *src;
-    if (src->private_memory != NULL) {
-      dst->is_external_memory = 1;   // dst buffer doesn't own the memory.
-      dst->private_memory = NULL;
-    }
-  }
-}
-
-// Copy and transfer ownership from src to dst (beware of parameter order!)
-void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst) {
-  if (src != NULL && dst != NULL) {
-    *dst = *src;
-    if (src->private_memory != NULL) {
-      src->is_external_memory = 1;   // src relinquishes ownership
-      src->private_memory = NULL;
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 182
drivers/webpold/dec/decode_vp8.h

@@ -1,182 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//  Low-level API for VP8 decoder
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_WEBP_DECODE_VP8_H_
-#define WEBP_WEBP_DECODE_VP8_H_
-
-#include "../decode.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Lower-level API
-//
-// These functions provide fine-grained control of the decoding process.
-// The call flow should resemble:
-//
-//   VP8Io io;
-//   VP8InitIo(&io);
-//   io.data = data;
-//   io.data_size = size;
-//   /* customize io's functions (setup()/put()/teardown()) if needed. */
-//
-//   VP8Decoder* dec = VP8New();
-//   bool ok = VP8Decode(dec);
-//   if (!ok) printf("Error: %s\n", VP8StatusMessage(dec));
-//   VP8Delete(dec);
-//   return ok;
-
-// Input / Output
-typedef struct VP8Io VP8Io;
-typedef int (*VP8IoPutHook)(const VP8Io* io);
-typedef int (*VP8IoSetupHook)(VP8Io* io);
-typedef void (*VP8IoTeardownHook)(const VP8Io* io);
-
-struct VP8Io {
-  // set by VP8GetHeaders()
-  int width, height;         // picture dimensions, in pixels (invariable).
-                             // These are the original, uncropped dimensions.
-                             // The actual area passed to put() is stored
-                             // in mb_w / mb_h fields.
-
-  // set before calling put()
-  int mb_y;                  // position of the current rows (in pixels)
-  int mb_w;                  // number of columns in the sample
-  int mb_h;                  // number of rows in the sample
-  const uint8_t* y, *u, *v;  // rows to copy (in yuv420 format)
-  int y_stride;              // row stride for luma
-  int uv_stride;             // row stride for chroma
-
-  void* opaque;              // user data
-
-  // called when fresh samples are available. Currently, samples are in
-  // YUV420 format, and can be up to width x 24 in size (depending on the
-  // in-loop filtering level, e.g.). Should return false in case of error
-  // or abort request. The actual size of the area to update is mb_w x mb_h
-  // in size, taking cropping into account.
-  VP8IoPutHook put;
-
-  // called just before starting to decode the blocks.
-  // Must return false in case of setup error, true otherwise. If false is
-  // returned, teardown() will NOT be called. But if the setup succeeded
-  // and true is returned, then teardown() will always be called afterward.
-  VP8IoSetupHook setup;
-
-  // Called just after block decoding is finished (or when an error occurred
-  // during put()). Is NOT called if setup() failed.
-  VP8IoTeardownHook teardown;
-
-  // this is a recommendation for the user-side yuv->rgb converter. This flag
-  // is set when calling setup() hook and can be overwritten by it. It then
-  // can be taken into consideration during the put() method.
-  int fancy_upsampling;
-
-  // Input buffer.
-  size_t data_size;
-  const uint8_t* data;
-
-  // If true, in-loop filtering will not be performed even if present in the
-  // bitstream. Switching off filtering may speed up decoding at the expense
-  // of more visible blocking. Note that output will also be non-compliant
-  // with the VP8 specifications.
-  int bypass_filtering;
-
-  // Cropping parameters.
-  int use_cropping;
-  int crop_left, crop_right, crop_top, crop_bottom;
-
-  // Scaling parameters.
-  int use_scaling;
-  int scaled_width, scaled_height;
-
-  // If non NULL, pointer to the alpha data (if present) corresponding to the
-  // start of the current row (That is: it is pre-offset by mb_y and takes
-  // cropping into account).
-  const uint8_t* a;
-};
-
-// Internal, version-checked, entry point
-int VP8InitIoInternal(VP8Io* const, int);
-
-// Set the custom IO function pointers and user-data. The setter for IO hooks
-// should be called before initiating incremental decoding. Returns true if
-// WebPIDecoder object is successfully modified, false otherwise.
-int WebPISetIOHooks(WebPIDecoder* const idec,
-                    VP8IoPutHook put,
-                    VP8IoSetupHook setup,
-                    VP8IoTeardownHook teardown,
-                    void* user_data);
-
-// Main decoding object. This is an opaque structure.
-typedef struct VP8Decoder VP8Decoder;
-
-// Create a new decoder object.
-VP8Decoder* VP8New(void);
-
-// Must be called to make sure 'io' is initialized properly.
-// Returns false in case of version mismatch. Upon such failure, no other
-// decoding function should be called (VP8Decode, VP8GetHeaders, ...)
-static WEBP_INLINE int VP8InitIo(VP8Io* const io) {
-  return VP8InitIoInternal(io, WEBP_DECODER_ABI_VERSION);
-}
-
-// Start decoding a new picture. Returns true if ok.
-int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
-
-// Decode a picture. Will call VP8GetHeaders() if it wasn't done already.
-// Returns false in case of error.
-int VP8Decode(VP8Decoder* const dec, VP8Io* const io);
-
-// Return current status of the decoder:
-VP8StatusCode VP8Status(VP8Decoder* const dec);
-
-// return readable string corresponding to the last status.
-const char* VP8StatusMessage(VP8Decoder* const dec);
-
-// Resets the decoder in its initial state, reclaiming memory.
-// Not a mandatory call between calls to VP8Decode().
-void VP8Clear(VP8Decoder* const dec);
-
-// Destroy the decoder object.
-void VP8Delete(VP8Decoder* const dec);
-
-//------------------------------------------------------------------------------
-// Miscellaneous VP8/VP8L bitstream probing functions.
-
-// Returns true if the next 3 bytes in data contain the VP8 signature.
-WEBP_EXTERN(int) VP8CheckSignature(const uint8_t* const data, size_t data_size);
-
-// Validates the VP8 data-header and retrieves basic header information viz
-// width and height. Returns 0 in case of formatting error. *width/*height
-// can be passed NULL.
-WEBP_EXTERN(int) VP8GetInfo(
-    const uint8_t* data,
-    size_t data_size,    // data available so far
-    size_t chunk_size,   // total data size expected in the chunk
-    int* const width, int* const height);
-
-// Returns true if the next byte(s) in data is a VP8L signature.
-WEBP_EXTERN(int) VP8LCheckSignature(const uint8_t* const data, size_t size);
-
-// Validates the VP8L data-header and retrieves basic header information viz
-// width, height and alpha. Returns 0 in case of formatting error.
-// width/height/has_alpha can be passed NULL.
-WEBP_EXTERN(int) VP8LGetInfo(
-    const uint8_t* data, size_t data_size,  // data available so far
-    int* const width, int* const height, int* const has_alpha);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_WEBP_DECODE_VP8_H_ */

+ 0 - 679
drivers/webpold/dec/frame.c

@@ -1,679 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Frame-reconstruction function. Memory allocation.
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-#include "./vp8i.h"
-#include "../utils/utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define ALIGN_MASK (32 - 1)
-
-//------------------------------------------------------------------------------
-// Filtering
-
-// kFilterExtraRows[] = How many extra lines are needed on the MB boundary
-// for caching, given a filtering level.
-// Simple filter:  up to 2 luma samples are read and 1 is written.
-// Complex filter: up to 4 luma samples are read and 3 are written. Same for
-//                 U/V, so it's 8 samples total (because of the 2x upsampling).
-static const uint8_t kFilterExtraRows[3] = { 0, 2, 8 };
-
-static WEBP_INLINE int hev_thresh_from_level(int level, int keyframe) {
-  if (keyframe) {
-    return (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
-  } else {
-    return (level >= 40) ? 3 : (level >= 20) ? 2 : (level >= 15) ? 1 : 0;
-  }
-}
-
-static void DoFilter(const VP8Decoder* const dec, int mb_x, int mb_y) {
-  const VP8ThreadContext* const ctx = &dec->thread_ctx_;
-  const int y_bps = dec->cache_y_stride_;
-  VP8FInfo* const f_info = ctx->f_info_ + mb_x;
-  uint8_t* const y_dst = dec->cache_y_ + ctx->id_ * 16 * y_bps + mb_x * 16;
-  const int level = f_info->f_level_;
-  const int ilevel = f_info->f_ilevel_;
-  const int limit = 2 * level + ilevel;
-  if (level == 0) {
-    return;
-  }
-  if (dec->filter_type_ == 1) {   // simple
-    if (mb_x > 0) {
-      VP8SimpleHFilter16(y_dst, y_bps, limit + 4);
-    }
-    if (f_info->f_inner_) {
-      VP8SimpleHFilter16i(y_dst, y_bps, limit);
-    }
-    if (mb_y > 0) {
-      VP8SimpleVFilter16(y_dst, y_bps, limit + 4);
-    }
-    if (f_info->f_inner_) {
-      VP8SimpleVFilter16i(y_dst, y_bps, limit);
-    }
-  } else {    // complex
-    const int uv_bps = dec->cache_uv_stride_;
-    uint8_t* const u_dst = dec->cache_u_ + ctx->id_ * 8 * uv_bps + mb_x * 8;
-    uint8_t* const v_dst = dec->cache_v_ + ctx->id_ * 8 * uv_bps + mb_x * 8;
-    const int hev_thresh =
-        hev_thresh_from_level(level, dec->frm_hdr_.key_frame_);
-    if (mb_x > 0) {
-      VP8HFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh);
-      VP8HFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh);
-    }
-    if (f_info->f_inner_) {
-      VP8HFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh);
-      VP8HFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh);
-    }
-    if (mb_y > 0) {
-      VP8VFilter16(y_dst, y_bps, limit + 4, ilevel, hev_thresh);
-      VP8VFilter8(u_dst, v_dst, uv_bps, limit + 4, ilevel, hev_thresh);
-    }
-    if (f_info->f_inner_) {
-      VP8VFilter16i(y_dst, y_bps, limit, ilevel, hev_thresh);
-      VP8VFilter8i(u_dst, v_dst, uv_bps, limit, ilevel, hev_thresh);
-    }
-  }
-}
-
-// Filter the decoded macroblock row (if needed)
-static void FilterRow(const VP8Decoder* const dec) {
-  int mb_x;
-  const int mb_y = dec->thread_ctx_.mb_y_;
-  assert(dec->thread_ctx_.filter_row_);
-  for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) {
-    DoFilter(dec, mb_x, mb_y);
-  }
-}
-
-//------------------------------------------------------------------------------
-
-void VP8StoreBlock(VP8Decoder* const dec) {
-  if (dec->filter_type_ > 0) {
-    VP8FInfo* const info = dec->f_info_ + dec->mb_x_;
-    const int skip = dec->mb_info_[dec->mb_x_].skip_;
-    int level = dec->filter_levels_[dec->segment_];
-    if (dec->filter_hdr_.use_lf_delta_) {
-      // TODO(skal): only CURRENT is handled for now.
-      level += dec->filter_hdr_.ref_lf_delta_[0];
-      if (dec->is_i4x4_) {
-        level += dec->filter_hdr_.mode_lf_delta_[0];
-      }
-    }
-    level = (level < 0) ? 0 : (level > 63) ? 63 : level;
-    info->f_level_ = level;
-
-    if (dec->filter_hdr_.sharpness_ > 0) {
-      if (dec->filter_hdr_.sharpness_ > 4) {
-        level >>= 2;
-      } else {
-        level >>= 1;
-      }
-      if (level > 9 - dec->filter_hdr_.sharpness_) {
-        level = 9 - dec->filter_hdr_.sharpness_;
-      }
-    }
-
-    info->f_ilevel_ = (level < 1) ? 1 : level;
-    info->f_inner_ = (!skip || dec->is_i4x4_);
-  }
-  {
-    // Transfer samples to row cache
-    int y;
-    const int y_offset = dec->cache_id_ * 16 * dec->cache_y_stride_;
-    const int uv_offset = dec->cache_id_ * 8 * dec->cache_uv_stride_;
-    uint8_t* const ydst = dec->cache_y_ + dec->mb_x_ * 16 + y_offset;
-    uint8_t* const udst = dec->cache_u_ + dec->mb_x_ * 8 + uv_offset;
-    uint8_t* const vdst = dec->cache_v_ + dec->mb_x_ * 8 + uv_offset;
-    for (y = 0; y < 16; ++y) {
-      memcpy(ydst + y * dec->cache_y_stride_,
-             dec->yuv_b_ + Y_OFF + y * BPS, 16);
-    }
-    for (y = 0; y < 8; ++y) {
-      memcpy(udst + y * dec->cache_uv_stride_,
-           dec->yuv_b_ + U_OFF + y * BPS, 8);
-      memcpy(vdst + y * dec->cache_uv_stride_,
-           dec->yuv_b_ + V_OFF + y * BPS, 8);
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// This function is called after a row of macroblocks is finished decoding.
-// It also takes into account the following restrictions:
-//  * In case of in-loop filtering, we must hold off sending some of the bottom
-//    pixels as they are yet unfiltered. They will be when the next macroblock
-//    row is decoded. Meanwhile, we must preserve them by rotating them in the
-//    cache area. This doesn't hold for the very bottom row of the uncropped
-//    picture of course.
-//  * we must clip the remaining pixels against the cropping area. The VP8Io
-//    struct must have the following fields set correctly before calling put():
-
-#define MACROBLOCK_VPOS(mb_y)  ((mb_y) * 16)    // vertical position of a MB
-
-// Finalize and transmit a complete row. Return false in case of user-abort.
-static int FinishRow(VP8Decoder* const dec, VP8Io* const io) {
-  int ok = 1;
-  const VP8ThreadContext* const ctx = &dec->thread_ctx_;
-  const int extra_y_rows = kFilterExtraRows[dec->filter_type_];
-  const int ysize = extra_y_rows * dec->cache_y_stride_;
-  const int uvsize = (extra_y_rows / 2) * dec->cache_uv_stride_;
-  const int y_offset = ctx->id_ * 16 * dec->cache_y_stride_;
-  const int uv_offset = ctx->id_ * 8 * dec->cache_uv_stride_;
-  uint8_t* const ydst = dec->cache_y_ - ysize + y_offset;
-  uint8_t* const udst = dec->cache_u_ - uvsize + uv_offset;
-  uint8_t* const vdst = dec->cache_v_ - uvsize + uv_offset;
-  const int first_row = (ctx->mb_y_ == 0);
-  const int last_row = (ctx->mb_y_ >= dec->br_mb_y_ - 1);
-  int y_start = MACROBLOCK_VPOS(ctx->mb_y_);
-  int y_end = MACROBLOCK_VPOS(ctx->mb_y_ + 1);
-
-  if (ctx->filter_row_) {
-    FilterRow(dec);
-  }
-
-  if (io->put) {
-    if (!first_row) {
-      y_start -= extra_y_rows;
-      io->y = ydst;
-      io->u = udst;
-      io->v = vdst;
-    } else {
-      io->y = dec->cache_y_ + y_offset;
-      io->u = dec->cache_u_ + uv_offset;
-      io->v = dec->cache_v_ + uv_offset;
-    }
-
-    if (!last_row) {
-      y_end -= extra_y_rows;
-    }
-    if (y_end > io->crop_bottom) {
-      y_end = io->crop_bottom;    // make sure we don't overflow on last row.
-    }
-    io->a = NULL;
-    if (dec->alpha_data_ != NULL && y_start < y_end) {
-      // TODO(skal): several things to correct here:
-      // * testing presence of alpha with dec->alpha_data_ is not a good idea
-      // * we're actually decompressing the full plane only once. It should be
-      //   more obvious from signature.
-      // * we could free alpha_data_ right after this call, but we don't own.
-      io->a = VP8DecompressAlphaRows(dec, y_start, y_end - y_start);
-      if (io->a == NULL) {
-        return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
-                           "Could not decode alpha data.");
-      }
-    }
-    if (y_start < io->crop_top) {
-      const int delta_y = io->crop_top - y_start;
-      y_start = io->crop_top;
-      assert(!(delta_y & 1));
-      io->y += dec->cache_y_stride_ * delta_y;
-      io->u += dec->cache_uv_stride_ * (delta_y >> 1);
-      io->v += dec->cache_uv_stride_ * (delta_y >> 1);
-      if (io->a != NULL) {
-        io->a += io->width * delta_y;
-      }
-    }
-    if (y_start < y_end) {
-      io->y += io->crop_left;
-      io->u += io->crop_left >> 1;
-      io->v += io->crop_left >> 1;
-      if (io->a != NULL) {
-        io->a += io->crop_left;
-      }
-      io->mb_y = y_start - io->crop_top;
-      io->mb_w = io->crop_right - io->crop_left;
-      io->mb_h = y_end - y_start;
-      ok = io->put(io);
-    }
-  }
-  // rotate top samples if needed
-  if (ctx->id_ + 1 == dec->num_caches_) {
-    if (!last_row) {
-      memcpy(dec->cache_y_ - ysize, ydst + 16 * dec->cache_y_stride_, ysize);
-      memcpy(dec->cache_u_ - uvsize, udst + 8 * dec->cache_uv_stride_, uvsize);
-      memcpy(dec->cache_v_ - uvsize, vdst + 8 * dec->cache_uv_stride_, uvsize);
-    }
-  }
-
-  return ok;
-}
-
-#undef MACROBLOCK_VPOS
-
-//------------------------------------------------------------------------------
-
-int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io) {
-  int ok = 1;
-  VP8ThreadContext* const ctx = &dec->thread_ctx_;
-  if (!dec->use_threads_) {
-    // ctx->id_ and ctx->f_info_ are already set
-    ctx->mb_y_ = dec->mb_y_;
-    ctx->filter_row_ = dec->filter_row_;
-    ok = FinishRow(dec, io);
-  } else {
-    WebPWorker* const worker = &dec->worker_;
-    // Finish previous job *before* updating context
-    ok &= WebPWorkerSync(worker);
-    assert(worker->status_ == OK);
-    if (ok) {   // spawn a new deblocking/output job
-      ctx->io_ = *io;
-      ctx->id_ = dec->cache_id_;
-      ctx->mb_y_ = dec->mb_y_;
-      ctx->filter_row_ = dec->filter_row_;
-      if (ctx->filter_row_) {    // just swap filter info
-        VP8FInfo* const tmp = ctx->f_info_;
-        ctx->f_info_ = dec->f_info_;
-        dec->f_info_ = tmp;
-      }
-      WebPWorkerLaunch(worker);
-      if (++dec->cache_id_ == dec->num_caches_) {
-        dec->cache_id_ = 0;
-      }
-    }
-  }
-  return ok;
-}
-
-//------------------------------------------------------------------------------
-// Finish setting up the decoding parameter once user's setup() is called.
-
-VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
-  // Call setup() first. This may trigger additional decoding features on 'io'.
-  // Note: Afterward, we must call teardown() not matter what.
-  if (io->setup && !io->setup(io)) {
-    VP8SetError(dec, VP8_STATUS_USER_ABORT, "Frame setup failed");
-    return dec->status_;
-  }
-
-  // Disable filtering per user request
-  if (io->bypass_filtering) {
-    dec->filter_type_ = 0;
-  }
-  // TODO(skal): filter type / strength / sharpness forcing
-
-  // Define the area where we can skip in-loop filtering, in case of cropping.
-  //
-  // 'Simple' filter reads two luma samples outside of the macroblock and
-  // and filters one. It doesn't filter the chroma samples. Hence, we can
-  // avoid doing the in-loop filtering before crop_top/crop_left position.
-  // For the 'Complex' filter, 3 samples are read and up to 3 are filtered.
-  // Means: there's a dependency chain that goes all the way up to the
-  // top-left corner of the picture (MB #0). We must filter all the previous
-  // macroblocks.
-  // TODO(skal): add an 'approximate_decoding' option, that won't produce
-  // a 1:1 bit-exactness for complex filtering?
-  {
-    const int extra_pixels = kFilterExtraRows[dec->filter_type_];
-    if (dec->filter_type_ == 2) {
-      // For complex filter, we need to preserve the dependency chain.
-      dec->tl_mb_x_ = 0;
-      dec->tl_mb_y_ = 0;
-    } else {
-      // For simple filter, we can filter only the cropped region.
-      // We include 'extra_pixels' on the other side of the boundary, since
-      // vertical or horizontal filtering of the previous macroblock can
-      // modify some abutting pixels.
-      dec->tl_mb_x_ = (io->crop_left - extra_pixels) >> 4;
-      dec->tl_mb_y_ = (io->crop_top - extra_pixels) >> 4;
-      if (dec->tl_mb_x_ < 0) dec->tl_mb_x_ = 0;
-      if (dec->tl_mb_y_ < 0) dec->tl_mb_y_ = 0;
-    }
-    // We need some 'extra' pixels on the right/bottom.
-    dec->br_mb_y_ = (io->crop_bottom + 15 + extra_pixels) >> 4;
-    dec->br_mb_x_ = (io->crop_right + 15 + extra_pixels) >> 4;
-    if (dec->br_mb_x_ > dec->mb_w_) {
-      dec->br_mb_x_ = dec->mb_w_;
-    }
-    if (dec->br_mb_y_ > dec->mb_h_) {
-      dec->br_mb_y_ = dec->mb_h_;
-    }
-  }
-  return VP8_STATUS_OK;
-}
-
-int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io) {
-  int ok = 1;
-  if (dec->use_threads_) {
-    ok = WebPWorkerSync(&dec->worker_);
-  }
-
-  if (io->teardown) {
-    io->teardown(io);
-  }
-  return ok;
-}
-
-//------------------------------------------------------------------------------
-// For multi-threaded decoding we need to use 3 rows of 16 pixels as delay line.
-//
-// Reason is: the deblocking filter cannot deblock the bottom horizontal edges
-// immediately, and needs to wait for first few rows of the next macroblock to
-// be decoded. Hence, deblocking is lagging behind by 4 or 8 pixels (depending
-// on strength).
-// With two threads, the vertical positions of the rows being decoded are:
-// Decode:  [ 0..15][16..31][32..47][48..63][64..79][...
-// Deblock:         [ 0..11][12..27][28..43][44..59][...
-// If we use two threads and two caches of 16 pixels, the sequence would be:
-// Decode:  [ 0..15][16..31][ 0..15!!][16..31][ 0..15][...
-// Deblock:         [ 0..11][12..27!!][-4..11][12..27][...
-// The problem occurs during row [12..15!!] that both the decoding and
-// deblocking threads are writing simultaneously.
-// With 3 cache lines, one get a safe write pattern:
-// Decode:  [ 0..15][16..31][32..47][ 0..15][16..31][32..47][0..
-// Deblock:         [ 0..11][12..27][28..43][-4..11][12..27][28...
-// Note that multi-threaded output _without_ deblocking can make use of two
-// cache lines of 16 pixels only, since there's no lagging behind. The decoding
-// and output process have non-concurrent writing:
-// Decode:  [ 0..15][16..31][ 0..15][16..31][...
-// io->put:         [ 0..15][16..31][ 0..15][...
-
-#define MT_CACHE_LINES 3
-#define ST_CACHE_LINES 1   // 1 cache row only for single-threaded case
-
-// Initialize multi/single-thread worker
-static int InitThreadContext(VP8Decoder* const dec) {
-  dec->cache_id_ = 0;
-  if (dec->use_threads_) {
-    WebPWorker* const worker = &dec->worker_;
-    if (!WebPWorkerReset(worker)) {
-      return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
-                         "thread initialization failed.");
-    }
-    worker->data1 = dec;
-    worker->data2 = (void*)&dec->thread_ctx_.io_;
-    worker->hook = (WebPWorkerHook)FinishRow;
-    dec->num_caches_ =
-      (dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1;
-  } else {
-    dec->num_caches_ = ST_CACHE_LINES;
-  }
-  return 1;
-}
-
-#undef MT_CACHE_LINES
-#undef ST_CACHE_LINES
-
-//------------------------------------------------------------------------------
-// Memory setup
-
-static int AllocateMemory(VP8Decoder* const dec) {
-  const int num_caches = dec->num_caches_;
-  const int mb_w = dec->mb_w_;
-  // Note: we use 'size_t' when there's no overflow risk, uint64_t otherwise.
-  const size_t intra_pred_mode_size = 4 * mb_w * sizeof(uint8_t);
-  const size_t top_size = (16 + 8 + 8) * mb_w;
-  const size_t mb_info_size = (mb_w + 1) * sizeof(VP8MB);
-  const size_t f_info_size =
-      (dec->filter_type_ > 0) ?
-          mb_w * (dec->use_threads_ ? 2 : 1) * sizeof(VP8FInfo)
-        : 0;
-  const size_t yuv_size = YUV_SIZE * sizeof(*dec->yuv_b_);
-  const size_t coeffs_size = 384 * sizeof(*dec->coeffs_);
-  const size_t cache_height = (16 * num_caches
-                            + kFilterExtraRows[dec->filter_type_]) * 3 / 2;
-  const size_t cache_size = top_size * cache_height;
-  // alpha_size is the only one that scales as width x height.
-  const uint64_t alpha_size = (dec->alpha_data_ != NULL) ?
-      (uint64_t)dec->pic_hdr_.width_ * dec->pic_hdr_.height_ : 0ULL;
-  const uint64_t needed = (uint64_t)intra_pred_mode_size
-                        + top_size + mb_info_size + f_info_size
-                        + yuv_size + coeffs_size
-                        + cache_size + alpha_size + ALIGN_MASK;
-  uint8_t* mem;
-
-  if (needed != (size_t)needed) return 0;  // check for overflow
-  if (needed > dec->mem_size_) {
-    free(dec->mem_);
-    dec->mem_size_ = 0;
-    dec->mem_ = WebPSafeMalloc(needed, sizeof(uint8_t));
-    if (dec->mem_ == NULL) {
-      return VP8SetError(dec, VP8_STATUS_OUT_OF_MEMORY,
-                         "no memory during frame initialization.");
-    }
-    // down-cast is ok, thanks to WebPSafeAlloc() above.
-    dec->mem_size_ = (size_t)needed;
-  }
-
-  mem = (uint8_t*)dec->mem_;
-  dec->intra_t_ = (uint8_t*)mem;
-  mem += intra_pred_mode_size;
-
-  dec->y_t_ = (uint8_t*)mem;
-  mem += 16 * mb_w;
-  dec->u_t_ = (uint8_t*)mem;
-  mem += 8 * mb_w;
-  dec->v_t_ = (uint8_t*)mem;
-  mem += 8 * mb_w;
-
-  dec->mb_info_ = ((VP8MB*)mem) + 1;
-  mem += mb_info_size;
-
-  dec->f_info_ = f_info_size ? (VP8FInfo*)mem : NULL;
-  mem += f_info_size;
-  dec->thread_ctx_.id_ = 0;
-  dec->thread_ctx_.f_info_ = dec->f_info_;
-  if (dec->use_threads_) {
-    // secondary cache line. The deblocking process need to make use of the
-    // filtering strength from previous macroblock row, while the new ones
-    // are being decoded in parallel. We'll just swap the pointers.
-    dec->thread_ctx_.f_info_ += mb_w;
-  }
-
-  mem = (uint8_t*)((uintptr_t)(mem + ALIGN_MASK) & ~ALIGN_MASK);
-  assert((yuv_size & ALIGN_MASK) == 0);
-  dec->yuv_b_ = (uint8_t*)mem;
-  mem += yuv_size;
-
-  dec->coeffs_ = (int16_t*)mem;
-  mem += coeffs_size;
-
-  dec->cache_y_stride_ = 16 * mb_w;
-  dec->cache_uv_stride_ = 8 * mb_w;
-  {
-    const int extra_rows = kFilterExtraRows[dec->filter_type_];
-    const int extra_y = extra_rows * dec->cache_y_stride_;
-    const int extra_uv = (extra_rows / 2) * dec->cache_uv_stride_;
-    dec->cache_y_ = ((uint8_t*)mem) + extra_y;
-    dec->cache_u_ = dec->cache_y_
-                  + 16 * num_caches * dec->cache_y_stride_ + extra_uv;
-    dec->cache_v_ = dec->cache_u_
-                  + 8 * num_caches * dec->cache_uv_stride_ + extra_uv;
-    dec->cache_id_ = 0;
-  }
-  mem += cache_size;
-
-  // alpha plane
-  dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL;
-  mem += alpha_size;
-
-  // note: left-info is initialized once for all.
-  memset(dec->mb_info_ - 1, 0, mb_info_size);
-
-  // initialize top
-  memset(dec->intra_t_, B_DC_PRED, intra_pred_mode_size);
-
-  return 1;
-}
-
-static void InitIo(VP8Decoder* const dec, VP8Io* io) {
-  // prepare 'io'
-  io->mb_y = 0;
-  io->y = dec->cache_y_;
-  io->u = dec->cache_u_;
-  io->v = dec->cache_v_;
-  io->y_stride = dec->cache_y_stride_;
-  io->uv_stride = dec->cache_uv_stride_;
-  io->a = NULL;
-}
-
-int VP8InitFrame(VP8Decoder* const dec, VP8Io* io) {
-  if (!InitThreadContext(dec)) return 0;  // call first. Sets dec->num_caches_.
-  if (!AllocateMemory(dec)) return 0;
-  InitIo(dec, io);
-  VP8DspInit();  // Init critical function pointers and look-up tables.
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Main reconstruction function.
-
-static const int kScan[16] = {
-  0 +  0 * BPS,  4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS,
-  0 +  4 * BPS,  4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS,
-  0 +  8 * BPS,  4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS,
-  0 + 12 * BPS,  4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS
-};
-
-static WEBP_INLINE int CheckMode(VP8Decoder* const dec, int mode) {
-  if (mode == B_DC_PRED) {
-    if (dec->mb_x_ == 0) {
-      return (dec->mb_y_ == 0) ? B_DC_PRED_NOTOPLEFT : B_DC_PRED_NOLEFT;
-    } else {
-      return (dec->mb_y_ == 0) ? B_DC_PRED_NOTOP : B_DC_PRED;
-    }
-  }
-  return mode;
-}
-
-static WEBP_INLINE void Copy32b(uint8_t* dst, uint8_t* src) {
-  *(uint32_t*)dst = *(uint32_t*)src;
-}
-
-void VP8ReconstructBlock(VP8Decoder* const dec) {
-  uint8_t* const y_dst = dec->yuv_b_ + Y_OFF;
-  uint8_t* const u_dst = dec->yuv_b_ + U_OFF;
-  uint8_t* const v_dst = dec->yuv_b_ + V_OFF;
-
-  // Rotate in the left samples from previously decoded block. We move four
-  // pixels at a time for alignment reason, and because of in-loop filter.
-  if (dec->mb_x_ > 0) {
-    int j;
-    for (j = -1; j < 16; ++j) {
-      Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]);
-    }
-    for (j = -1; j < 8; ++j) {
-      Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]);
-      Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]);
-    }
-  } else {
-    int j;
-    for (j = 0; j < 16; ++j) {
-      y_dst[j * BPS - 1] = 129;
-    }
-    for (j = 0; j < 8; ++j) {
-      u_dst[j * BPS - 1] = 129;
-      v_dst[j * BPS - 1] = 129;
-    }
-    // Init top-left sample on left column too
-    if (dec->mb_y_ > 0) {
-      y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129;
-    }
-  }
-  {
-    // bring top samples into the cache
-    uint8_t* const top_y = dec->y_t_ + dec->mb_x_ * 16;
-    uint8_t* const top_u = dec->u_t_ + dec->mb_x_ * 8;
-    uint8_t* const top_v = dec->v_t_ + dec->mb_x_ * 8;
-    const int16_t* coeffs = dec->coeffs_;
-    int n;
-
-    if (dec->mb_y_ > 0) {
-      memcpy(y_dst - BPS, top_y, 16);
-      memcpy(u_dst - BPS, top_u, 8);
-      memcpy(v_dst - BPS, top_v, 8);
-    } else if (dec->mb_x_ == 0) {
-      // we only need to do this init once at block (0,0).
-      // Afterward, it remains valid for the whole topmost row.
-      memset(y_dst - BPS - 1, 127, 16 + 4 + 1);
-      memset(u_dst - BPS - 1, 127, 8 + 1);
-      memset(v_dst - BPS - 1, 127, 8 + 1);
-    }
-
-    // predict and add residuals
-
-    if (dec->is_i4x4_) {   // 4x4
-      uint32_t* const top_right = (uint32_t*)(y_dst - BPS + 16);
-
-      if (dec->mb_y_ > 0) {
-        if (dec->mb_x_ >= dec->mb_w_ - 1) {    // on rightmost border
-          top_right[0] = top_y[15] * 0x01010101u;
-        } else {
-          memcpy(top_right, top_y + 16, sizeof(*top_right));
-        }
-      }
-      // replicate the top-right pixels below
-      top_right[BPS] = top_right[2 * BPS] = top_right[3 * BPS] = top_right[0];
-
-      // predict and add residues for all 4x4 blocks in turn.
-      for (n = 0; n < 16; n++) {
-        uint8_t* const dst = y_dst + kScan[n];
-        VP8PredLuma4[dec->imodes_[n]](dst);
-        if (dec->non_zero_ac_ & (1 << n)) {
-          VP8Transform(coeffs + n * 16, dst, 0);
-        } else if (dec->non_zero_ & (1 << n)) {  // only DC is present
-          VP8TransformDC(coeffs + n * 16, dst);
-        }
-      }
-    } else {    // 16x16
-      const int pred_func = CheckMode(dec, dec->imodes_[0]);
-      VP8PredLuma16[pred_func](y_dst);
-      if (dec->non_zero_) {
-        for (n = 0; n < 16; n++) {
-          uint8_t* const dst = y_dst + kScan[n];
-          if (dec->non_zero_ac_ & (1 << n)) {
-            VP8Transform(coeffs + n * 16, dst, 0);
-          } else if (dec->non_zero_ & (1 << n)) {  // only DC is present
-            VP8TransformDC(coeffs + n * 16, dst);
-          }
-        }
-      }
-    }
-    {
-      // Chroma
-      const int pred_func = CheckMode(dec, dec->uvmode_);
-      VP8PredChroma8[pred_func](u_dst);
-      VP8PredChroma8[pred_func](v_dst);
-
-      if (dec->non_zero_ & 0x0f0000) {   // chroma-U
-        const int16_t* const u_coeffs = dec->coeffs_ + 16 * 16;
-        if (dec->non_zero_ac_ & 0x0f0000) {
-          VP8TransformUV(u_coeffs, u_dst);
-        } else {
-          VP8TransformDCUV(u_coeffs, u_dst);
-        }
-      }
-      if (dec->non_zero_ & 0xf00000) {   // chroma-V
-        const int16_t* const v_coeffs = dec->coeffs_ + 20 * 16;
-        if (dec->non_zero_ac_ & 0xf00000) {
-          VP8TransformUV(v_coeffs, v_dst);
-        } else {
-          VP8TransformDCUV(v_coeffs, v_dst);
-        }
-      }
-
-      // stash away top samples for next block
-      if (dec->mb_y_ < dec->mb_h_ - 1) {
-        memcpy(top_y, y_dst + 15 * BPS, 16);
-        memcpy(top_u, u_dst +  7 * BPS,  8);
-        memcpy(top_v, v_dst +  7 * BPS,  8);
-      }
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 785
drivers/webpold/dec/idec.c

@@ -1,785 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Incremental decoding
-//
-// Author: [email protected] (Somnath Banerjee)
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "./webpi.h"
-#include "./vp8i.h"
-#include "../utils/utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// In append mode, buffer allocations increase as multiples of this value.
-// Needs to be a power of 2.
-#define CHUNK_SIZE 4096
-#define MAX_MB_SIZE 4096
-
-//------------------------------------------------------------------------------
-// Data structures for memory and states
-
-// Decoding states. State normally flows like HEADER->PARTS0->DATA->DONE.
-// If there is any error the decoder goes into state ERROR.
-typedef enum {
-  STATE_PRE_VP8,  // All data before that of the first VP8 chunk.
-  STATE_VP8_FRAME_HEADER,  // For VP8 Frame header (within VP8 chunk).
-  STATE_VP8_PARTS0,
-  STATE_VP8_DATA,
-  STATE_VP8L_HEADER,
-  STATE_VP8L_DATA,
-  STATE_DONE,
-  STATE_ERROR
-} DecState;
-
-// Operating state for the MemBuffer
-typedef enum {
-  MEM_MODE_NONE = 0,
-  MEM_MODE_APPEND,
-  MEM_MODE_MAP
-} MemBufferMode;
-
-// storage for partition #0 and partial data (in a rolling fashion)
-typedef struct {
-  MemBufferMode mode_;  // Operation mode
-  size_t start_;        // start location of the data to be decoded
-  size_t end_;          // end location
-  size_t buf_size_;     // size of the allocated buffer
-  uint8_t* buf_;        // We don't own this buffer in case WebPIUpdate()
-
-  size_t part0_size_;         // size of partition #0
-  const uint8_t* part0_buf_;  // buffer to store partition #0
-} MemBuffer;
-
-struct WebPIDecoder {
-  DecState state_;         // current decoding state
-  WebPDecParams params_;   // Params to store output info
-  int is_lossless_;        // for down-casting 'dec_'.
-  void* dec_;              // either a VP8Decoder or a VP8LDecoder instance
-  VP8Io io_;
-
-  MemBuffer mem_;          // input memory buffer.
-  WebPDecBuffer output_;   // output buffer (when no external one is supplied)
-  size_t chunk_size_;      // Compressed VP8/VP8L size extracted from Header.
-};
-
-// MB context to restore in case VP8DecodeMB() fails
-typedef struct {
-  VP8MB left_;
-  VP8MB info_;
-  uint8_t intra_t_[4];
-  uint8_t intra_l_[4];
-  VP8BitReader br_;
-  VP8BitReader token_br_;
-} MBContext;
-
-//------------------------------------------------------------------------------
-// MemBuffer: incoming data handling
-
-static void RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
-  if (br->buf_ != NULL) {
-    br->buf_ += offset;
-    br->buf_end_ += offset;
-  }
-}
-
-static WEBP_INLINE size_t MemDataSize(const MemBuffer* mem) {
-  return (mem->end_ - mem->start_);
-}
-
-static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) {
-  MemBuffer* const mem = &idec->mem_;
-  const uint8_t* const new_base = mem->buf_ + mem->start_;
-  // note: for VP8, setting up idec->io_ is only really needed at the beginning
-  // of the decoding, till partition #0 is complete.
-  idec->io_.data = new_base;
-  idec->io_.data_size = MemDataSize(mem);
-
-  if (idec->dec_ != NULL) {
-    if (!idec->is_lossless_) {
-      VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
-      const int last_part = dec->num_parts_ - 1;
-      if (offset != 0) {
-        int p;
-        for (p = 0; p <= last_part; ++p) {
-          RemapBitReader(dec->parts_ + p, offset);
-        }
-        // Remap partition #0 data pointer to new offset, but only in MAP
-        // mode (in APPEND mode, partition #0 is copied into a fixed memory).
-        if (mem->mode_ == MEM_MODE_MAP) {
-          RemapBitReader(&dec->br_, offset);
-        }
-      }
-      assert(last_part >= 0);
-      dec->parts_[last_part].buf_end_ = mem->buf_ + mem->end_;
-    } else {    // Resize lossless bitreader
-      VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
-      VP8LBitReaderSetBuffer(&dec->br_, new_base, MemDataSize(mem));
-    }
-  }
-}
-
-// Appends data to the end of MemBuffer->buf_. It expands the allocated memory
-// size if required and also updates VP8BitReader's if new memory is allocated.
-static int AppendToMemBuffer(WebPIDecoder* const idec,
-                             const uint8_t* const data, size_t data_size) {
-  MemBuffer* const mem = &idec->mem_;
-  const uint8_t* const old_base = mem->buf_ + mem->start_;
-  assert(mem->mode_ == MEM_MODE_APPEND);
-  if (data_size > MAX_CHUNK_PAYLOAD) {
-    // security safeguard: trying to allocate more than what the format
-    // allows for a chunk should be considered a smoke smell.
-    return 0;
-  }
-
-  if (mem->end_ + data_size > mem->buf_size_) {  // Need some free memory
-    const size_t current_size = MemDataSize(mem);
-    const uint64_t new_size = (uint64_t)current_size + data_size;
-    const uint64_t extra_size = (new_size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);
-    uint8_t* const new_buf =
-        (uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
-    if (new_buf == NULL) return 0;
-    memcpy(new_buf, old_base, current_size);
-    free(mem->buf_);
-    mem->buf_ = new_buf;
-    mem->buf_size_ = (size_t)extra_size;
-    mem->start_ = 0;
-    mem->end_ = current_size;
-  }
-
-  memcpy(mem->buf_ + mem->end_, data, data_size);
-  mem->end_ += data_size;
-  assert(mem->end_ <= mem->buf_size_);
-
-  DoRemap(idec, mem->buf_ + mem->start_ - old_base);
-  return 1;
-}
-
-static int RemapMemBuffer(WebPIDecoder* const idec,
-                          const uint8_t* const data, size_t data_size) {
-  MemBuffer* const mem = &idec->mem_;
-  const uint8_t* const old_base = mem->buf_ + mem->start_;
-  assert(mem->mode_ == MEM_MODE_MAP);
-
-  if (data_size < mem->buf_size_) return 0;  // can't remap to a shorter buffer!
-
-  mem->buf_ = (uint8_t*)data;
-  mem->end_ = mem->buf_size_ = data_size;
-
-  DoRemap(idec, mem->buf_ + mem->start_ - old_base);
-  return 1;
-}
-
-static void InitMemBuffer(MemBuffer* const mem) {
-  mem->mode_       = MEM_MODE_NONE;
-  mem->buf_        = NULL;
-  mem->buf_size_   = 0;
-  mem->part0_buf_  = NULL;
-  mem->part0_size_ = 0;
-}
-
-static void ClearMemBuffer(MemBuffer* const mem) {
-  assert(mem);
-  if (mem->mode_ == MEM_MODE_APPEND) {
-    free(mem->buf_);
-    free((void*)mem->part0_buf_);
-  }
-}
-
-static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) {
-  if (mem->mode_ == MEM_MODE_NONE) {
-    mem->mode_ = expected;    // switch to the expected mode
-  } else if (mem->mode_ != expected) {
-    return 0;         // we mixed the modes => error
-  }
-  assert(mem->mode_ == expected);   // mode is ok
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Macroblock-decoding contexts
-
-static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br,
-                        MBContext* const context) {
-  const VP8BitReader* const br = &dec->br_;
-  const VP8MB* const left = dec->mb_info_ - 1;
-  const VP8MB* const info = dec->mb_info_ + dec->mb_x_;
-
-  context->left_ = *left;
-  context->info_ = *info;
-  context->br_ = *br;
-  context->token_br_ = *token_br;
-  memcpy(context->intra_t_, dec->intra_t_ + 4 * dec->mb_x_, 4);
-  memcpy(context->intra_l_, dec->intra_l_, 4);
-}
-
-static void RestoreContext(const MBContext* context, VP8Decoder* const dec,
-                           VP8BitReader* const token_br) {
-  VP8BitReader* const br = &dec->br_;
-  VP8MB* const left = dec->mb_info_ - 1;
-  VP8MB* const info = dec->mb_info_ + dec->mb_x_;
-
-  *left = context->left_;
-  *info = context->info_;
-  *br = context->br_;
-  *token_br = context->token_br_;
-  memcpy(dec->intra_t_ + 4 * dec->mb_x_, context->intra_t_, 4);
-  memcpy(dec->intra_l_, context->intra_l_, 4);
-}
-
-//------------------------------------------------------------------------------
-
-static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
-  if (idec->state_ == STATE_VP8_DATA) {
-    VP8Io* const io = &idec->io_;
-    if (io->teardown) {
-      io->teardown(io);
-    }
-  }
-  idec->state_ = STATE_ERROR;
-  return error;
-}
-
-static void ChangeState(WebPIDecoder* const idec, DecState new_state,
-                        size_t consumed_bytes) {
-  MemBuffer* const mem = &idec->mem_;
-  idec->state_ = new_state;
-  mem->start_ += consumed_bytes;
-  assert(mem->start_ <= mem->end_);
-  idec->io_.data = mem->buf_ + mem->start_;
-  idec->io_.data_size = MemDataSize(mem);
-}
-
-// Headers
-static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) {
-  MemBuffer* const mem = &idec->mem_;
-  const uint8_t* data = mem->buf_ + mem->start_;
-  size_t curr_size = MemDataSize(mem);
-  VP8StatusCode status;
-  WebPHeaderStructure headers;
-
-  headers.data = data;
-  headers.data_size = curr_size;
-  status = WebPParseHeaders(&headers);
-  if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
-    return VP8_STATUS_SUSPENDED;  // We haven't found a VP8 chunk yet.
-  } else if (status != VP8_STATUS_OK) {
-    return IDecError(idec, status);
-  }
-
-  idec->chunk_size_ = headers.compressed_size;
-  idec->is_lossless_ = headers.is_lossless;
-  if (!idec->is_lossless_) {
-    VP8Decoder* const dec = VP8New();
-    if (dec == NULL) {
-      return VP8_STATUS_OUT_OF_MEMORY;
-    }
-    idec->dec_ = dec;
-#ifdef WEBP_USE_THREAD
-    dec->use_threads_ = (idec->params_.options != NULL) &&
-                        (idec->params_.options->use_threads > 0);
-#else
-    dec->use_threads_ = 0;
-#endif
-    dec->alpha_data_ = headers.alpha_data;
-    dec->alpha_data_size_ = headers.alpha_data_size;
-    ChangeState(idec, STATE_VP8_FRAME_HEADER, headers.offset);
-  } else {
-    VP8LDecoder* const dec = VP8LNew();
-    if (dec == NULL) {
-      return VP8_STATUS_OUT_OF_MEMORY;
-    }
-    idec->dec_ = dec;
-    ChangeState(idec, STATE_VP8L_HEADER, headers.offset);
-  }
-  return VP8_STATUS_OK;
-}
-
-static VP8StatusCode DecodeVP8FrameHeader(WebPIDecoder* const idec) {
-  const uint8_t* data = idec->mem_.buf_ + idec->mem_.start_;
-  const size_t curr_size = MemDataSize(&idec->mem_);
-  uint32_t bits;
-
-  if (curr_size < VP8_FRAME_HEADER_SIZE) {
-    // Not enough data bytes to extract VP8 Frame Header.
-    return VP8_STATUS_SUSPENDED;
-  }
-  if (!VP8GetInfo(data, curr_size, idec->chunk_size_, NULL, NULL)) {
-    return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
-  }
-
-  bits = data[0] | (data[1] << 8) | (data[2] << 16);
-  idec->mem_.part0_size_ = (bits >> 5) + VP8_FRAME_HEADER_SIZE;
-
-  idec->io_.data = data;
-  idec->io_.data_size = curr_size;
-  idec->state_ = STATE_VP8_PARTS0;
-  return VP8_STATUS_OK;
-}
-
-// Partition #0
-static int CopyParts0Data(WebPIDecoder* const idec) {
-  VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
-  VP8BitReader* const br = &dec->br_;
-  const size_t psize = br->buf_end_ - br->buf_;
-  MemBuffer* const mem = &idec->mem_;
-  assert(!idec->is_lossless_);
-  assert(mem->part0_buf_ == NULL);
-  assert(psize > 0);
-  assert(psize <= mem->part0_size_);  // Format limit: no need for runtime check
-  if (mem->mode_ == MEM_MODE_APPEND) {
-    // We copy and grab ownership of the partition #0 data.
-    uint8_t* const part0_buf = (uint8_t*)malloc(psize);
-    if (part0_buf == NULL) {
-      return 0;
-    }
-    memcpy(part0_buf, br->buf_, psize);
-    mem->part0_buf_ = part0_buf;
-    br->buf_ = part0_buf;
-    br->buf_end_ = part0_buf + psize;
-  } else {
-    // Else: just keep pointers to the partition #0's data in dec_->br_.
-  }
-  mem->start_ += psize;
-  return 1;
-}
-
-static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
-  VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
-  VP8Io* const io = &idec->io_;
-  const WebPDecParams* const params = &idec->params_;
-  WebPDecBuffer* const output = params->output;
-
-  // Wait till we have enough data for the whole partition #0
-  if (MemDataSize(&idec->mem_) < idec->mem_.part0_size_) {
-    return VP8_STATUS_SUSPENDED;
-  }
-
-  if (!VP8GetHeaders(dec, io)) {
-    const VP8StatusCode status = dec->status_;
-    if (status == VP8_STATUS_SUSPENDED ||
-        status == VP8_STATUS_NOT_ENOUGH_DATA) {
-      // treating NOT_ENOUGH_DATA as SUSPENDED state
-      return VP8_STATUS_SUSPENDED;
-    }
-    return IDecError(idec, status);
-  }
-
-  // Allocate/Verify output buffer now
-  dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options,
-                                       output);
-  if (dec->status_ != VP8_STATUS_OK) {
-    return IDecError(idec, dec->status_);
-  }
-
-  if (!CopyParts0Data(idec)) {
-    return IDecError(idec, VP8_STATUS_OUT_OF_MEMORY);
-  }
-
-  // Finish setting up the decoding parameters. Will call io->setup().
-  if (VP8EnterCritical(dec, io) != VP8_STATUS_OK) {
-    return IDecError(idec, dec->status_);
-  }
-
-  // Note: past this point, teardown() must always be called
-  // in case of error.
-  idec->state_ = STATE_VP8_DATA;
-  // Allocate memory and prepare everything.
-  if (!VP8InitFrame(dec, io)) {
-    return IDecError(idec, dec->status_);
-  }
-  return VP8_STATUS_OK;
-}
-
-// Remaining partitions
-static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
-  VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
-  VP8Io* const io = &idec->io_;
-
-  assert(dec->ready_);
-
-  for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
-    VP8BitReader* token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
-    if (dec->mb_x_ == 0) {
-      VP8InitScanline(dec);
-    }
-    for (; dec->mb_x_ < dec->mb_w_;  dec->mb_x_++) {
-      MBContext context;
-      SaveContext(dec, token_br, &context);
-
-      if (!VP8DecodeMB(dec, token_br)) {
-        RestoreContext(&context, dec, token_br);
-        // We shouldn't fail when MAX_MB data was available
-        if (dec->num_parts_ == 1 && MemDataSize(&idec->mem_) > MAX_MB_SIZE) {
-          return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
-        }
-        return VP8_STATUS_SUSPENDED;
-      }
-      VP8ReconstructBlock(dec);
-      // Store data and save block's filtering params
-      VP8StoreBlock(dec);
-
-      // Release buffer only if there is only one partition
-      if (dec->num_parts_ == 1) {
-        idec->mem_.start_ = token_br->buf_ - idec->mem_.buf_;
-        assert(idec->mem_.start_ <= idec->mem_.end_);
-      }
-    }
-    if (!VP8ProcessRow(dec, io)) {
-      return IDecError(idec, VP8_STATUS_USER_ABORT);
-    }
-    dec->mb_x_ = 0;
-  }
-  // Synchronize the thread and check for errors.
-  if (!VP8ExitCritical(dec, io)) {
-    return IDecError(idec, VP8_STATUS_USER_ABORT);
-  }
-  dec->ready_ = 0;
-  idec->state_ = STATE_DONE;
-
-  return VP8_STATUS_OK;
-}
-
-static int ErrorStatusLossless(WebPIDecoder* const idec, VP8StatusCode status) {
-  if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) {
-    return VP8_STATUS_SUSPENDED;
-  }
-  return IDecError(idec, status);
-}
-
-static VP8StatusCode DecodeVP8LHeader(WebPIDecoder* const idec) {
-  VP8Io* const io = &idec->io_;
-  VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
-  const WebPDecParams* const params = &idec->params_;
-  WebPDecBuffer* const output = params->output;
-  size_t curr_size = MemDataSize(&idec->mem_);
-  assert(idec->is_lossless_);
-
-  // Wait until there's enough data for decoding header.
-  if (curr_size < (idec->chunk_size_ >> 3)) {
-    return VP8_STATUS_SUSPENDED;
-  }
-  if (!VP8LDecodeHeader(dec, io)) {
-    return ErrorStatusLossless(idec, dec->status_);
-  }
-  // Allocate/verify output buffer now.
-  dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options,
-                                       output);
-  if (dec->status_ != VP8_STATUS_OK) {
-    return IDecError(idec, dec->status_);
-  }
-
-  idec->state_ = STATE_VP8L_DATA;
-  return VP8_STATUS_OK;
-}
-
-static VP8StatusCode DecodeVP8LData(WebPIDecoder* const idec) {
-  VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
-  const size_t curr_size = MemDataSize(&idec->mem_);
-  assert(idec->is_lossless_);
-
-  // At present Lossless decoder can't decode image incrementally. So wait till
-  // all the image data is aggregated before image can be decoded.
-  if (curr_size < idec->chunk_size_) {
-    return VP8_STATUS_SUSPENDED;
-  }
-
-  if (!VP8LDecodeImage(dec)) {
-    return ErrorStatusLossless(idec, dec->status_);
-  }
-
-  idec->state_ = STATE_DONE;
-
-  return VP8_STATUS_OK;
-}
-
-  // Main decoding loop
-static VP8StatusCode IDecode(WebPIDecoder* idec) {
-  VP8StatusCode status = VP8_STATUS_SUSPENDED;
-
-  if (idec->state_ == STATE_PRE_VP8) {
-    status = DecodeWebPHeaders(idec);
-  } else {
-    if (idec->dec_ == NULL) {
-      return VP8_STATUS_SUSPENDED;    // can't continue if we have no decoder.
-    }
-  }
-  if (idec->state_ == STATE_VP8_FRAME_HEADER) {
-    status = DecodeVP8FrameHeader(idec);
-  }
-  if (idec->state_ == STATE_VP8_PARTS0) {
-    status = DecodePartition0(idec);
-  }
-  if (idec->state_ == STATE_VP8_DATA) {
-    status = DecodeRemaining(idec);
-  }
-  if (idec->state_ == STATE_VP8L_HEADER) {
-    status = DecodeVP8LHeader(idec);
-  }
-  if (idec->state_ == STATE_VP8L_DATA) {
-    status = DecodeVP8LData(idec);
-  }
-  return status;
-}
-
-//------------------------------------------------------------------------------
-// Public functions
-
-WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
-  WebPIDecoder* idec = (WebPIDecoder*)calloc(1, sizeof(*idec));
-  if (idec == NULL) {
-    return NULL;
-  }
-
-  idec->state_ = STATE_PRE_VP8;
-  idec->chunk_size_ = 0;
-
-  InitMemBuffer(&idec->mem_);
-  WebPInitDecBuffer(&idec->output_);
-  VP8InitIo(&idec->io_);
-
-  WebPResetDecParams(&idec->params_);
-  idec->params_.output = output_buffer ? output_buffer : &idec->output_;
-  WebPInitCustomIo(&idec->params_, &idec->io_);  // Plug the I/O functions.
-
-  return idec;
-}
-
-WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
-                          WebPDecoderConfig* config) {
-  WebPIDecoder* idec;
-
-  // Parse the bitstream's features, if requested:
-  if (data != NULL && data_size > 0 && config != NULL) {
-    if (WebPGetFeatures(data, data_size, &config->input) != VP8_STATUS_OK) {
-      return NULL;
-    }
-  }
-  // Create an instance of the incremental decoder
-  idec = WebPINewDecoder(config ? &config->output : NULL);
-  if (idec == NULL) {
-    return NULL;
-  }
-  // Finish initialization
-  if (config != NULL) {
-    idec->params_.options = &config->options;
-  }
-  return idec;
-}
-
-void WebPIDelete(WebPIDecoder* idec) {
-  if (idec == NULL) return;
-  if (idec->dec_ != NULL) {
-    if (!idec->is_lossless_) {
-      VP8Delete(idec->dec_);
-    } else {
-      VP8LDelete(idec->dec_);
-    }
-  }
-  ClearMemBuffer(&idec->mem_);
-  WebPFreeDecBuffer(&idec->output_);
-  free(idec);
-}
-
-//------------------------------------------------------------------------------
-// Wrapper toward WebPINewDecoder
-
-WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer,
-                          size_t output_buffer_size, int output_stride) {
-  WebPIDecoder* idec;
-  if (mode >= MODE_YUV) return NULL;
-  idec = WebPINewDecoder(NULL);
-  if (idec == NULL) return NULL;
-  idec->output_.colorspace = mode;
-  idec->output_.is_external_memory = 1;
-  idec->output_.u.RGBA.rgba = output_buffer;
-  idec->output_.u.RGBA.stride = output_stride;
-  idec->output_.u.RGBA.size = output_buffer_size;
-  return idec;
-}
-
-WebPIDecoder* WebPINewYUVA(uint8_t* luma, size_t luma_size, int luma_stride,
-                           uint8_t* u, size_t u_size, int u_stride,
-                           uint8_t* v, size_t v_size, int v_stride,
-                           uint8_t* a, size_t a_size, int a_stride) {
-  WebPIDecoder* const idec = WebPINewDecoder(NULL);
-  if (idec == NULL) return NULL;
-  idec->output_.colorspace = (a == NULL) ? MODE_YUV : MODE_YUVA;
-  idec->output_.is_external_memory = 1;
-  idec->output_.u.YUVA.y = luma;
-  idec->output_.u.YUVA.y_stride = luma_stride;
-  idec->output_.u.YUVA.y_size = luma_size;
-  idec->output_.u.YUVA.u = u;
-  idec->output_.u.YUVA.u_stride = u_stride;
-  idec->output_.u.YUVA.u_size = u_size;
-  idec->output_.u.YUVA.v = v;
-  idec->output_.u.YUVA.v_stride = v_stride;
-  idec->output_.u.YUVA.v_size = v_size;
-  idec->output_.u.YUVA.a = a;
-  idec->output_.u.YUVA.a_stride = a_stride;
-  idec->output_.u.YUVA.a_size = a_size;
-  return idec;
-}
-
-WebPIDecoder* WebPINewYUV(uint8_t* luma, size_t luma_size, int luma_stride,
-                          uint8_t* u, size_t u_size, int u_stride,
-                          uint8_t* v, size_t v_size, int v_stride) {
-  return WebPINewYUVA(luma, luma_size, luma_stride,
-                      u, u_size, u_stride,
-                      v, v_size, v_stride,
-                      NULL, 0, 0);
-}
-
-//------------------------------------------------------------------------------
-
-static VP8StatusCode IDecCheckStatus(const WebPIDecoder* const idec) {
-  assert(idec);
-  if (idec->state_ == STATE_ERROR) {
-    return VP8_STATUS_BITSTREAM_ERROR;
-  }
-  if (idec->state_ == STATE_DONE) {
-    return VP8_STATUS_OK;
-  }
-  return VP8_STATUS_SUSPENDED;
-}
-
-VP8StatusCode WebPIAppend(WebPIDecoder* idec,
-                          const uint8_t* data, size_t data_size) {
-  VP8StatusCode status;
-  if (idec == NULL || data == NULL) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-  status = IDecCheckStatus(idec);
-  if (status != VP8_STATUS_SUSPENDED) {
-    return status;
-  }
-  // Check mixed calls between RemapMemBuffer and AppendToMemBuffer.
-  if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_APPEND)) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-  // Append data to memory buffer
-  if (!AppendToMemBuffer(idec, data, data_size)) {
-    return VP8_STATUS_OUT_OF_MEMORY;
-  }
-  return IDecode(idec);
-}
-
-VP8StatusCode WebPIUpdate(WebPIDecoder* idec,
-                          const uint8_t* data, size_t data_size) {
-  VP8StatusCode status;
-  if (idec == NULL || data == NULL) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-  status = IDecCheckStatus(idec);
-  if (status != VP8_STATUS_SUSPENDED) {
-    return status;
-  }
-  // Check mixed calls between RemapMemBuffer and AppendToMemBuffer.
-  if (!CheckMemBufferMode(&idec->mem_, MEM_MODE_MAP)) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-  // Make the memory buffer point to the new buffer
-  if (!RemapMemBuffer(idec, data, data_size)) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-  return IDecode(idec);
-}
-
-//------------------------------------------------------------------------------
-
-static const WebPDecBuffer* GetOutputBuffer(const WebPIDecoder* const idec) {
-  if (idec == NULL || idec->dec_ == NULL) {
-    return NULL;
-  }
-  if (idec->state_ <= STATE_VP8_PARTS0) {
-    return NULL;
-  }
-  return idec->params_.output;
-}
-
-const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec,
-                                      int* left, int* top,
-                                      int* width, int* height) {
-  const WebPDecBuffer* const src = GetOutputBuffer(idec);
-  if (left != NULL) *left = 0;
-  if (top != NULL) *top = 0;
-  // TODO(skal): later include handling of rotations.
-  if (src) {
-    if (width != NULL) *width = src->width;
-    if (height != NULL) *height = idec->params_.last_y;
-  } else {
-    if (width != NULL) *width = 0;
-    if (height != NULL) *height = 0;
-  }
-  return src;
-}
-
-uint8_t* WebPIDecGetRGB(const WebPIDecoder* idec, int* last_y,
-                        int* width, int* height, int* stride) {
-  const WebPDecBuffer* const src = GetOutputBuffer(idec);
-  if (src == NULL) return NULL;
-  if (src->colorspace >= MODE_YUV) {
-    return NULL;
-  }
-
-  if (last_y != NULL) *last_y = idec->params_.last_y;
-  if (width != NULL) *width = src->width;
-  if (height != NULL) *height = src->height;
-  if (stride != NULL) *stride = src->u.RGBA.stride;
-
-  return src->u.RGBA.rgba;
-}
-
-uint8_t* WebPIDecGetYUVA(const WebPIDecoder* idec, int* last_y,
-                         uint8_t** u, uint8_t** v, uint8_t** a,
-                         int* width, int* height,
-                         int* stride, int* uv_stride, int* a_stride) {
-  const WebPDecBuffer* const src = GetOutputBuffer(idec);
-  if (src == NULL) return NULL;
-  if (src->colorspace < MODE_YUV) {
-    return NULL;
-  }
-
-  if (last_y != NULL) *last_y = idec->params_.last_y;
-  if (u != NULL) *u = src->u.YUVA.u;
-  if (v != NULL) *v = src->u.YUVA.v;
-  if (a != NULL) *a = src->u.YUVA.a;
-  if (width != NULL) *width = src->width;
-  if (height != NULL) *height = src->height;
-  if (stride != NULL) *stride = src->u.YUVA.y_stride;
-  if (uv_stride != NULL) *uv_stride = src->u.YUVA.u_stride;
-  if (a_stride != NULL) *a_stride = src->u.YUVA.a_stride;
-
-  return src->u.YUVA.y;
-}
-
-int WebPISetIOHooks(WebPIDecoder* const idec,
-                    VP8IoPutHook put,
-                    VP8IoSetupHook setup,
-                    VP8IoTeardownHook teardown,
-                    void* user_data) {
-  if (idec == NULL || idec->state_ > STATE_PRE_VP8) {
-    return 0;
-  }
-
-  idec->io_.put = put;
-  idec->io_.setup = setup;
-  idec->io_.teardown = teardown;
-  idec->io_.opaque = user_data;
-
-  return 1;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 633
drivers/webpold/dec/io.c

@@ -1,633 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// functions for sample output.
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-#include "../dec/vp8i.h"
-#include "./webpi.h"
-#include "../dsp/dsp.h"
-#include "../dsp/yuv.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Main YUV<->RGB conversion functions
-
-static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
-  WebPDecBuffer* output = p->output;
-  const WebPYUVABuffer* const buf = &output->u.YUVA;
-  uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
-  uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
-  uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
-  const int mb_w = io->mb_w;
-  const int mb_h = io->mb_h;
-  const int uv_w = (mb_w + 1) / 2;
-  const int uv_h = (mb_h + 1) / 2;
-  int j;
-  for (j = 0; j < mb_h; ++j) {
-    memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
-  }
-  for (j = 0; j < uv_h; ++j) {
-    memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
-    memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
-  }
-  return io->mb_h;
-}
-
-// Point-sampling U/V sampler.
-static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
-  WebPDecBuffer* output = p->output;
-  const WebPRGBABuffer* const buf = &output->u.RGBA;
-  uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
-  const uint8_t* y_src = io->y;
-  const uint8_t* u_src = io->u;
-  const uint8_t* v_src = io->v;
-  const WebPSampleLinePairFunc sample = WebPSamplers[output->colorspace];
-  const int mb_w = io->mb_w;
-  const int last = io->mb_h - 1;
-  int j;
-  for (j = 0; j < last; j += 2) {
-    sample(y_src, y_src + io->y_stride, u_src, v_src,
-           dst, dst + buf->stride, mb_w);
-    y_src += 2 * io->y_stride;
-    u_src += io->uv_stride;
-    v_src += io->uv_stride;
-    dst += 2 * buf->stride;
-  }
-  if (j == last) {  // Just do the last line twice
-    sample(y_src, y_src, u_src, v_src, dst, dst, mb_w);
-  }
-  return io->mb_h;
-}
-
-//------------------------------------------------------------------------------
-// YUV444 -> RGB conversion
-
-#if 0   // TODO(skal): this is for future rescaling.
-static int EmitRGB(const VP8Io* const io, WebPDecParams* const p) {
-  WebPDecBuffer* output = p->output;
-  const WebPRGBABuffer* const buf = &output->u.RGBA;
-  uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
-  const uint8_t* y_src = io->y;
-  const uint8_t* u_src = io->u;
-  const uint8_t* v_src = io->v;
-  const WebPYUV444Converter convert = WebPYUV444Converters[output->colorspace];
-  const int mb_w = io->mb_w;
-  const int last = io->mb_h;
-  int j;
-  for (j = 0; j < last; ++j) {
-    convert(y_src, u_src, v_src, dst, mb_w);
-    y_src += io->y_stride;
-    u_src += io->uv_stride;
-    v_src += io->uv_stride;
-    dst += buf->stride;
-  }
-  return io->mb_h;
-}
-#endif
-
-//------------------------------------------------------------------------------
-// Fancy upsampling
-
-#ifdef FANCY_UPSAMPLING
-static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
-  int num_lines_out = io->mb_h;   // a priori guess
-  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
-  WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
-  const uint8_t* cur_y = io->y;
-  const uint8_t* cur_u = io->u;
-  const uint8_t* cur_v = io->v;
-  const uint8_t* top_u = p->tmp_u;
-  const uint8_t* top_v = p->tmp_v;
-  int y = io->mb_y;
-  const int y_end = io->mb_y + io->mb_h;
-  const int mb_w = io->mb_w;
-  const int uv_w = (mb_w + 1) / 2;
-
-  if (y == 0) {
-    // First line is special cased. We mirror the u/v samples at boundary.
-    upsample(NULL, cur_y, cur_u, cur_v, cur_u, cur_v, NULL, dst, mb_w);
-  } else {
-    // We can finish the left-over line from previous call.
-    upsample(p->tmp_y, cur_y, top_u, top_v, cur_u, cur_v,
-             dst - buf->stride, dst, mb_w);
-    ++num_lines_out;
-  }
-  // Loop over each output pairs of row.
-  for (; y + 2 < y_end; y += 2) {
-    top_u = cur_u;
-    top_v = cur_v;
-    cur_u += io->uv_stride;
-    cur_v += io->uv_stride;
-    dst += 2 * buf->stride;
-    cur_y += 2 * io->y_stride;
-    upsample(cur_y - io->y_stride, cur_y,
-             top_u, top_v, cur_u, cur_v,
-             dst - buf->stride, dst, mb_w);
-  }
-  // move to last row
-  cur_y += io->y_stride;
-  if (io->crop_top + y_end < io->crop_bottom) {
-    // Save the unfinished samples for next call (as we're not done yet).
-    memcpy(p->tmp_y, cur_y, mb_w * sizeof(*p->tmp_y));
-    memcpy(p->tmp_u, cur_u, uv_w * sizeof(*p->tmp_u));
-    memcpy(p->tmp_v, cur_v, uv_w * sizeof(*p->tmp_v));
-    // The fancy upsampler leaves a row unfinished behind
-    // (except for the very last row)
-    num_lines_out--;
-  } else {
-    // Process the very last row of even-sized picture
-    if (!(y_end & 1)) {
-      upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v,
-               dst + buf->stride, NULL, mb_w);
-    }
-  }
-  return num_lines_out;
-}
-
-#endif    /* FANCY_UPSAMPLING */
-
-//------------------------------------------------------------------------------
-
-static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p) {
-  const uint8_t* alpha = io->a;
-  const WebPYUVABuffer* const buf = &p->output->u.YUVA;
-  const int mb_w = io->mb_w;
-  const int mb_h = io->mb_h;
-  uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
-  int j;
-
-  if (alpha != NULL) {
-    for (j = 0; j < mb_h; ++j) {
-      memcpy(dst, alpha, mb_w * sizeof(*dst));
-      alpha += io->width;
-      dst += buf->a_stride;
-    }
-  } else if (buf->a != NULL) {
-    // the user requested alpha, but there is none, set it to opaque.
-    for (j = 0; j < mb_h; ++j) {
-      memset(dst, 0xff, mb_w * sizeof(*dst));
-      dst += buf->a_stride;
-    }
-  }
-  return 0;
-}
-
-static int GetAlphaSourceRow(const VP8Io* const io,
-                             const uint8_t** alpha, int* const num_rows) {
-  int start_y = io->mb_y;
-  *num_rows = io->mb_h;
-
-  // Compensate for the 1-line delay of the fancy upscaler.
-  // This is similar to EmitFancyRGB().
-  if (io->fancy_upsampling) {
-    if (start_y == 0) {
-      // We don't process the last row yet. It'll be done during the next call.
-      --*num_rows;
-    } else {
-      --start_y;
-      // Fortunately, *alpha data is persistent, so we can go back
-      // one row and finish alpha blending, now that the fancy upscaler
-      // completed the YUV->RGB interpolation.
-      *alpha -= io->width;
-    }
-    if (io->crop_top + io->mb_y + io->mb_h == io->crop_bottom) {
-      // If it's the very last call, we process all the remaining rows!
-      *num_rows = io->crop_bottom - io->crop_top - start_y;
-    }
-  }
-  return start_y;
-}
-
-static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p) {
-  const uint8_t* alpha = io->a;
-  if (alpha != NULL) {
-    const int mb_w = io->mb_w;
-    const WEBP_CSP_MODE colorspace = p->output->colorspace;
-    const int alpha_first =
-        (colorspace == MODE_ARGB || colorspace == MODE_Argb);
-    const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-    int num_rows;
-    const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
-    uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
-    uint8_t* dst = base_rgba + (alpha_first ? 0 : 3);
-    uint32_t alpha_mask = 0xff;
-    int i, j;
-
-    for (j = 0; j < num_rows; ++j) {
-      for (i = 0; i < mb_w; ++i) {
-        const uint32_t alpha_value = alpha[i];
-        dst[4 * i] = alpha_value;
-        alpha_mask &= alpha_value;
-      }
-      alpha += io->width;
-      dst += buf->stride;
-    }
-    // alpha_mask is < 0xff if there's non-trivial alpha to premultiply with.
-    if (alpha_mask != 0xff && WebPIsPremultipliedMode(colorspace)) {
-      WebPApplyAlphaMultiply(base_rgba, alpha_first,
-                             mb_w, num_rows, buf->stride);
-    }
-  }
-  return 0;
-}
-
-static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p) {
-  const uint8_t* alpha = io->a;
-  if (alpha != NULL) {
-    const int mb_w = io->mb_w;
-    const WEBP_CSP_MODE colorspace = p->output->colorspace;
-    const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-    int num_rows;
-    const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
-    uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
-    uint8_t* alpha_dst = base_rgba + 1;
-    uint32_t alpha_mask = 0x0f;
-    int i, j;
-
-    for (j = 0; j < num_rows; ++j) {
-      for (i = 0; i < mb_w; ++i) {
-        // Fill in the alpha value (converted to 4 bits).
-        const uint32_t alpha_value = alpha[i] >> 4;
-        alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value;
-        alpha_mask &= alpha_value;
-      }
-      alpha += io->width;
-      alpha_dst += buf->stride;
-    }
-    if (alpha_mask != 0x0f && WebPIsPremultipliedMode(colorspace)) {
-      WebPApplyAlphaMultiply4444(base_rgba, mb_w, num_rows, buf->stride);
-    }
-  }
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// YUV rescaling (no final RGB conversion needed)
-
-static int Rescale(const uint8_t* src, int src_stride,
-                   int new_lines, WebPRescaler* const wrk) {
-  int num_lines_out = 0;
-  while (new_lines > 0) {    // import new contributions of source rows.
-    const int lines_in = WebPRescalerImport(wrk, new_lines, src, src_stride);
-    src += lines_in * src_stride;
-    new_lines -= lines_in;
-    num_lines_out += WebPRescalerExport(wrk);    // emit output row(s)
-  }
-  return num_lines_out;
-}
-
-static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
-  const int mb_h = io->mb_h;
-  const int uv_mb_h = (mb_h + 1) >> 1;
-  const int num_lines_out = Rescale(io->y, io->y_stride, mb_h, &p->scaler_y);
-  Rescale(io->u, io->uv_stride, uv_mb_h, &p->scaler_u);
-  Rescale(io->v, io->uv_stride, uv_mb_h, &p->scaler_v);
-  return num_lines_out;
-}
-
-static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p) {
-  if (io->a != NULL) {
-    Rescale(io->a, io->width, io->mb_h, &p->scaler_a);
-  }
-  return 0;
-}
-
-static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
-  const int has_alpha = WebPIsAlphaMode(p->output->colorspace);
-  const WebPYUVABuffer* const buf = &p->output->u.YUVA;
-  const int out_width  = io->scaled_width;
-  const int out_height = io->scaled_height;
-  const int uv_out_width  = (out_width + 1) >> 1;
-  const int uv_out_height = (out_height + 1) >> 1;
-  const int uv_in_width  = (io->mb_w + 1) >> 1;
-  const int uv_in_height = (io->mb_h + 1) >> 1;
-  const size_t work_size = 2 * out_width;   // scratch memory for luma rescaler
-  const size_t uv_work_size = 2 * uv_out_width;  // and for each u/v ones
-  size_t tmp_size;
-  int32_t* work;
-
-  tmp_size = work_size + 2 * uv_work_size;
-  if (has_alpha) {
-    tmp_size += work_size;
-  }
-  p->memory = calloc(1, tmp_size * sizeof(*work));
-  if (p->memory == NULL) {
-    return 0;   // memory error
-  }
-  work = (int32_t*)p->memory;
-  WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h,
-                   buf->y, out_width, out_height, buf->y_stride, 1,
-                   io->mb_w, out_width, io->mb_h, out_height,
-                   work);
-  WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height,
-                   buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
-                   uv_in_width, uv_out_width,
-                   uv_in_height, uv_out_height,
-                   work + work_size);
-  WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height,
-                   buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
-                   uv_in_width, uv_out_width,
-                   uv_in_height, uv_out_height,
-                   work + work_size + uv_work_size);
-  p->emit = EmitRescaledYUV;
-
-  if (has_alpha) {
-    WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h,
-                     buf->a, out_width, out_height, buf->a_stride, 1,
-                     io->mb_w, out_width, io->mb_h, out_height,
-                     work + work_size + 2 * uv_work_size);
-    p->emit_alpha = EmitRescaledAlphaYUV;
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// RGBA rescaling
-
-static int ExportRGB(WebPDecParams* const p, int y_pos) {
-  const WebPYUV444Converter convert =
-      WebPYUV444Converters[p->output->colorspace];
-  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* dst = buf->rgba + (p->last_y + y_pos) * buf->stride;
-  int num_lines_out = 0;
-  // For RGB rescaling, because of the YUV420, current scan position
-  // U/V can be +1/-1 line from the Y one.  Hence the double test.
-  while (WebPRescalerHasPendingOutput(&p->scaler_y) &&
-         WebPRescalerHasPendingOutput(&p->scaler_u)) {
-    assert(p->last_y + y_pos + num_lines_out < p->output->height);
-    assert(p->scaler_u.y_accum == p->scaler_v.y_accum);
-    WebPRescalerExportRow(&p->scaler_y);
-    WebPRescalerExportRow(&p->scaler_u);
-    WebPRescalerExportRow(&p->scaler_v);
-    convert(p->scaler_y.dst, p->scaler_u.dst, p->scaler_v.dst,
-            dst, p->scaler_y.dst_width);
-    dst += buf->stride;
-    ++num_lines_out;
-  }
-  return num_lines_out;
-}
-
-static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
-  const int mb_h = io->mb_h;
-  const int uv_mb_h = (mb_h + 1) >> 1;
-  int j = 0, uv_j = 0;
-  int num_lines_out = 0;
-  while (j < mb_h) {
-    const int y_lines_in =
-        WebPRescalerImport(&p->scaler_y, mb_h - j,
-                           io->y + j * io->y_stride, io->y_stride);
-    const int u_lines_in =
-        WebPRescalerImport(&p->scaler_u, uv_mb_h - uv_j,
-                           io->u + uv_j * io->uv_stride, io->uv_stride);
-    const int v_lines_in =
-        WebPRescalerImport(&p->scaler_v, uv_mb_h - uv_j,
-                           io->v + uv_j * io->uv_stride, io->uv_stride);
-    (void)v_lines_in;   // remove a gcc warning
-    assert(u_lines_in == v_lines_in);
-    j += y_lines_in;
-    uv_j += u_lines_in;
-    num_lines_out += ExportRGB(p, num_lines_out);
-  }
-  return num_lines_out;
-}
-
-static int ExportAlpha(WebPDecParams* const p, int y_pos) {
-  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* const base_rgba = buf->rgba + (p->last_y + y_pos) * buf->stride;
-  const WEBP_CSP_MODE colorspace = p->output->colorspace;
-  const int alpha_first =
-      (colorspace == MODE_ARGB || colorspace == MODE_Argb);
-  uint8_t* dst = base_rgba + (alpha_first ? 0 : 3);
-  int num_lines_out = 0;
-  const int is_premult_alpha = WebPIsPremultipliedMode(colorspace);
-  uint32_t alpha_mask = 0xff;
-  const int width = p->scaler_a.dst_width;
-
-  while (WebPRescalerHasPendingOutput(&p->scaler_a)) {
-    int i;
-    assert(p->last_y + y_pos + num_lines_out < p->output->height);
-    WebPRescalerExportRow(&p->scaler_a);
-    for (i = 0; i < width; ++i) {
-      const uint32_t alpha_value = p->scaler_a.dst[i];
-      dst[4 * i] = alpha_value;
-      alpha_mask &= alpha_value;
-    }
-    dst += buf->stride;
-    ++num_lines_out;
-  }
-  if (is_premult_alpha && alpha_mask != 0xff) {
-    WebPApplyAlphaMultiply(base_rgba, alpha_first,
-                           width, num_lines_out, buf->stride);
-  }
-  return num_lines_out;
-}
-
-static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos) {
-  const WebPRGBABuffer* const buf = &p->output->u.RGBA;
-  uint8_t* const base_rgba = buf->rgba + (p->last_y + y_pos) * buf->stride;
-  uint8_t* alpha_dst = base_rgba + 1;
-  int num_lines_out = 0;
-  const WEBP_CSP_MODE colorspace = p->output->colorspace;
-  const int width = p->scaler_a.dst_width;
-  const int is_premult_alpha = WebPIsPremultipliedMode(colorspace);
-  uint32_t alpha_mask = 0x0f;
-
-  while (WebPRescalerHasPendingOutput(&p->scaler_a)) {
-    int i;
-    assert(p->last_y + y_pos + num_lines_out < p->output->height);
-    WebPRescalerExportRow(&p->scaler_a);
-    for (i = 0; i < width; ++i) {
-      // Fill in the alpha value (converted to 4 bits).
-      const uint32_t alpha_value = p->scaler_a.dst[i] >> 4;
-      alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value;
-      alpha_mask &= alpha_value;
-    }
-    alpha_dst += buf->stride;
-    ++num_lines_out;
-  }
-  if (is_premult_alpha && alpha_mask != 0x0f) {
-    WebPApplyAlphaMultiply4444(base_rgba, width, num_lines_out, buf->stride);
-  }
-  return num_lines_out;
-}
-
-static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p) {
-  if (io->a != NULL) {
-    WebPRescaler* const scaler = &p->scaler_a;
-    int j = 0;
-    int pos = 0;
-    while (j < io->mb_h) {
-      j += WebPRescalerImport(scaler, io->mb_h - j,
-                              io->a + j * io->width, io->width);
-      pos += p->emit_alpha_row(p, pos);
-    }
-  }
-  return 0;
-}
-
-static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
-  const int has_alpha = WebPIsAlphaMode(p->output->colorspace);
-  const int out_width  = io->scaled_width;
-  const int out_height = io->scaled_height;
-  const int uv_in_width  = (io->mb_w + 1) >> 1;
-  const int uv_in_height = (io->mb_h + 1) >> 1;
-  const size_t work_size = 2 * out_width;   // scratch memory for one rescaler
-  int32_t* work;  // rescalers work area
-  uint8_t* tmp;   // tmp storage for scaled YUV444 samples before RGB conversion
-  size_t tmp_size1, tmp_size2;
-
-  tmp_size1 = 3 * work_size;
-  tmp_size2 = 3 * out_width;
-  if (has_alpha) {
-    tmp_size1 += work_size;
-    tmp_size2 += out_width;
-  }
-  p->memory = calloc(1, tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp));
-  if (p->memory == NULL) {
-    return 0;   // memory error
-  }
-  work = (int32_t*)p->memory;
-  tmp = (uint8_t*)(work + tmp_size1);
-  WebPRescalerInit(&p->scaler_y, io->mb_w, io->mb_h,
-                   tmp + 0 * out_width, out_width, out_height, 0, 1,
-                   io->mb_w, out_width, io->mb_h, out_height,
-                   work + 0 * work_size);
-  WebPRescalerInit(&p->scaler_u, uv_in_width, uv_in_height,
-                   tmp + 1 * out_width, out_width, out_height, 0, 1,
-                   io->mb_w, 2 * out_width, io->mb_h, 2 * out_height,
-                   work + 1 * work_size);
-  WebPRescalerInit(&p->scaler_v, uv_in_width, uv_in_height,
-                   tmp + 2 * out_width, out_width, out_height, 0, 1,
-                   io->mb_w, 2 * out_width, io->mb_h, 2 * out_height,
-                   work + 2 * work_size);
-  p->emit = EmitRescaledRGB;
-
-  if (has_alpha) {
-    WebPRescalerInit(&p->scaler_a, io->mb_w, io->mb_h,
-                     tmp + 3 * out_width, out_width, out_height, 0, 1,
-                     io->mb_w, out_width, io->mb_h, out_height,
-                     work + 3 * work_size);
-    p->emit_alpha = EmitRescaledAlphaRGB;
-    if (p->output->colorspace == MODE_RGBA_4444 ||
-        p->output->colorspace == MODE_rgbA_4444) {
-      p->emit_alpha_row = ExportAlphaRGBA4444;
-    } else {
-      p->emit_alpha_row = ExportAlpha;
-    }
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Default custom functions
-
-static int CustomSetup(VP8Io* io) {
-  WebPDecParams* const p = (WebPDecParams*)io->opaque;
-  const WEBP_CSP_MODE colorspace = p->output->colorspace;
-  const int is_rgb = WebPIsRGBMode(colorspace);
-  const int is_alpha = WebPIsAlphaMode(colorspace);
-
-  p->memory = NULL;
-  p->emit = NULL;
-  p->emit_alpha = NULL;
-  p->emit_alpha_row = NULL;
-  if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) {
-    return 0;
-  }
-
-  if (io->use_scaling) {
-    const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p);
-    if (!ok) {
-      return 0;    // memory error
-    }
-  } else {
-    if (is_rgb) {
-      p->emit = EmitSampledRGB;   // default
-#ifdef FANCY_UPSAMPLING
-      if (io->fancy_upsampling) {
-        const int uv_width = (io->mb_w + 1) >> 1;
-        p->memory = malloc(io->mb_w + 2 * uv_width);
-        if (p->memory == NULL) {
-          return 0;   // memory error.
-        }
-        p->tmp_y = (uint8_t*)p->memory;
-        p->tmp_u = p->tmp_y + io->mb_w;
-        p->tmp_v = p->tmp_u + uv_width;
-        p->emit = EmitFancyRGB;
-        WebPInitUpsamplers();
-      }
-#endif
-    } else {
-      p->emit = EmitYUV;
-    }
-    if (is_alpha) {  // need transparency output
-      if (WebPIsPremultipliedMode(colorspace)) WebPInitPremultiply();
-      p->emit_alpha =
-          (colorspace == MODE_RGBA_4444 || colorspace == MODE_rgbA_4444) ?
-              EmitAlphaRGBA4444
-          : is_rgb ? EmitAlphaRGB
-          : EmitAlphaYUV;
-    }
-  }
-
-  if (is_rgb) {
-    VP8YUVInit();
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-
-static int CustomPut(const VP8Io* io) {
-  WebPDecParams* const p = (WebPDecParams*)io->opaque;
-  const int mb_w = io->mb_w;
-  const int mb_h = io->mb_h;
-  int num_lines_out;
-  assert(!(io->mb_y & 1));
-
-  if (mb_w <= 0 || mb_h <= 0) {
-    return 0;
-  }
-  num_lines_out = p->emit(io, p);
-  if (p->emit_alpha) {
-    p->emit_alpha(io, p);
-  }
-  p->last_y += num_lines_out;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-
-static void CustomTeardown(const VP8Io* io) {
-  WebPDecParams* const p = (WebPDecParams*)io->opaque;
-  free(p->memory);
-  p->memory = NULL;
-}
-
-//------------------------------------------------------------------------------
-// Main entry point
-
-void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io) {
-  io->put      = CustomPut;
-  io->setup    = CustomSetup;
-  io->teardown = CustomTeardown;
-  io->opaque   = params;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 35
drivers/webpold/dec/layer.c

@@ -1,35 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Enhancement layer (for YUV444/422)
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "./vp8i.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-
-int VP8DecodeLayer(VP8Decoder* const dec) {
-  assert(dec);
-  assert(dec->layer_data_size_ > 0);
-  (void)dec;
-
-  // TODO: handle enhancement layer here.
-
-  return 1;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 113
drivers/webpold/dec/quant.c

@@ -1,113 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Quantizer initialization
-//
-// Author: Skal ([email protected])
-
-#include "./vp8i.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-static WEBP_INLINE int clip(int v, int M) {
-  return v < 0 ? 0 : v > M ? M : v;
-}
-
-// Paragraph 14.1
-static const uint8_t kDcTable[128] = {
-  4,     5,   6,   7,   8,   9,  10,  10,
-  11,   12,  13,  14,  15,  16,  17,  17,
-  18,   19,  20,  20,  21,  21,  22,  22,
-  23,   23,  24,  25,  25,  26,  27,  28,
-  29,   30,  31,  32,  33,  34,  35,  36,
-  37,   37,  38,  39,  40,  41,  42,  43,
-  44,   45,  46,  46,  47,  48,  49,  50,
-  51,   52,  53,  54,  55,  56,  57,  58,
-  59,   60,  61,  62,  63,  64,  65,  66,
-  67,   68,  69,  70,  71,  72,  73,  74,
-  75,   76,  76,  77,  78,  79,  80,  81,
-  82,   83,  84,  85,  86,  87,  88,  89,
-  91,   93,  95,  96,  98, 100, 101, 102,
-  104, 106, 108, 110, 112, 114, 116, 118,
-  122, 124, 126, 128, 130, 132, 134, 136,
-  138, 140, 143, 145, 148, 151, 154, 157
-};
-
-static const uint16_t kAcTable[128] = {
-  4,     5,   6,   7,   8,   9,  10,  11,
-  12,   13,  14,  15,  16,  17,  18,  19,
-  20,   21,  22,  23,  24,  25,  26,  27,
-  28,   29,  30,  31,  32,  33,  34,  35,
-  36,   37,  38,  39,  40,  41,  42,  43,
-  44,   45,  46,  47,  48,  49,  50,  51,
-  52,   53,  54,  55,  56,  57,  58,  60,
-  62,   64,  66,  68,  70,  72,  74,  76,
-  78,   80,  82,  84,  86,  88,  90,  92,
-  94,   96,  98, 100, 102, 104, 106, 108,
-  110, 112, 114, 116, 119, 122, 125, 128,
-  131, 134, 137, 140, 143, 146, 149, 152,
-  155, 158, 161, 164, 167, 170, 173, 177,
-  181, 185, 189, 193, 197, 201, 205, 209,
-  213, 217, 221, 225, 229, 234, 239, 245,
-  249, 254, 259, 264, 269, 274, 279, 284
-};
-
-//------------------------------------------------------------------------------
-// Paragraph 9.6
-
-void VP8ParseQuant(VP8Decoder* const dec) {
-  VP8BitReader* const br = &dec->br_;
-  const int base_q0 = VP8GetValue(br, 7);
-  const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-  const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
-
-  const VP8SegmentHeader* const hdr = &dec->segment_hdr_;
-  int i;
-
-  for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
-    int q;
-    if (hdr->use_segment_) {
-      q = hdr->quantizer_[i];
-      if (!hdr->absolute_delta_) {
-        q += base_q0;
-      }
-    } else {
-      if (i > 0) {
-        dec->dqm_[i] = dec->dqm_[0];
-        continue;
-      } else {
-        q = base_q0;
-      }
-    }
-    {
-      VP8QuantMatrix* const m = &dec->dqm_[i];
-      m->y1_mat_[0] = kDcTable[clip(q + dqy1_dc, 127)];
-      m->y1_mat_[1] = kAcTable[clip(q + 0,       127)];
-
-      m->y2_mat_[0] = kDcTable[clip(q + dqy2_dc, 127)] * 2;
-      // For all x in [0..284], x*155/100 is bitwise equal to (x*101581) >> 16.
-      // The smallest precision for that is '(x*6349) >> 12' but 16 is a good
-      // word size.
-      m->y2_mat_[1] = (kAcTable[clip(q + dqy2_ac, 127)] * 101581) >> 16;
-      if (m->y2_mat_[1] < 8) m->y2_mat_[1] = 8;
-
-      m->uv_mat_[0] = kDcTable[clip(q + dquv_dc, 117)];
-      m->uv_mat_[1] = kAcTable[clip(q + dquv_ac, 127)];
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 589
drivers/webpold/dec/tree.c

@@ -1,589 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Coding trees and probas
-//
-// Author: Skal ([email protected])
-
-#include "vp8i.h"
-
-#define USE_GENERIC_TREE
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#ifdef USE_GENERIC_TREE
-static const int8_t kYModesIntra4[18] = {
-  -B_DC_PRED, 1,
-    -B_TM_PRED, 2,
-      -B_VE_PRED, 3,
-        4, 6,
-          -B_HE_PRED, 5,
-            -B_RD_PRED, -B_VR_PRED,
-        -B_LD_PRED, 7,
-          -B_VL_PRED, 8,
-            -B_HD_PRED, -B_HU_PRED
-};
-#endif
-
-#ifndef ONLY_KEYFRAME_CODE
-
-// inter prediction modes
-enum {
-  LEFT4 = 0, ABOVE4 = 1, ZERO4 = 2, NEW4 = 3,
-  NEARESTMV, NEARMV, ZEROMV, NEWMV, SPLITMV };
-
-static const int8_t kYModesInter[8] = {
-  -DC_PRED, 1,
-    2, 3,
-      -V_PRED, -H_PRED,
-      -TM_PRED, -B_PRED
-};
-
-static const int8_t kMBSplit[6] = {
-  -3, 1,
-    -2, 2,
-      -0, -1
-};
-
-static const int8_t kMVRef[8] = {
-  -ZEROMV, 1,
-    -NEARESTMV, 2,
-      -NEARMV, 3,
-        -NEWMV, -SPLITMV
-};
-
-static const int8_t kMVRef4[6] = {
-  -LEFT4, 1,
-    -ABOVE4, 2,
-      -ZERO4, -NEW4
-};
-#endif
-
-//------------------------------------------------------------------------------
-// Default probabilities
-
-// Inter
-#ifndef ONLY_KEYFRAME_CODE
-static const uint8_t kYModeProbaInter0[4] = { 112, 86, 140, 37 };
-static const uint8_t kUVModeProbaInter0[3] = { 162, 101, 204 };
-static const uint8_t kMVProba0[2][NUM_MV_PROBAS] = {
-  { 162, 128, 225, 146, 172, 147, 214,  39,
-    156, 128, 129, 132,  75, 145, 178, 206,
-    239, 254, 254 },
-  { 164, 128, 204, 170, 119, 235, 140, 230,
-    228, 128, 130, 130,  74, 148, 180, 203,
-    236, 254, 254 }
-};
-#endif
-
-// Paragraph 13.5
-static const uint8_t
-  CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
-  // genereated using vp8_default_coef_probs() in entropy.c:129
-  { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 },
-      { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 },
-      { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 },
-      { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 },
-      { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 },
-    },
-    { { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 },
-      { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 },
-      { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 },
-    },
-    { { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 },
-      { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 },
-      { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 },
-      { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 },
-      { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 },
-      { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 },
-      { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
-    }
-  },
-  { { { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 },
-      { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 },
-      { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 }
-    },
-    { { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 },
-      { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 },
-      { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 }
-    },
-    { { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 },
-      { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 },
-      { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 }
-    },
-    { { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 },
-      { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 },
-      { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 },
-      { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 },
-      { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 }
-    },
-    { { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 },
-      { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 },
-      { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 }
-    },
-    { { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 },
-      { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 },
-      { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 }
-    },
-    { { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 },
-      { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 }
-    }
-  },
-  { { { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 },
-      { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 },
-      { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 }
-    },
-    { { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 },
-      { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 },
-      { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 },
-      { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 },
-      { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 }
-    },
-    { { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 },
-      { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 },
-      { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
-    }
-  },
-  { { { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 },
-      { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 },
-      { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 }
-    },
-    { { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 },
-      { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 },
-      { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 }
-    },
-    { { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 },
-      { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 },
-      { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 }
-    },
-    { { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 },
-      { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 },
-      { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 }
-    },
-    { { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 },
-      { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 },
-      { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 }
-    },
-    { { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 },
-      { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 },
-      { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 },
-      { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 },
-      { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 }
-    },
-    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    }
-  }
-};
-
-// Paragraph 11.5
-static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = {
-  { { 231, 120, 48, 89, 115, 113, 120, 152, 112 },
-    { 152, 179, 64, 126, 170, 118, 46, 70, 95 },
-    { 175, 69, 143, 80, 85, 82, 72, 155, 103 },
-    { 56, 58, 10, 171, 218, 189, 17, 13, 152 },
-    { 114, 26, 17, 163, 44, 195, 21, 10, 173 },
-    { 121, 24, 80, 195, 26, 62, 44, 64, 85 },
-    { 144, 71, 10, 38, 171, 213, 144, 34, 26 },
-    { 170, 46, 55, 19, 136, 160, 33, 206, 71 },
-    { 63, 20, 8, 114, 114, 208, 12, 9, 226 },
-    { 81, 40, 11, 96, 182, 84, 29, 16, 36 } },
-  { { 134, 183, 89, 137, 98, 101, 106, 165, 148 },
-    { 72, 187, 100, 130, 157, 111, 32, 75, 80 },
-    { 66, 102, 167, 99, 74, 62, 40, 234, 128 },
-    { 41, 53, 9, 178, 241, 141, 26, 8, 107 },
-    { 74, 43, 26, 146, 73, 166, 49, 23, 157 },
-    { 65, 38, 105, 160, 51, 52, 31, 115, 128 },
-    { 104, 79, 12, 27, 217, 255, 87, 17, 7 },
-    { 87, 68, 71, 44, 114, 51, 15, 186, 23 },
-    { 47, 41, 14, 110, 182, 183, 21, 17, 194 },
-    { 66, 45, 25, 102, 197, 189, 23, 18, 22 } },
-  { { 88, 88, 147, 150, 42, 46, 45, 196, 205 },
-    { 43, 97, 183, 117, 85, 38, 35, 179, 61 },
-    { 39, 53, 200, 87, 26, 21, 43, 232, 171 },
-    { 56, 34, 51, 104, 114, 102, 29, 93, 77 },
-    { 39, 28, 85, 171, 58, 165, 90, 98, 64 },
-    { 34, 22, 116, 206, 23, 34, 43, 166, 73 },
-    { 107, 54, 32, 26, 51, 1, 81, 43, 31 },
-    { 68, 25, 106, 22, 64, 171, 36, 225, 114 },
-    { 34, 19, 21, 102, 132, 188, 16, 76, 124 },
-    { 62, 18, 78, 95, 85, 57, 50, 48, 51 } },
-  { { 193, 101, 35, 159, 215, 111, 89, 46, 111 },
-    { 60, 148, 31, 172, 219, 228, 21, 18, 111 },
-    { 112, 113, 77, 85, 179, 255, 38, 120, 114 },
-    { 40, 42, 1, 196, 245, 209, 10, 25, 109 },
-    { 88, 43, 29, 140, 166, 213, 37, 43, 154 },
-    { 61, 63, 30, 155, 67, 45, 68, 1, 209 },
-    { 100, 80, 8, 43, 154, 1, 51, 26, 71 },
-    { 142, 78, 78, 16, 255, 128, 34, 197, 171 },
-    { 41, 40, 5, 102, 211, 183, 4, 1, 221 },
-    { 51, 50, 17, 168, 209, 192, 23, 25, 82 } },
-  { { 138, 31, 36, 171, 27, 166, 38, 44, 229 },
-    { 67, 87, 58, 169, 82, 115, 26, 59, 179 },
-    { 63, 59, 90, 180, 59, 166, 93, 73, 154 },
-    { 40, 40, 21, 116, 143, 209, 34, 39, 175 },
-    { 47, 15, 16, 183, 34, 223, 49, 45, 183 },
-    { 46, 17, 33, 183, 6, 98, 15, 32, 183 },
-    { 57, 46, 22, 24, 128, 1, 54, 17, 37 },
-    { 65, 32, 73, 115, 28, 128, 23, 128, 205 },
-    { 40, 3, 9, 115, 51, 192, 18, 6, 223 },
-    { 87, 37, 9, 115, 59, 77, 64, 21, 47 } },
-  { { 104, 55, 44, 218, 9, 54, 53, 130, 226 },
-    { 64, 90, 70, 205, 40, 41, 23, 26, 57 },
-    { 54, 57, 112, 184, 5, 41, 38, 166, 213 },
-    { 30, 34, 26, 133, 152, 116, 10, 32, 134 },
-    { 39, 19, 53, 221, 26, 114, 32, 73, 255 },
-    { 31, 9, 65, 234, 2, 15, 1, 118, 73 },
-    { 75, 32, 12, 51, 192, 255, 160, 43, 51 },
-    { 88, 31, 35, 67, 102, 85, 55, 186, 85 },
-    { 56, 21, 23, 111, 59, 205, 45, 37, 192 },
-    { 55, 38, 70, 124, 73, 102, 1, 34, 98 } },
-  { { 125, 98, 42, 88, 104, 85, 117, 175, 82 },
-    { 95, 84, 53, 89, 128, 100, 113, 101, 45 },
-    { 75, 79, 123, 47, 51, 128, 81, 171, 1 },
-    { 57, 17, 5, 71, 102, 57, 53, 41, 49 },
-    { 38, 33, 13, 121, 57, 73, 26, 1, 85 },
-    { 41, 10, 67, 138, 77, 110, 90, 47, 114 },
-    { 115, 21, 2, 10, 102, 255, 166, 23, 6 },
-    { 101, 29, 16, 10, 85, 128, 101, 196, 26 },
-    { 57, 18, 10, 102, 102, 213, 34, 20, 43 },
-    { 117, 20, 15, 36, 163, 128, 68, 1, 26 } },
-  { { 102, 61, 71, 37, 34, 53, 31, 243, 192 },
-    { 69, 60, 71, 38, 73, 119, 28, 222, 37 },
-    { 68, 45, 128, 34, 1, 47, 11, 245, 171 },
-    { 62, 17, 19, 70, 146, 85, 55, 62, 70 },
-    { 37, 43, 37, 154, 100, 163, 85, 160, 1 },
-    { 63, 9, 92, 136, 28, 64, 32, 201, 85 },
-    { 75, 15, 9, 9, 64, 255, 184, 119, 16 },
-    { 86, 6, 28, 5, 64, 255, 25, 248, 1 },
-    { 56, 8, 17, 132, 137, 255, 55, 116, 128 },
-    { 58, 15, 20, 82, 135, 57, 26, 121, 40 } },
-  { { 164, 50, 31, 137, 154, 133, 25, 35, 218 },
-    { 51, 103, 44, 131, 131, 123, 31, 6, 158 },
-    { 86, 40, 64, 135, 148, 224, 45, 183, 128 },
-    { 22, 26, 17, 131, 240, 154, 14, 1, 209 },
-    { 45, 16, 21, 91, 64, 222, 7, 1, 197 },
-    { 56, 21, 39, 155, 60, 138, 23, 102, 213 },
-    { 83, 12, 13, 54, 192, 255, 68, 47, 28 },
-    { 85, 26, 85, 85, 128, 128, 32, 146, 171 },
-    { 18, 11, 7, 63, 144, 171, 4, 4, 246 },
-    { 35, 27, 10, 146, 174, 171, 12, 26, 128 } },
-  { { 190, 80, 35, 99, 180, 80, 126, 54, 45 },
-    { 85, 126, 47, 87, 176, 51, 41, 20, 32 },
-    { 101, 75, 128, 139, 118, 146, 116, 128, 85 },
-    { 56, 41, 15, 176, 236, 85, 37, 9, 62 },
-    { 71, 30, 17, 119, 118, 255, 17, 18, 138 },
-    { 101, 38, 60, 138, 55, 70, 43, 26, 142 },
-    { 146, 36, 19, 30, 171, 255, 97, 27, 20 },
-    { 138, 45, 61, 62, 219, 1, 81, 188, 64 },
-    { 32, 41, 20, 117, 151, 142, 20, 21, 163 },
-    { 112, 19, 12, 61, 195, 128, 48, 4, 24 } }
-};
-
-void VP8ResetProba(VP8Proba* const proba) {
-  memset(proba->segments_, 255u, sizeof(proba->segments_));
-  memcpy(proba->coeffs_, CoeffsProba0, sizeof(CoeffsProba0));
-#ifndef ONLY_KEYFRAME_CODE
-  memcpy(proba->mv_, kMVProba0, sizeof(kMVProba0));
-  memcpy(proba->ymode_, kYModeProbaInter0, sizeof(kYModeProbaInter0));
-  memcpy(proba->uvmode_, kUVModeProbaInter0, sizeof(kUVModeProbaInter0));
-#endif
-}
-
-void VP8ParseIntraMode(VP8BitReader* const br,  VP8Decoder* const dec) {
-  uint8_t* const top = dec->intra_t_ + 4 * dec->mb_x_;
-  uint8_t* const left = dec->intra_l_;
-  // Hardcoded 16x16 intra-mode decision tree.
-  dec->is_i4x4_ = !VP8GetBit(br, 145);   // decide for B_PRED first
-  if (!dec->is_i4x4_) {
-    const int ymode =
-        VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED)
-                           : (VP8GetBit(br, 163) ? V_PRED : DC_PRED);
-    dec->imodes_[0] = ymode;
-    memset(top, ymode, 4 * sizeof(top[0]));
-    memset(left, ymode, 4 * sizeof(left[0]));
-  } else {
-    uint8_t* modes = dec->imodes_;
-    int y;
-    for (y = 0; y < 4; ++y) {
-      int ymode = left[y];
-      int x;
-      for (x = 0; x < 4; ++x) {
-        const uint8_t* const prob = kBModesProba[top[x]][ymode];
-#ifdef USE_GENERIC_TREE
-        // Generic tree-parsing
-        int i = 0;
-        do {
-          i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])];
-        } while (i > 0);
-        ymode = -i;
-#else
-        // Hardcoded tree parsing
-        ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED :
-                  !VP8GetBit(br, prob[1]) ? B_TM_PRED :
-                    !VP8GetBit(br, prob[2]) ? B_VE_PRED :
-                      !VP8GetBit(br, prob[3]) ?
-                        (!VP8GetBit(br, prob[4]) ? B_HE_PRED :
-                          (!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) :
-                        (!VP8GetBit(br, prob[6]) ? B_LD_PRED :
-                          (!VP8GetBit(br, prob[7]) ? B_VL_PRED :
-                            (!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
-#endif    // USE_GENERIC_TREE
-        top[x] = ymode;
-        *modes++ = ymode;
-      }
-      left[y] = ymode;
-    }
-  }
-  // Hardcoded UVMode decision tree
-  dec->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED
-               : !VP8GetBit(br, 114) ? V_PRED
-               : VP8GetBit(br, 183) ? TM_PRED : H_PRED;
-}
-
-//------------------------------------------------------------------------------
-// Paragraph 13
-
-static const uint8_t
-    CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
-  { { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 },
-      { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  },
-  { { { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 },
-      { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 }
-    },
-    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  },
-  { { { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  },
-  { { { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 },
-      { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  }
-};
-
-#ifndef ONLY_KEYFRAME_CODE
-static const uint8_t MVUpdateProba[2][NUM_MV_PROBAS] = {
-  { 237, 246, 253, 253, 254, 254, 254, 254,
-    254, 254, 254, 254, 254, 254, 250, 250,
-    252, 254, 254 },
-  { 231, 243, 245, 253, 254, 254, 254, 254,
-    254, 254, 254, 254, 254, 254, 251, 251,
-    254, 254, 254 }
-};
-#endif
-
-// Paragraph 9.9
-void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
-  VP8Proba* const proba = &dec->proba_;
-  int t, b, c, p;
-  for (t = 0; t < NUM_TYPES; ++t) {
-    for (b = 0; b < NUM_BANDS; ++b) {
-      for (c = 0; c < NUM_CTX; ++c) {
-        for (p = 0; p < NUM_PROBAS; ++p) {
-          if (VP8GetBit(br, CoeffsUpdateProba[t][b][c][p])) {
-            proba->coeffs_[t][b][c][p] = VP8GetValue(br, 8);
-          }
-        }
-      }
-    }
-  }
-  dec->use_skip_proba_ = VP8Get(br);
-  if (dec->use_skip_proba_) {
-    dec->skip_p_ = VP8GetValue(br, 8);
-  }
-#ifndef ONLY_KEYFRAME_CODE
-  if (!dec->frm_hdr_.key_frame_) {
-    int i;
-    dec->intra_p_ = VP8GetValue(br, 8);
-    dec->last_p_ = VP8GetValue(br, 8);
-    dec->golden_p_ = VP8GetValue(br, 8);
-    if (VP8Get(br)) {   // update y-mode
-      for (i = 0; i < 4; ++i) {
-        proba->ymode_[i] = VP8GetValue(br, 8);
-      }
-    }
-    if (VP8Get(br)) {   // update uv-mode
-      for (i = 0; i < 3; ++i) {
-        proba->uvmode_[i] = VP8GetValue(br, 8);
-      }
-    }
-    // update MV
-    for (i = 0; i < 2; ++i) {
-      int k;
-      for (k = 0; k < NUM_MV_PROBAS; ++k) {
-        if (VP8GetBit(br, MVUpdateProba[i][k])) {
-          const int v = VP8GetValue(br, 7);
-          proba->mv_[i][k] = v ? v << 1 : 1;
-        }
-      }
-    }
-  }
-#endif
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 787
drivers/webpold/dec/vp8.c

@@ -1,787 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// main entry for the decoder
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-
-#include "./vp8i.h"
-#include "./vp8li.h"
-#include "./webpi.h"
-#include "../utils/bit_reader.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-
-int WebPGetDecoderVersion(void) {
-  return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION;
-}
-
-//------------------------------------------------------------------------------
-// VP8Decoder
-
-static void SetOk(VP8Decoder* const dec) {
-  dec->status_ = VP8_STATUS_OK;
-  dec->error_msg_ = "OK";
-}
-
-int VP8InitIoInternal(VP8Io* const io, int version) {
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
-    return 0;  // mismatch error
-  }
-  if (io != NULL) {
-    memset(io, 0, sizeof(*io));
-  }
-  return 1;
-}
-
-VP8Decoder* VP8New(void) {
-  VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(*dec));
-  if (dec != NULL) {
-    SetOk(dec);
-    WebPWorkerInit(&dec->worker_);
-    dec->ready_ = 0;
-    dec->num_parts_ = 1;
-  }
-  return dec;
-}
-
-VP8StatusCode VP8Status(VP8Decoder* const dec) {
-  if (!dec) return VP8_STATUS_INVALID_PARAM;
-  return dec->status_;
-}
-
-const char* VP8StatusMessage(VP8Decoder* const dec) {
-  if (dec == NULL) return "no object";
-  if (!dec->error_msg_) return "OK";
-  return dec->error_msg_;
-}
-
-void VP8Delete(VP8Decoder* const dec) {
-  if (dec != NULL) {
-    VP8Clear(dec);
-    free(dec);
-  }
-}
-
-int VP8SetError(VP8Decoder* const dec,
-                VP8StatusCode error, const char* const msg) {
-  // TODO This check would be unnecessary if alpha decompression was separated
-  // from VP8ProcessRow/FinishRow. This avoids setting 'dec->status_' to
-  // something other than VP8_STATUS_BITSTREAM_ERROR on alpha decompression
-  // failure.
-  if (dec->status_ == VP8_STATUS_OK) {
-    dec->status_ = error;
-    dec->error_msg_ = msg;
-    dec->ready_ = 0;
-  }
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-
-int VP8CheckSignature(const uint8_t* const data, size_t data_size) {
-  return (data_size >= 3 &&
-          data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a);
-}
-
-int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size,
-               int* const width, int* const height) {
-  if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) {
-    return 0;         // not enough data
-  }
-  // check signature
-  if (!VP8CheckSignature(data + 3, data_size - 3)) {
-    return 0;         // Wrong signature.
-  } else {
-    const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16);
-    const int key_frame = !(bits & 1);
-    const int w = ((data[7] << 8) | data[6]) & 0x3fff;
-    const int h = ((data[9] << 8) | data[8]) & 0x3fff;
-
-    if (!key_frame) {   // Not a keyframe.
-      return 0;
-    }
-
-    if (((bits >> 1) & 7) > 3) {
-      return 0;         // unknown profile
-    }
-    if (!((bits >> 4) & 1)) {
-      return 0;         // first frame is invisible!
-    }
-    if (((bits >> 5)) >= chunk_size) {  // partition_length
-      return 0;         // inconsistent size information.
-    }
-
-    if (width) {
-      *width = w;
-    }
-    if (height) {
-      *height = h;
-    }
-
-    return 1;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Header parsing
-
-static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
-  assert(hdr != NULL);
-  hdr->use_segment_ = 0;
-  hdr->update_map_ = 0;
-  hdr->absolute_delta_ = 1;
-  memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_));
-  memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_));
-}
-
-// Paragraph 9.3
-static int ParseSegmentHeader(VP8BitReader* br,
-                              VP8SegmentHeader* hdr, VP8Proba* proba) {
-  assert(br != NULL);
-  assert(hdr != NULL);
-  hdr->use_segment_ = VP8Get(br);
-  if (hdr->use_segment_) {
-    hdr->update_map_ = VP8Get(br);
-    if (VP8Get(br)) {   // update data
-      int s;
-      hdr->absolute_delta_ = VP8Get(br);
-      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-        hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
-      }
-      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-        hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0;
-      }
-    }
-    if (hdr->update_map_) {
-      int s;
-      for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
-        proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u;
-      }
-    }
-  } else {
-    hdr->update_map_ = 0;
-  }
-  return !br->eof_;
-}
-
-// Paragraph 9.5
-// This function returns VP8_STATUS_SUSPENDED if we don't have all the
-// necessary data in 'buf'.
-// This case is not necessarily an error (for incremental decoding).
-// Still, no bitreader is ever initialized to make it possible to read
-// unavailable memory.
-// If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA
-// is returned, and this is an unrecoverable error.
-// If the partitions were positioned ok, VP8_STATUS_OK is returned.
-static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
-                                     const uint8_t* buf, size_t size) {
-  VP8BitReader* const br = &dec->br_;
-  const uint8_t* sz = buf;
-  const uint8_t* buf_end = buf + size;
-  const uint8_t* part_start;
-  int last_part;
-  int p;
-
-  dec->num_parts_ = 1 << VP8GetValue(br, 2);
-  last_part = dec->num_parts_ - 1;
-  part_start = buf + last_part * 3;
-  if (buf_end < part_start) {
-    // we can't even read the sizes with sz[]! That's a failure.
-    return VP8_STATUS_NOT_ENOUGH_DATA;
-  }
-  for (p = 0; p < last_part; ++p) {
-    const uint32_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16);
-    const uint8_t* part_end = part_start + psize;
-    if (part_end > buf_end) part_end = buf_end;
-    VP8InitBitReader(dec->parts_ + p, part_start, part_end);
-    part_start = part_end;
-    sz += 3;
-  }
-  VP8InitBitReader(dec->parts_ + last_part, part_start, buf_end);
-  return (part_start < buf_end) ? VP8_STATUS_OK :
-           VP8_STATUS_SUSPENDED;   // Init is ok, but there's not enough data
-}
-
-// Paragraph 9.4
-static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
-  VP8FilterHeader* const hdr = &dec->filter_hdr_;
-  hdr->simple_    = VP8Get(br);
-  hdr->level_     = VP8GetValue(br, 6);
-  hdr->sharpness_ = VP8GetValue(br, 3);
-  hdr->use_lf_delta_ = VP8Get(br);
-  if (hdr->use_lf_delta_) {
-    if (VP8Get(br)) {   // update lf-delta?
-      int i;
-      for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
-        if (VP8Get(br)) {
-          hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6);
-        }
-      }
-      for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
-        if (VP8Get(br)) {
-          hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6);
-        }
-      }
-    }
-  }
-  dec->filter_type_ = (hdr->level_ == 0) ? 0 : hdr->simple_ ? 1 : 2;
-  if (dec->filter_type_ > 0) {    // precompute filter levels per segment
-    if (dec->segment_hdr_.use_segment_) {
-      int s;
-      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-        int strength = dec->segment_hdr_.filter_strength_[s];
-        if (!dec->segment_hdr_.absolute_delta_) {
-          strength += hdr->level_;
-        }
-        dec->filter_levels_[s] = strength;
-      }
-    } else {
-      dec->filter_levels_[0] = hdr->level_;
-    }
-  }
-  return !br->eof_;
-}
-
-// Topmost call
-int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
-  const uint8_t* buf;
-  size_t buf_size;
-  VP8FrameHeader* frm_hdr;
-  VP8PictureHeader* pic_hdr;
-  VP8BitReader* br;
-  VP8StatusCode status;
-  WebPHeaderStructure headers;
-
-  if (dec == NULL) {
-    return 0;
-  }
-  SetOk(dec);
-  if (io == NULL) {
-    return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
-                       "null VP8Io passed to VP8GetHeaders()");
-  }
-
-  // Process Pre-VP8 chunks.
-  headers.data = io->data;
-  headers.data_size = io->data_size;
-  status = WebPParseHeaders(&headers);
-  if (status != VP8_STATUS_OK) {
-    return VP8SetError(dec, status, "Incorrect/incomplete header.");
-  }
-  if (headers.is_lossless) {
-    return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
-                       "Unexpected lossless format encountered.");
-  }
-
-  if (dec->alpha_data_ == NULL) {
-    assert(dec->alpha_data_size_ == 0);
-    // We have NOT set alpha data yet. Set it now.
-    // (This is to ensure that dec->alpha_data_ is NOT reset to NULL if
-    // WebPParseHeaders() is called more than once, as in incremental decoding
-    // case.)
-    dec->alpha_data_ = headers.alpha_data;
-    dec->alpha_data_size_ = headers.alpha_data_size;
-  }
-
-  // Process the VP8 frame header.
-  buf = headers.data + headers.offset;
-  buf_size = headers.data_size - headers.offset;
-  assert(headers.data_size >= headers.offset);  // WebPParseHeaders' guarantee
-  if (buf_size < 4) {
-    return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
-                       "Truncated header.");
-  }
-
-  // Paragraph 9.1
-  {
-    const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16);
-    frm_hdr = &dec->frm_hdr_;
-    frm_hdr->key_frame_ = !(bits & 1);
-    frm_hdr->profile_ = (bits >> 1) & 7;
-    frm_hdr->show_ = (bits >> 4) & 1;
-    frm_hdr->partition_length_ = (bits >> 5);
-    if (frm_hdr->profile_ > 3)
-      return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
-                         "Incorrect keyframe parameters.");
-    if (!frm_hdr->show_)
-      return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
-                         "Frame not displayable.");
-    buf += 3;
-    buf_size -= 3;
-  }
-
-  pic_hdr = &dec->pic_hdr_;
-  if (frm_hdr->key_frame_) {
-    // Paragraph 9.2
-    if (buf_size < 7) {
-      return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
-                         "cannot parse picture header");
-    }
-    if (!VP8CheckSignature(buf, buf_size)) {
-      return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
-                         "Bad code word");
-    }
-    pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff;
-    pic_hdr->xscale_ = buf[4] >> 6;   // ratio: 1, 5/4 5/3 or 2
-    pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff;
-    pic_hdr->yscale_ = buf[6] >> 6;
-    buf += 7;
-    buf_size -= 7;
-
-    dec->mb_w_ = (pic_hdr->width_ + 15) >> 4;
-    dec->mb_h_ = (pic_hdr->height_ + 15) >> 4;
-    // Setup default output area (can be later modified during io->setup())
-    io->width = pic_hdr->width_;
-    io->height = pic_hdr->height_;
-    io->use_scaling  = 0;
-    io->use_cropping = 0;
-    io->crop_top  = 0;
-    io->crop_left = 0;
-    io->crop_right  = io->width;
-    io->crop_bottom = io->height;
-    io->mb_w = io->width;   // sanity check
-    io->mb_h = io->height;  // ditto
-
-    VP8ResetProba(&dec->proba_);
-    ResetSegmentHeader(&dec->segment_hdr_);
-    dec->segment_ = 0;    // default for intra
-  }
-
-  // Check if we have all the partition #0 available, and initialize dec->br_
-  // to read this partition (and this partition only).
-  if (frm_hdr->partition_length_ > buf_size) {
-    return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
-                       "bad partition length");
-  }
-
-  br = &dec->br_;
-  VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_);
-  buf += frm_hdr->partition_length_;
-  buf_size -= frm_hdr->partition_length_;
-
-  if (frm_hdr->key_frame_) {
-    pic_hdr->colorspace_ = VP8Get(br);
-    pic_hdr->clamp_type_ = VP8Get(br);
-  }
-  if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
-    return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
-                       "cannot parse segment header");
-  }
-  // Filter specs
-  if (!ParseFilterHeader(br, dec)) {
-    return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
-                       "cannot parse filter header");
-  }
-  status = ParsePartitions(dec, buf, buf_size);
-  if (status != VP8_STATUS_OK) {
-    return VP8SetError(dec, status, "cannot parse partitions");
-  }
-
-  // quantizer change
-  VP8ParseQuant(dec);
-
-  // Frame buffer marking
-  if (!frm_hdr->key_frame_) {
-    // Paragraph 9.7
-#ifndef ONLY_KEYFRAME_CODE
-    dec->buffer_flags_ = VP8Get(br) << 0;   // update golden
-    dec->buffer_flags_ |= VP8Get(br) << 1;  // update alt ref
-    if (!(dec->buffer_flags_ & 1)) {
-      dec->buffer_flags_ |= VP8GetValue(br, 2) << 2;
-    }
-    if (!(dec->buffer_flags_ & 2)) {
-      dec->buffer_flags_ |= VP8GetValue(br, 2) << 4;
-    }
-    dec->buffer_flags_ |= VP8Get(br) << 6;    // sign bias golden
-    dec->buffer_flags_ |= VP8Get(br) << 7;    // sign bias alt ref
-#else
-    return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
-                       "Not a key frame.");
-#endif
-  } else {
-    dec->buffer_flags_ = 0x003 | 0x100;
-  }
-
-  // Paragraph 9.8
-#ifndef ONLY_KEYFRAME_CODE
-  dec->update_proba_ = VP8Get(br);
-  if (!dec->update_proba_) {    // save for later restore
-    dec->proba_saved_ = dec->proba_;
-  }
-  dec->buffer_flags_ &= 1 << 8;
-  dec->buffer_flags_ |=
-      (frm_hdr->key_frame_ || VP8Get(br)) << 8;    // refresh last frame
-#else
-  VP8Get(br);   // just ignore the value of update_proba_
-#endif
-
-  VP8ParseProba(br, dec);
-
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-  // Extensions
-  if (dec->pic_hdr_.colorspace_) {
-    const size_t kTrailerSize = 8;
-    const uint8_t kTrailerMarker = 0x01;
-    const uint8_t* ext_buf = buf - kTrailerSize;
-    size_t size;
-
-    if (frm_hdr->partition_length_ < kTrailerSize ||
-        ext_buf[kTrailerSize - 1] != kTrailerMarker) {
-      return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
-                         "RIFF: Inconsistent extra information.");
-    }
-
-    // Layer
-    size = (ext_buf[0] << 0) | (ext_buf[1] << 8) | (ext_buf[2] << 16);
-    dec->layer_data_size_ = size;
-    dec->layer_data_ = NULL;  // will be set later
-    dec->layer_colorspace_ = ext_buf[3];
-  }
-#endif
-
-  // sanitized state
-  dec->ready_ = 1;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Residual decoding (Paragraph 13.2 / 13.3)
-
-static const uint8_t kBands[16 + 1] = {
-  0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
-  0  // extra entry as sentinel
-};
-
-static const uint8_t kCat3[] = { 173, 148, 140, 0 };
-static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 };
-static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 };
-static const uint8_t kCat6[] =
-  { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 };
-static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 };
-static const uint8_t kZigzag[16] = {
-  0, 1, 4, 8,  5, 2, 3, 6,  9, 12, 13, 10,  7, 11, 14, 15
-};
-
-typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS];  // for const-casting
-
-// Returns the position of the last non-zero coeff plus one
-// (and 0 if there's no coeff at all)
-static int GetCoeffs(VP8BitReader* const br, ProbaArray prob,
-                     int ctx, const quant_t dq, int n, int16_t* out) {
-  // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'.
-  const uint8_t* p = prob[n][ctx];
-  if (!VP8GetBit(br, p[0])) {   // first EOB is more a 'CBP' bit.
-    return 0;
-  }
-  while (1) {
-    ++n;
-    if (!VP8GetBit(br, p[1])) {
-      p = prob[kBands[n]][0];
-    } else {  // non zero coeff
-      int v, j;
-      if (!VP8GetBit(br, p[2])) {
-        p = prob[kBands[n]][1];
-        v = 1;
-      } else {
-        if (!VP8GetBit(br, p[3])) {
-          if (!VP8GetBit(br, p[4])) {
-            v = 2;
-          } else {
-            v = 3 + VP8GetBit(br, p[5]);
-          }
-        } else {
-          if (!VP8GetBit(br, p[6])) {
-            if (!VP8GetBit(br, p[7])) {
-              v = 5 + VP8GetBit(br, 159);
-            } else {
-              v = 7 + 2 * VP8GetBit(br, 165);
-              v += VP8GetBit(br, 145);
-            }
-          } else {
-            const uint8_t* tab;
-            const int bit1 = VP8GetBit(br, p[8]);
-            const int bit0 = VP8GetBit(br, p[9 + bit1]);
-            const int cat = 2 * bit1 + bit0;
-            v = 0;
-            for (tab = kCat3456[cat]; *tab; ++tab) {
-              v += v + VP8GetBit(br, *tab);
-            }
-            v += 3 + (8 << cat);
-          }
-        }
-        p = prob[kBands[n]][2];
-      }
-      j = kZigzag[n - 1];
-      out[j] = VP8GetSigned(br, v) * dq[j > 0];
-      if (n == 16 || !VP8GetBit(br, p[0])) {   // EOB
-        return n;
-      }
-    }
-    if (n == 16) {
-      return 16;
-    }
-  }
-}
-
-// Alias-safe way of converting 4bytes to 32bits.
-typedef union {
-  uint8_t  i8[4];
-  uint32_t i32;
-} PackedNz;
-
-// Table to unpack four bits into four bytes
-static const PackedNz kUnpackTab[16] = {
-  {{0, 0, 0, 0}},  {{1, 0, 0, 0}},  {{0, 1, 0, 0}},  {{1, 1, 0, 0}},
-  {{0, 0, 1, 0}},  {{1, 0, 1, 0}},  {{0, 1, 1, 0}},  {{1, 1, 1, 0}},
-  {{0, 0, 0, 1}},  {{1, 0, 0, 1}},  {{0, 1, 0, 1}},  {{1, 1, 0, 1}},
-  {{0, 0, 1, 1}},  {{1, 0, 1, 1}},  {{0, 1, 1, 1}},  {{1, 1, 1, 1}} };
-
-// Macro to pack four LSB of four bytes into four bits.
-#if defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || \
-    defined(__BIG_ENDIAN__)
-#define PACK_CST 0x08040201U
-#else
-#define PACK_CST 0x01020408U
-#endif
-#define PACK(X, S) ((((X).i32 * PACK_CST) & 0xff000000) >> (S))
-
-static void ParseResiduals(VP8Decoder* const dec,
-                           VP8MB* const mb, VP8BitReader* const token_br) {
-  int out_t_nz, out_l_nz, first;
-  ProbaArray ac_prob;
-  const VP8QuantMatrix* q = &dec->dqm_[dec->segment_];
-  int16_t* dst = dec->coeffs_;
-  VP8MB* const left_mb = dec->mb_info_ - 1;
-  PackedNz nz_ac, nz_dc;
-  PackedNz tnz, lnz;
-  uint32_t non_zero_ac = 0;
-  uint32_t non_zero_dc = 0;
-  int x, y, ch;
-
-  nz_dc.i32 = nz_ac.i32 = 0;
-  memset(dst, 0, 384 * sizeof(*dst));
-  if (!dec->is_i4x4_) {    // parse DC
-    int16_t dc[16] = { 0 };
-    const int ctx = mb->dc_nz_ + left_mb->dc_nz_;
-    mb->dc_nz_ = left_mb->dc_nz_ =
-        (GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[1],
-                   ctx, q->y2_mat_, 0, dc) > 0);
-    first = 1;
-    ac_prob = (ProbaArray)dec->proba_.coeffs_[0];
-    VP8TransformWHT(dc, dst);
-  } else {
-    first = 0;
-    ac_prob = (ProbaArray)dec->proba_.coeffs_[3];
-  }
-
-  tnz = kUnpackTab[mb->nz_ & 0xf];
-  lnz = kUnpackTab[left_mb->nz_ & 0xf];
-  for (y = 0; y < 4; ++y) {
-    int l = lnz.i8[y];
-    for (x = 0; x < 4; ++x) {
-      const int ctx = l + tnz.i8[x];
-      const int nz = GetCoeffs(token_br, ac_prob, ctx,
-                               q->y1_mat_, first, dst);
-      tnz.i8[x] = l = (nz > 0);
-      nz_dc.i8[x] = (dst[0] != 0);
-      nz_ac.i8[x] = (nz > 1);
-      dst += 16;
-    }
-    lnz.i8[y] = l;
-    non_zero_dc |= PACK(nz_dc, 24 - y * 4);
-    non_zero_ac |= PACK(nz_ac, 24 - y * 4);
-  }
-  out_t_nz = PACK(tnz, 24);
-  out_l_nz = PACK(lnz, 24);
-
-  tnz = kUnpackTab[mb->nz_ >> 4];
-  lnz = kUnpackTab[left_mb->nz_ >> 4];
-  for (ch = 0; ch < 4; ch += 2) {
-    for (y = 0; y < 2; ++y) {
-      int l = lnz.i8[ch + y];
-      for (x = 0; x < 2; ++x) {
-        const int ctx = l + tnz.i8[ch + x];
-        const int nz =
-            GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[2],
-                      ctx, q->uv_mat_, 0, dst);
-        tnz.i8[ch + x] = l = (nz > 0);
-        nz_dc.i8[y * 2 + x] = (dst[0] != 0);
-        nz_ac.i8[y * 2 + x] = (nz > 1);
-        dst += 16;
-      }
-      lnz.i8[ch + y] = l;
-    }
-    non_zero_dc |= PACK(nz_dc, 8 - ch * 2);
-    non_zero_ac |= PACK(nz_ac, 8 - ch * 2);
-  }
-  out_t_nz |= PACK(tnz, 20);
-  out_l_nz |= PACK(lnz, 20);
-  mb->nz_ = out_t_nz;
-  left_mb->nz_ = out_l_nz;
-
-  dec->non_zero_ac_ = non_zero_ac;
-  dec->non_zero_ = non_zero_ac | non_zero_dc;
-  mb->skip_ = !dec->non_zero_;
-}
-#undef PACK
-
-//------------------------------------------------------------------------------
-// Main loop
-
-int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) {
-  VP8BitReader* const br = &dec->br_;
-  VP8MB* const left = dec->mb_info_ - 1;
-  VP8MB* const info = dec->mb_info_ + dec->mb_x_;
-
-  // Note: we don't save segment map (yet), as we don't expect
-  // to decode more than 1 keyframe.
-  if (dec->segment_hdr_.update_map_) {
-    // Hardcoded tree parsing
-    dec->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) ?
-        VP8GetBit(br, dec->proba_.segments_[1]) :
-        2 + VP8GetBit(br, dec->proba_.segments_[2]);
-  }
-  info->skip_ = dec->use_skip_proba_ ? VP8GetBit(br, dec->skip_p_) : 0;
-
-  VP8ParseIntraMode(br, dec);
-  if (br->eof_) {
-    return 0;
-  }
-
-  if (!info->skip_) {
-    ParseResiduals(dec, info, token_br);
-  } else {
-    left->nz_ = info->nz_ = 0;
-    if (!dec->is_i4x4_) {
-      left->dc_nz_ = info->dc_nz_ = 0;
-    }
-    dec->non_zero_ = 0;
-    dec->non_zero_ac_ = 0;
-  }
-
-  return (!token_br->eof_);
-}
-
-void VP8InitScanline(VP8Decoder* const dec) {
-  VP8MB* const left = dec->mb_info_ - 1;
-  left->nz_ = 0;
-  left->dc_nz_ = 0;
-  memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_));
-  dec->filter_row_ =
-    (dec->filter_type_ > 0) &&
-    (dec->mb_y_ >= dec->tl_mb_y_) && (dec->mb_y_ <= dec->br_mb_y_);
-}
-
-static int ParseFrame(VP8Decoder* const dec, VP8Io* io) {
-  for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) {
-    VP8BitReader* const token_br =
-        &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
-    VP8InitScanline(dec);
-    for (dec->mb_x_ = 0; dec->mb_x_ < dec->mb_w_;  dec->mb_x_++) {
-      if (!VP8DecodeMB(dec, token_br)) {
-        return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
-                           "Premature end-of-file encountered.");
-      }
-      VP8ReconstructBlock(dec);
-
-      // Store data and save block's filtering params
-      VP8StoreBlock(dec);
-    }
-    if (!VP8ProcessRow(dec, io)) {
-      return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted.");
-    }
-  }
-  if (dec->use_threads_ && !WebPWorkerSync(&dec->worker_)) {
-    return 0;
-  }
-
-  // Finish
-#ifndef ONLY_KEYFRAME_CODE
-  if (!dec->update_proba_) {
-    dec->proba_ = dec->proba_saved_;
-  }
-#endif
-
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-  if (dec->layer_data_size_ > 0) {
-    if (!VP8DecodeLayer(dec)) {
-      return 0;
-    }
-  }
-#endif
-
-  return 1;
-}
-
-// Main entry point
-int VP8Decode(VP8Decoder* const dec, VP8Io* const io) {
-  int ok = 0;
-  if (dec == NULL) {
-    return 0;
-  }
-  if (io == NULL) {
-    return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
-                       "NULL VP8Io parameter in VP8Decode().");
-  }
-
-  if (!dec->ready_) {
-    if (!VP8GetHeaders(dec, io)) {
-      return 0;
-    }
-  }
-  assert(dec->ready_);
-
-  // Finish setting up the decoding parameter. Will call io->setup().
-  ok = (VP8EnterCritical(dec, io) == VP8_STATUS_OK);
-  if (ok) {   // good to go.
-    // Will allocate memory and prepare everything.
-    if (ok) ok = VP8InitFrame(dec, io);
-
-    // Main decoding loop
-    if (ok) ok = ParseFrame(dec, io);
-
-    // Exit.
-    ok &= VP8ExitCritical(dec, io);
-  }
-
-  if (!ok) {
-    VP8Clear(dec);
-    return 0;
-  }
-
-  dec->ready_ = 0;
-  return ok;
-}
-
-void VP8Clear(VP8Decoder* const dec) {
-  if (dec == NULL) {
-    return;
-  }
-  if (dec->use_threads_) {
-    WebPWorkerEnd(&dec->worker_);
-  }
-  if (dec->mem_) {
-    free(dec->mem_);
-  }
-  dec->mem_ = NULL;
-  dec->mem_size_ = 0;
-  memset(&dec->br_, 0, sizeof(dec->br_));
-  dec->ready_ = 0;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 335
drivers/webpold/dec/vp8i.h

@@ -1,335 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// VP8 decoder: internal header.
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_DEC_VP8I_H_
-#define WEBP_DEC_VP8I_H_
-
-#include <string.h>     // for memcpy()
-#include "./vp8li.h"
-#include "../utils/bit_reader.h"
-#include "../utils/thread.h"
-#include "../dsp/dsp.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Various defines and enums
-
-// version numbers
-#define DEC_MAJ_VERSION 0
-#define DEC_MIN_VERSION 2
-#define DEC_REV_VERSION 0
-
-#define ONLY_KEYFRAME_CODE      // to remove any code related to P-Frames
-
-// intra prediction modes
-enum { B_DC_PRED = 0,   // 4x4 modes
-       B_TM_PRED,
-       B_VE_PRED,
-       B_HE_PRED,
-       B_RD_PRED,
-       B_VR_PRED,
-       B_LD_PRED,
-       B_VL_PRED,
-       B_HD_PRED,
-       B_HU_PRED,
-       NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED,  // = 10
-
-       // Luma16 or UV modes
-       DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED,
-       H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED,
-       B_PRED = NUM_BMODES,   // refined I4x4 mode
-
-       // special modes
-       B_DC_PRED_NOTOP = 4,
-       B_DC_PRED_NOLEFT = 5,
-       B_DC_PRED_NOTOPLEFT = 6,
-       NUM_B_DC_MODES = 7 };
-
-enum { MB_FEATURE_TREE_PROBS = 3,
-       NUM_MB_SEGMENTS = 4,
-       NUM_REF_LF_DELTAS = 4,
-       NUM_MODE_LF_DELTAS = 4,    // I4x4, ZERO, *, SPLIT
-       MAX_NUM_PARTITIONS = 8,
-       // Probabilities
-       NUM_TYPES = 4,
-       NUM_BANDS = 8,
-       NUM_CTX = 3,
-       NUM_PROBAS = 11,
-       NUM_MV_PROBAS = 19 };
-
-// YUV-cache parameters.
-// Constraints are: We need to store one 16x16 block of luma samples (y),
-// and two 8x8 chroma blocks (u/v). These are better be 16-bytes aligned,
-// in order to be SIMD-friendly. We also need to store the top, left and
-// top-left samples (from previously decoded blocks), along with four
-// extra top-right samples for luma (intra4x4 prediction only).
-// One possible layout is, using 32 * (17 + 9) bytes:
-//
-//   .+------   <- only 1 pixel high
-//   .|yyyyt.
-//   .|yyyyt.
-//   .|yyyyt.
-//   .|yyyy..
-//   .+--.+--   <- only 1 pixel high
-//   .|uu.|vv
-//   .|uu.|vv
-//
-// Every character is a 4x4 block, with legend:
-//  '.' = unused
-//  'y' = y-samples   'u' = u-samples     'v' = u-samples
-//  '|' = left sample,   '-' = top sample,    '+' = top-left sample
-//  't' = extra top-right sample for 4x4 modes
-// With this layout, BPS (=Bytes Per Scan-line) is one cacheline size.
-#define BPS       32    // this is the common stride used by yuv[]
-#define YUV_SIZE (BPS * 17 + BPS * 9)
-#define Y_SIZE   (BPS * 17)
-#define Y_OFF    (BPS * 1 + 8)
-#define U_OFF    (Y_OFF + BPS * 16 + BPS)
-#define V_OFF    (U_OFF + 16)
-
-//------------------------------------------------------------------------------
-// Headers
-
-typedef struct {
-  uint8_t key_frame_;
-  uint8_t profile_;
-  uint8_t show_;
-  uint32_t partition_length_;
-} VP8FrameHeader;
-
-typedef struct {
-  uint16_t width_;
-  uint16_t height_;
-  uint8_t xscale_;
-  uint8_t yscale_;
-  uint8_t colorspace_;   // 0 = YCbCr
-  uint8_t clamp_type_;
-} VP8PictureHeader;
-
-// segment features
-typedef struct {
-  int use_segment_;
-  int update_map_;        // whether to update the segment map or not
-  int absolute_delta_;    // absolute or delta values for quantizer and filter
-  int8_t quantizer_[NUM_MB_SEGMENTS];        // quantization changes
-  int8_t filter_strength_[NUM_MB_SEGMENTS];  // filter strength for segments
-} VP8SegmentHeader;
-
-// Struct collecting all frame-persistent probabilities.
-typedef struct {
-  uint8_t segments_[MB_FEATURE_TREE_PROBS];
-  // Type: 0:Intra16-AC  1:Intra16-DC   2:Chroma   3:Intra4
-  uint8_t coeffs_[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
-#ifndef ONLY_KEYFRAME_CODE
-  uint8_t ymode_[4], uvmode_[3];
-  uint8_t mv_[2][NUM_MV_PROBAS];
-#endif
-} VP8Proba;
-
-// Filter parameters
-typedef struct {
-  int simple_;                  // 0=complex, 1=simple
-  int level_;                   // [0..63]
-  int sharpness_;               // [0..7]
-  int use_lf_delta_;
-  int ref_lf_delta_[NUM_REF_LF_DELTAS];
-  int mode_lf_delta_[NUM_MODE_LF_DELTAS];
-} VP8FilterHeader;
-
-//------------------------------------------------------------------------------
-// Informations about the macroblocks.
-
-typedef struct {  // filter specs
-  unsigned int f_level_:6;      // filter strength: 0..63
-  unsigned int f_ilevel_:6;     // inner limit: 1..63
-  unsigned int f_inner_:1;      // do inner filtering?
-} VP8FInfo;
-
-typedef struct {  // used for syntax-parsing
-  unsigned int nz_;          // non-zero AC/DC coeffs
-  unsigned int dc_nz_:1;     // non-zero DC coeffs
-  unsigned int skip_:1;      // block type
-} VP8MB;
-
-// Dequantization matrices
-typedef int quant_t[2];      // [DC / AC].  Can be 'uint16_t[2]' too (~slower).
-typedef struct {
-  quant_t y1_mat_, y2_mat_, uv_mat_;
-} VP8QuantMatrix;
-
-// Persistent information needed by the parallel processing
-typedef struct {
-  int id_;            // cache row to process (in [0..2])
-  int mb_y_;          // macroblock position of the row
-  int filter_row_;    // true if row-filtering is needed
-  VP8FInfo* f_info_;  // filter strengths
-  VP8Io io_;          // copy of the VP8Io to pass to put()
-} VP8ThreadContext;
-
-//------------------------------------------------------------------------------
-// VP8Decoder: the main opaque structure handed over to user
-
-struct VP8Decoder {
-  VP8StatusCode status_;
-  int ready_;     // true if ready to decode a picture with VP8Decode()
-  const char* error_msg_;  // set when status_ is not OK.
-
-  // Main data source
-  VP8BitReader br_;
-
-  // headers
-  VP8FrameHeader   frm_hdr_;
-  VP8PictureHeader pic_hdr_;
-  VP8FilterHeader  filter_hdr_;
-  VP8SegmentHeader segment_hdr_;
-
-  // Worker
-  WebPWorker worker_;
-  int use_threads_;    // use multi-thread
-  int cache_id_;       // current cache row
-  int num_caches_;     // number of cached rows of 16 pixels (1, 2 or 3)
-  VP8ThreadContext thread_ctx_;  // Thread context
-
-  // dimension, in macroblock units.
-  int mb_w_, mb_h_;
-
-  // Macroblock to process/filter, depending on cropping and filter_type.
-  int tl_mb_x_, tl_mb_y_;  // top-left MB that must be in-loop filtered
-  int br_mb_x_, br_mb_y_;  // last bottom-right MB that must be decoded
-
-  // number of partitions.
-  int num_parts_;
-  // per-partition boolean decoders.
-  VP8BitReader parts_[MAX_NUM_PARTITIONS];
-
-  // buffer refresh flags
-  //   bit 0: refresh Gold, bit 1: refresh Alt
-  //   bit 2-3: copy to Gold, bit 4-5: copy to Alt
-  //   bit 6: Gold sign bias, bit 7: Alt sign bias
-  //   bit 8: refresh last frame
-  uint32_t buffer_flags_;
-
-  // dequantization (one set of DC/AC dequant factor per segment)
-  VP8QuantMatrix dqm_[NUM_MB_SEGMENTS];
-
-  // probabilities
-  VP8Proba proba_;
-  int use_skip_proba_;
-  uint8_t skip_p_;
-#ifndef ONLY_KEYFRAME_CODE
-  uint8_t intra_p_, last_p_, golden_p_;
-  VP8Proba proba_saved_;
-  int update_proba_;
-#endif
-
-  // Boundary data cache and persistent buffers.
-  uint8_t* intra_t_;     // top intra modes values: 4 * mb_w_
-  uint8_t  intra_l_[4];  // left intra modes values
-  uint8_t* y_t_;         // top luma samples: 16 * mb_w_
-  uint8_t* u_t_, *v_t_;  // top u/v samples: 8 * mb_w_ each
-
-  VP8MB* mb_info_;       // contextual macroblock info (mb_w_ + 1)
-  VP8FInfo* f_info_;     // filter strength info
-  uint8_t* yuv_b_;       // main block for Y/U/V (size = YUV_SIZE)
-  int16_t* coeffs_;      // 384 coeffs = (16+8+8) * 4*4
-
-  uint8_t* cache_y_;     // macroblock row for storing unfiltered samples
-  uint8_t* cache_u_;
-  uint8_t* cache_v_;
-  int cache_y_stride_;
-  int cache_uv_stride_;
-
-  // main memory chunk for the above data. Persistent.
-  void* mem_;
-  size_t mem_size_;
-
-  // Per macroblock non-persistent infos.
-  int mb_x_, mb_y_;       // current position, in macroblock units
-  uint8_t is_i4x4_;       // true if intra4x4
-  uint8_t imodes_[16];    // one 16x16 mode (#0) or sixteen 4x4 modes
-  uint8_t uvmode_;        // chroma prediction mode
-  uint8_t segment_;       // block's segment
-
-  // bit-wise info about the content of each sub-4x4 blocks: there are 16 bits
-  // for luma (bits #0->#15), then 4 bits for chroma-u (#16->#19) and 4 bits for
-  // chroma-v (#20->#23), each corresponding to one 4x4 block in decoding order.
-  // If the bit is set, the 4x4 block contains some non-zero coefficients.
-  uint32_t non_zero_;
-  uint32_t non_zero_ac_;
-
-  // Filtering side-info
-  int filter_type_;                         // 0=off, 1=simple, 2=complex
-  int filter_row_;                          // per-row flag
-  uint8_t filter_levels_[NUM_MB_SEGMENTS];  // precalculated per-segment
-
-  // extensions
-  const uint8_t* alpha_data_;   // compressed alpha data (if present)
-  size_t alpha_data_size_;
-  uint8_t* alpha_plane_;        // output. Persistent, contains the whole data.
-
-  int layer_colorspace_;
-  const uint8_t* layer_data_;   // compressed layer data (if present)
-  size_t layer_data_size_;
-};
-
-//------------------------------------------------------------------------------
-// internal functions. Not public.
-
-// in vp8.c
-int VP8SetError(VP8Decoder* const dec,
-                VP8StatusCode error, const char* const msg);
-
-// in tree.c
-void VP8ResetProba(VP8Proba* const proba);
-void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec);
-void VP8ParseIntraMode(VP8BitReader* const br,  VP8Decoder* const dec);
-
-// in quant.c
-void VP8ParseQuant(VP8Decoder* const dec);
-
-// in frame.c
-int VP8InitFrame(VP8Decoder* const dec, VP8Io* io);
-// Predict a block and add residual
-void VP8ReconstructBlock(VP8Decoder* const dec);
-// Call io->setup() and finish setting up scan parameters.
-// After this call returns, one must always call VP8ExitCritical() with the
-// same parameters. Both functions should be used in pair. Returns VP8_STATUS_OK
-// if ok, otherwise sets and returns the error status on *dec.
-VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io);
-// Must always be called in pair with VP8EnterCritical().
-// Returns false in case of error.
-int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io);
-// Process the last decoded row (filtering + output)
-int VP8ProcessRow(VP8Decoder* const dec, VP8Io* const io);
-// Store a block, along with filtering params
-void VP8StoreBlock(VP8Decoder* const dec);
-// To be called at the start of a new scanline, to initialize predictors.
-void VP8InitScanline(VP8Decoder* const dec);
-// Decode one macroblock. Returns false if there is not enough data.
-int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br);
-
-// in alpha.c
-const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
-                                      int row, int num_rows);
-
-// in layer.c
-int VP8DecodeLayer(VP8Decoder* const dec);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_DEC_VP8I_H_ */

+ 0 - 1200
drivers/webpold/dec/vp8l.c

@@ -1,1200 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// main entry for the decoder
-//
-// Authors: Vikas Arora ([email protected])
-//          Jyrki Alakuijala ([email protected])
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "./vp8li.h"
-#include "../dsp/lossless.h"
-#include "../dsp/yuv.h"
-#include "../utils/huffman.h"
-#include "../utils/utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define NUM_ARGB_CACHE_ROWS          16
-
-static const int kCodeLengthLiterals = 16;
-static const int kCodeLengthRepeatCode = 16;
-static const int kCodeLengthExtraBits[3] = { 2, 3, 7 };
-static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
-
-// -----------------------------------------------------------------------------
-//  Five Huffman codes are used at each meta code:
-//  1. green + length prefix codes + color cache codes,
-//  2. alpha,
-//  3. red,
-//  4. blue, and,
-//  5. distance prefix codes.
-typedef enum {
-  GREEN = 0,
-  RED   = 1,
-  BLUE  = 2,
-  ALPHA = 3,
-  DIST  = 4
-} HuffIndex;
-
-static const uint16_t kAlphabetSize[HUFFMAN_CODES_PER_META_CODE] = {
-  NUM_LITERAL_CODES + NUM_LENGTH_CODES,
-  NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
-  NUM_DISTANCE_CODES
-};
-
-
-#define NUM_CODE_LENGTH_CODES       19
-static const uint8_t kCodeLengthCodeOrder[NUM_CODE_LENGTH_CODES] = {
-  17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-#define CODE_TO_PLANE_CODES        120
-static const uint8_t code_to_plane_lut[CODE_TO_PLANE_CODES] = {
-   0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a,
-   0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a,
-   0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b,
-   0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03,
-   0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c,
-   0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e,
-   0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b,
-   0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f,
-   0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b,
-   0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41,
-   0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f,
-   0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70
-};
-
-static int DecodeImageStream(int xsize, int ysize,
-                             int is_level0,
-                             VP8LDecoder* const dec,
-                             uint32_t** const decoded_data);
-
-//------------------------------------------------------------------------------
-
-int VP8LCheckSignature(const uint8_t* const data, size_t size) {
-  return (size >= 1) && (data[0] == VP8L_MAGIC_BYTE);
-}
-
-static int ReadImageInfo(VP8LBitReader* const br,
-                         int* const width, int* const height,
-                         int* const has_alpha) {
-  const uint8_t signature = VP8LReadBits(br, 8);
-  if (!VP8LCheckSignature(&signature, 1)) {
-    return 0;
-  }
-  *width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
-  *height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
-  *has_alpha = VP8LReadBits(br, 1);
-  VP8LReadBits(br, VP8L_VERSION_BITS);  // Read/ignore the version number.
-  return 1;
-}
-
-int VP8LGetInfo(const uint8_t* data, size_t data_size,
-                int* const width, int* const height, int* const has_alpha) {
-  if (data == NULL || data_size < VP8L_FRAME_HEADER_SIZE) {
-    return 0;         // not enough data
-  } else {
-    int w, h, a;
-    VP8LBitReader br;
-    VP8LInitBitReader(&br, data, data_size);
-    if (!ReadImageInfo(&br, &w, &h, &a)) {
-      return 0;
-    }
-    if (width != NULL) *width = w;
-    if (height != NULL) *height = h;
-    if (has_alpha != NULL) *has_alpha = a;
-    return 1;
-  }
-}
-
-//------------------------------------------------------------------------------
-
-static WEBP_INLINE int GetCopyDistance(int distance_symbol,
-                                       VP8LBitReader* const br) {
-  int extra_bits, offset;
-  if (distance_symbol < 4) {
-    return distance_symbol + 1;
-  }
-  extra_bits = (distance_symbol - 2) >> 1;
-  offset = (2 + (distance_symbol & 1)) << extra_bits;
-  return offset + VP8LReadBits(br, extra_bits) + 1;
-}
-
-static WEBP_INLINE int GetCopyLength(int length_symbol,
-                                     VP8LBitReader* const br) {
-  // Length and distance prefixes are encoded the same way.
-  return GetCopyDistance(length_symbol, br);
-}
-
-static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) {
-  if (plane_code > CODE_TO_PLANE_CODES) {
-    return plane_code - CODE_TO_PLANE_CODES;
-  } else {
-    const int dist_code = code_to_plane_lut[plane_code - 1];
-    const int yoffset = dist_code >> 4;
-    const int xoffset = 8 - (dist_code & 0xf);
-    const int dist = yoffset * xsize + xoffset;
-    return (dist >= 1) ? dist : 1;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Decodes the next Huffman code from bit-stream.
-// FillBitWindow(br) needs to be called at minimum every second call
-// to ReadSymbolUnsafe.
-static int ReadSymbolUnsafe(const HuffmanTree* tree, VP8LBitReader* const br) {
-  const HuffmanTreeNode* node = tree->root_;
-  assert(node != NULL);
-  while (!HuffmanTreeNodeIsLeaf(node)) {
-    node = HuffmanTreeNextNode(node, VP8LReadOneBitUnsafe(br));
-  }
-  return node->symbol_;
-}
-
-static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree,
-                                  VP8LBitReader* const br) {
-  const int read_safe = (br->pos_ + 8 > br->len_);
-  if (!read_safe) {
-    return ReadSymbolUnsafe(tree, br);
-  } else {
-    const HuffmanTreeNode* node = tree->root_;
-    assert(node != NULL);
-    while (!HuffmanTreeNodeIsLeaf(node)) {
-      node = HuffmanTreeNextNode(node, VP8LReadOneBit(br));
-    }
-    return node->symbol_;
-  }
-}
-
-static int ReadHuffmanCodeLengths(
-    VP8LDecoder* const dec, const int* const code_length_code_lengths,
-    int num_symbols, int* const code_lengths) {
-  int ok = 0;
-  VP8LBitReader* const br = &dec->br_;
-  int symbol;
-  int max_symbol;
-  int prev_code_len = DEFAULT_CODE_LENGTH;
-  HuffmanTree tree;
-
-  if (!HuffmanTreeBuildImplicit(&tree, code_length_code_lengths,
-                                NUM_CODE_LENGTH_CODES)) {
-    dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-    return 0;
-  }
-
-  if (VP8LReadBits(br, 1)) {    // use length
-    const int length_nbits = 2 + 2 * VP8LReadBits(br, 3);
-    max_symbol = 2 + VP8LReadBits(br, length_nbits);
-    if (max_symbol > num_symbols) {
-      dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-      goto End;
-    }
-  } else {
-    max_symbol = num_symbols;
-  }
-
-  symbol = 0;
-  while (symbol < num_symbols) {
-    int code_len;
-    if (max_symbol-- == 0) break;
-    VP8LFillBitWindow(br);
-    code_len = ReadSymbol(&tree, br);
-    if (code_len < kCodeLengthLiterals) {
-      code_lengths[symbol++] = code_len;
-      if (code_len != 0) prev_code_len = code_len;
-    } else {
-      const int use_prev = (code_len == kCodeLengthRepeatCode);
-      const int slot = code_len - kCodeLengthLiterals;
-      const int extra_bits = kCodeLengthExtraBits[slot];
-      const int repeat_offset = kCodeLengthRepeatOffsets[slot];
-      int repeat = VP8LReadBits(br, extra_bits) + repeat_offset;
-      if (symbol + repeat > num_symbols) {
-        dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-        goto End;
-      } else {
-        const int length = use_prev ? prev_code_len : 0;
-        while (repeat-- > 0) code_lengths[symbol++] = length;
-      }
-    }
-  }
-  ok = 1;
-
- End:
-  HuffmanTreeRelease(&tree);
-  return ok;
-}
-
-static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
-                           HuffmanTree* const tree) {
-  int ok = 0;
-  VP8LBitReader* const br = &dec->br_;
-  const int simple_code = VP8LReadBits(br, 1);
-
-  if (simple_code) {  // Read symbols, codes & code lengths directly.
-    int symbols[2];
-    int codes[2];
-    int code_lengths[2];
-    const int num_symbols = VP8LReadBits(br, 1) + 1;
-    const int first_symbol_len_code = VP8LReadBits(br, 1);
-    // The first code is either 1 bit or 8 bit code.
-    symbols[0] = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8);
-    codes[0] = 0;
-    code_lengths[0] = num_symbols - 1;
-    // The second code (if present), is always 8 bit long.
-    if (num_symbols == 2) {
-      symbols[1] = VP8LReadBits(br, 8);
-      codes[1] = 1;
-      code_lengths[1] = num_symbols - 1;
-    }
-    ok = HuffmanTreeBuildExplicit(tree, code_lengths, codes, symbols,
-                                  alphabet_size, num_symbols);
-  } else {  // Decode Huffman-coded code lengths.
-    int* code_lengths = NULL;
-    int i;
-    int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
-    const int num_codes = VP8LReadBits(br, 4) + 4;
-    if (num_codes > NUM_CODE_LENGTH_CODES) {
-      dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-      return 0;
-    }
-
-    code_lengths =
-        (int*)WebPSafeCalloc((uint64_t)alphabet_size, sizeof(*code_lengths));
-    if (code_lengths == NULL) {
-      dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
-      return 0;
-    }
-
-    for (i = 0; i < num_codes; ++i) {
-      code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3);
-    }
-    ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size,
-                                code_lengths);
-    if (ok) {
-      ok = HuffmanTreeBuildImplicit(tree, code_lengths, alphabet_size);
-    }
-    free(code_lengths);
-  }
-  ok = ok && !br->error_;
-  if (!ok) {
-    dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-    return 0;
-  }
-  return 1;
-}
-
-static void DeleteHtreeGroups(HTreeGroup* htree_groups, int num_htree_groups) {
-  if (htree_groups != NULL) {
-    int i, j;
-    for (i = 0; i < num_htree_groups; ++i) {
-      HuffmanTree* const htrees = htree_groups[i].htrees_;
-      for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
-        HuffmanTreeRelease(&htrees[j]);
-      }
-    }
-    free(htree_groups);
-  }
-}
-
-static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
-                            int color_cache_bits, int allow_recursion) {
-  int i, j;
-  VP8LBitReader* const br = &dec->br_;
-  VP8LMetadata* const hdr = &dec->hdr_;
-  uint32_t* huffman_image = NULL;
-  HTreeGroup* htree_groups = NULL;
-  int num_htree_groups = 1;
-
-  if (allow_recursion && VP8LReadBits(br, 1)) {
-    // use meta Huffman codes.
-    const int huffman_precision = VP8LReadBits(br, 3) + 2;
-    const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision);
-    const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision);
-    const int huffman_pixs = huffman_xsize * huffman_ysize;
-    if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec,
-                           &huffman_image)) {
-      dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-      goto Error;
-    }
-    hdr->huffman_subsample_bits_ = huffman_precision;
-    for (i = 0; i < huffman_pixs; ++i) {
-      // The huffman data is stored in red and green bytes.
-      const int index = (huffman_image[i] >> 8) & 0xffff;
-      huffman_image[i] = index;
-      if (index >= num_htree_groups) {
-        num_htree_groups = index + 1;
-      }
-    }
-  }
-
-  if (br->error_) goto Error;
-
-  assert(num_htree_groups <= 0x10000);
-  htree_groups =
-      (HTreeGroup*)WebPSafeCalloc((uint64_t)num_htree_groups,
-                                  sizeof(*htree_groups));
-  if (htree_groups == NULL) {
-    dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  for (i = 0; i < num_htree_groups; ++i) {
-    HuffmanTree* const htrees = htree_groups[i].htrees_;
-    for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
-      int alphabet_size = kAlphabetSize[j];
-      if (j == 0 && color_cache_bits > 0) {
-        alphabet_size += 1 << color_cache_bits;
-      }
-      if (!ReadHuffmanCode(alphabet_size, dec, htrees + j)) goto Error;
-    }
-  }
-
-  // All OK. Finalize pointers and return.
-  hdr->huffman_image_ = huffman_image;
-  hdr->num_htree_groups_ = num_htree_groups;
-  hdr->htree_groups_ = htree_groups;
-  return 1;
-
- Error:
-  free(huffman_image);
-  DeleteHtreeGroups(htree_groups, num_htree_groups);
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// Scaling.
-
-static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
-  const int num_channels = 4;
-  const int in_width = io->mb_w;
-  const int out_width = io->scaled_width;
-  const int in_height = io->mb_h;
-  const int out_height = io->scaled_height;
-  const uint64_t work_size = 2 * num_channels * (uint64_t)out_width;
-  int32_t* work;        // Rescaler work area.
-  const uint64_t scaled_data_size = num_channels * (uint64_t)out_width;
-  uint32_t* scaled_data;  // Temporary storage for scaled BGRA data.
-  const uint64_t memory_size = sizeof(*dec->rescaler) +
-                               work_size * sizeof(*work) +
-                               scaled_data_size * sizeof(*scaled_data);
-  uint8_t* memory = (uint8_t*)WebPSafeCalloc(memory_size, sizeof(*memory));
-  if (memory == NULL) {
-    dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
-    return 0;
-  }
-  assert(dec->rescaler_memory == NULL);
-  dec->rescaler_memory = memory;
-
-  dec->rescaler = (WebPRescaler*)memory;
-  memory += sizeof(*dec->rescaler);
-  work = (int32_t*)memory;
-  memory += work_size * sizeof(*work);
-  scaled_data = (uint32_t*)memory;
-
-  WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data,
-                   out_width, out_height, 0, num_channels,
-                   in_width, out_width, in_height, out_height, work);
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Export to ARGB
-
-// We have special "export" function since we need to convert from BGRA
-static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
-                  int rgba_stride, uint8_t* const rgba) {
-  const uint32_t* const src = (const uint32_t*)rescaler->dst;
-  const int dst_width = rescaler->dst_width;
-  int num_lines_out = 0;
-  while (WebPRescalerHasPendingOutput(rescaler)) {
-    uint8_t* const dst = rgba + num_lines_out * rgba_stride;
-    WebPRescalerExportRow(rescaler);
-    VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
-    ++num_lines_out;
-  }
-  return num_lines_out;
-}
-
-// Emit scaled rows.
-static int EmitRescaledRows(const VP8LDecoder* const dec,
-                            const uint32_t* const data, int in_stride, int mb_h,
-                            uint8_t* const out, int out_stride) {
-  const WEBP_CSP_MODE colorspace = dec->output_->colorspace;
-  const uint8_t* const in = (const uint8_t*)data;
-  int num_lines_in = 0;
-  int num_lines_out = 0;
-  while (num_lines_in < mb_h) {
-    const uint8_t* const row_in = in + num_lines_in * in_stride;
-    uint8_t* const row_out = out + num_lines_out * out_stride;
-    num_lines_in += WebPRescalerImport(dec->rescaler, mb_h - num_lines_in,
-                                       row_in, in_stride);
-    num_lines_out += Export(dec->rescaler, colorspace, out_stride, row_out);
-  }
-  return num_lines_out;
-}
-
-// Emit rows without any scaling.
-static int EmitRows(WEBP_CSP_MODE colorspace,
-                    const uint32_t* const data, int in_stride,
-                    int mb_w, int mb_h,
-                    uint8_t* const out, int out_stride) {
-  int lines = mb_h;
-  const uint8_t* row_in = (const uint8_t*)data;
-  uint8_t* row_out = out;
-  while (lines-- > 0) {
-    VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out);
-    row_in += in_stride;
-    row_out += out_stride;
-  }
-  return mb_h;  // Num rows out == num rows in.
-}
-
-//------------------------------------------------------------------------------
-// Export to YUVA
-
-static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos,
-                          const WebPDecBuffer* const output) {
-  const WebPYUVABuffer* const buf = &output->u.YUVA;
-  // first, the luma plane
-  {
-    int i;
-    uint8_t* const y = buf->y + y_pos * buf->y_stride;
-    for (i = 0; i < width; ++i) {
-      const uint32_t p = src[i];
-      y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff);
-    }
-  }
-
-  // then U/V planes
-  {
-    uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride;
-    uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride;
-    const int uv_width = width >> 1;
-    int i;
-    for (i = 0; i < uv_width; ++i) {
-      const uint32_t v0 = src[2 * i + 0];
-      const uint32_t v1 = src[2 * i + 1];
-      // VP8RGBToU/V expects four accumulated pixels. Hence we need to
-      // scale r/g/b value by a factor 2. We just shift v0/v1 one bit less.
-      const int r = ((v0 >> 15) & 0x1fe) + ((v1 >> 15) & 0x1fe);
-      const int g = ((v0 >>  7) & 0x1fe) + ((v1 >>  7) & 0x1fe);
-      const int b = ((v0 <<  1) & 0x1fe) + ((v1 <<  1) & 0x1fe);
-      if (!(y_pos & 1)) {  // even lines: store values
-        u[i] = VP8RGBToU(r, g, b);
-        v[i] = VP8RGBToV(r, g, b);
-      } else {             // odd lines: average with previous values
-        const int tmp_u = VP8RGBToU(r, g, b);
-        const int tmp_v = VP8RGBToV(r, g, b);
-        // Approximated average-of-four. But it's an acceptable diff.
-        u[i] = (u[i] + tmp_u + 1) >> 1;
-        v[i] = (v[i] + tmp_v + 1) >> 1;
-      }
-    }
-    if (width & 1) {       // last pixel
-      const uint32_t v0 = src[2 * i + 0];
-      const int r = (v0 >> 14) & 0x3fc;
-      const int g = (v0 >>  6) & 0x3fc;
-      const int b = (v0 <<  2) & 0x3fc;
-      if (!(y_pos & 1)) {  // even lines
-        u[i] = VP8RGBToU(r, g, b);
-        v[i] = VP8RGBToV(r, g, b);
-      } else {             // odd lines (note: we could just skip this)
-        const int tmp_u = VP8RGBToU(r, g, b);
-        const int tmp_v = VP8RGBToV(r, g, b);
-        u[i] = (u[i] + tmp_u + 1) >> 1;
-        v[i] = (v[i] + tmp_v + 1) >> 1;
-      }
-    }
-  }
-  // Lastly, store alpha if needed.
-  if (buf->a != NULL) {
-    int i;
-    uint8_t* const a = buf->a + y_pos * buf->a_stride;
-    for (i = 0; i < width; ++i) a[i] = (src[i] >> 24);
-  }
-}
-
-static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) {
-  WebPRescaler* const rescaler = dec->rescaler;
-  const uint32_t* const src = (const uint32_t*)rescaler->dst;
-  const int dst_width = rescaler->dst_width;
-  int num_lines_out = 0;
-  while (WebPRescalerHasPendingOutput(rescaler)) {
-    WebPRescalerExportRow(rescaler);
-    ConvertToYUVA(src, dst_width, y_pos, dec->output_);
-    ++y_pos;
-    ++num_lines_out;
-  }
-  return num_lines_out;
-}
-
-static int EmitRescaledRowsYUVA(const VP8LDecoder* const dec,
-                                const uint32_t* const data,
-                                int in_stride, int mb_h) {
-  const uint8_t* const in = (const uint8_t*)data;
-  int num_lines_in = 0;
-  int y_pos = dec->last_out_row_;
-  while (num_lines_in < mb_h) {
-    const uint8_t* const row_in = in + num_lines_in * in_stride;
-    num_lines_in += WebPRescalerImport(dec->rescaler, mb_h - num_lines_in,
-                                       row_in, in_stride);
-    y_pos += ExportYUVA(dec, y_pos);
-  }
-  return y_pos;
-}
-
-static int EmitRowsYUVA(const VP8LDecoder* const dec,
-                        const uint32_t* const data, int in_stride,
-                        int mb_w, int num_rows) {
-  int y_pos = dec->last_out_row_;
-  const uint8_t* row_in = (const uint8_t*)data;
-  while (num_rows-- > 0) {
-    ConvertToYUVA((const uint32_t*)row_in, mb_w, y_pos, dec->output_);
-    row_in += in_stride;
-    ++y_pos;
-  }
-  return y_pos;
-}
-
-//------------------------------------------------------------------------------
-// Cropping.
-
-// Sets io->mb_y, io->mb_h & io->mb_w according to start row, end row and
-// crop options. Also updates the input data pointer, so that it points to the
-// start of the cropped window.
-// Note that 'pixel_stride' is in units of 'uint32_t' (and not 'bytes).
-// Returns true if the crop window is not empty.
-static int SetCropWindow(VP8Io* const io, int y_start, int y_end,
-                         const uint32_t** const in_data, int pixel_stride) {
-  assert(y_start < y_end);
-  assert(io->crop_left < io->crop_right);
-  if (y_end > io->crop_bottom) {
-    y_end = io->crop_bottom;  // make sure we don't overflow on last row.
-  }
-  if (y_start < io->crop_top) {
-    const int delta = io->crop_top - y_start;
-    y_start = io->crop_top;
-    *in_data += pixel_stride * delta;
-  }
-  if (y_start >= y_end) return 0;  // Crop window is empty.
-
-  *in_data += io->crop_left;
-
-  io->mb_y = y_start - io->crop_top;
-  io->mb_w = io->crop_right - io->crop_left;
-  io->mb_h = y_end - y_start;
-  return 1;  // Non-empty crop window.
-}
-
-//------------------------------------------------------------------------------
-
-static WEBP_INLINE int GetMetaIndex(
-    const uint32_t* const image, int xsize, int bits, int x, int y) {
-  if (bits == 0) return 0;
-  return image[xsize * (y >> bits) + (x >> bits)];
-}
-
-static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr,
-                                                   int x, int y) {
-  const int meta_index = GetMetaIndex(hdr->huffman_image_, hdr->huffman_xsize_,
-                                      hdr->huffman_subsample_bits_, x, y);
-  assert(meta_index < hdr->num_htree_groups_);
-  return hdr->htree_groups_ + meta_index;
-}
-
-//------------------------------------------------------------------------------
-// Main loop, with custom row-processing function
-
-typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row);
-
-static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows,
-                                   const uint32_t* const rows) {
-  int n = dec->next_transform_;
-  const int cache_pixs = dec->width_ * num_rows;
-  const int start_row = dec->last_row_;
-  const int end_row = start_row + num_rows;
-  const uint32_t* rows_in = rows;
-  uint32_t* const rows_out = dec->argb_cache_;
-
-  // Inverse transforms.
-  // TODO: most transforms only need to operate on the cropped region only.
-  memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out));
-  while (n-- > 0) {
-    VP8LTransform* const transform = &dec->transforms_[n];
-    VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out);
-    rows_in = rows_out;
-  }
-}
-
-// Processes (transforms, scales & color-converts) the rows decoded after the
-// last call.
-static void ProcessRows(VP8LDecoder* const dec, int row) {
-  const uint32_t* const rows = dec->argb_ + dec->width_ * dec->last_row_;
-  const int num_rows = row - dec->last_row_;
-
-  if (num_rows <= 0) return;  // Nothing to be done.
-  ApplyInverseTransforms(dec, num_rows, rows);
-
-  // Emit output.
-  {
-    VP8Io* const io = dec->io_;
-    const uint32_t* rows_data = dec->argb_cache_;
-    if (!SetCropWindow(io, dec->last_row_, row, &rows_data, io->width)) {
-      // Nothing to output (this time).
-    } else {
-      const WebPDecBuffer* const output = dec->output_;
-      const int in_stride = io->width * sizeof(*rows_data);
-      if (output->colorspace < MODE_YUV) {  // convert to RGBA
-        const WebPRGBABuffer* const buf = &output->u.RGBA;
-        uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
-        const int num_rows_out = io->use_scaling ?
-            EmitRescaledRows(dec, rows_data, in_stride, io->mb_h,
-                             rgba, buf->stride) :
-            EmitRows(output->colorspace, rows_data, in_stride,
-                     io->mb_w, io->mb_h, rgba, buf->stride);
-        // Update 'last_out_row_'.
-        dec->last_out_row_ += num_rows_out;
-      } else {                              // convert to YUVA
-        dec->last_out_row_ = io->use_scaling ?
-            EmitRescaledRowsYUVA(dec, rows_data, in_stride, io->mb_h) :
-            EmitRowsYUVA(dec, rows_data, in_stride, io->mb_w, io->mb_h);
-      }
-      assert(dec->last_out_row_ <= output->height);
-    }
-  }
-
-  // Update 'last_row_'.
-  dec->last_row_ = row;
-  assert(dec->last_row_ <= dec->height_);
-}
-
-static int DecodeImageData(VP8LDecoder* const dec,
-                           uint32_t* const data, int width, int height,
-                           ProcessRowsFunc process_func) {
-  int ok = 1;
-  int col = 0, row = 0;
-  VP8LBitReader* const br = &dec->br_;
-  VP8LMetadata* const hdr = &dec->hdr_;
-  HTreeGroup* htree_group = hdr->htree_groups_;
-  uint32_t* src = data;
-  uint32_t* last_cached = data;
-  uint32_t* const src_end = data + width * height;
-  const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
-  const int color_cache_limit = len_code_limit + hdr->color_cache_size_;
-  VP8LColorCache* const color_cache =
-      (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
-  const int mask = hdr->huffman_mask_;
-
-  assert(htree_group != NULL);
-
-  while (!br->eos_ && src < src_end) {
-    int code;
-    // Only update when changing tile. Note we could use the following test:
-    //   if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed
-    // but that's actually slower and requires storing the previous col/row
-    if ((col & mask) == 0) {
-      htree_group = GetHtreeGroupForPos(hdr, col, row);
-    }
-    VP8LFillBitWindow(br);
-    code = ReadSymbol(&htree_group->htrees_[GREEN], br);
-    if (code < NUM_LITERAL_CODES) {   // Literal.
-      int red, green, blue, alpha;
-      red = ReadSymbol(&htree_group->htrees_[RED], br);
-      green = code;
-      VP8LFillBitWindow(br);
-      blue = ReadSymbol(&htree_group->htrees_[BLUE], br);
-      alpha = ReadSymbol(&htree_group->htrees_[ALPHA], br);
-      *src = (alpha << 24) + (red << 16) + (green << 8) + blue;
- AdvanceByOne:
-      ++src;
-      ++col;
-      if (col >= width) {
-        col = 0;
-        ++row;
-        if ((process_func != NULL) && (row % NUM_ARGB_CACHE_ROWS == 0)) {
-          process_func(dec, row);
-        }
-        if (color_cache != NULL) {
-          while (last_cached < src) {
-            VP8LColorCacheInsert(color_cache, *last_cached++);
-          }
-        }
-      }
-    } else if (code < len_code_limit) {           // Backward reference
-      int dist_code, dist;
-      const int length_sym = code - NUM_LITERAL_CODES;
-      const int length = GetCopyLength(length_sym, br);
-      const int dist_symbol = ReadSymbol(&htree_group->htrees_[DIST], br);
-      VP8LFillBitWindow(br);
-      dist_code = GetCopyDistance(dist_symbol, br);
-      dist = PlaneCodeToDistance(width, dist_code);
-      if (src - data < dist || src_end - src < length) {
-        ok = 0;
-        goto End;
-      }
-      {
-        int i;
-        for (i = 0; i < length; ++i) src[i] = src[i - dist];
-        src += length;
-      }
-      col += length;
-      while (col >= width) {
-        col -= width;
-        ++row;
-        if ((process_func != NULL) && (row % NUM_ARGB_CACHE_ROWS == 0)) {
-          process_func(dec, row);
-        }
-      }
-      if (src < src_end) {
-        htree_group = GetHtreeGroupForPos(hdr, col, row);
-        if (color_cache != NULL) {
-          while (last_cached < src) {
-            VP8LColorCacheInsert(color_cache, *last_cached++);
-          }
-        }
-      }
-    } else if (code < color_cache_limit) {    // Color cache.
-      const int key = code - len_code_limit;
-      assert(color_cache != NULL);
-      while (last_cached < src) {
-        VP8LColorCacheInsert(color_cache, *last_cached++);
-      }
-      *src = VP8LColorCacheLookup(color_cache, key);
-      goto AdvanceByOne;
-    } else {    // Not reached.
-      ok = 0;
-      goto End;
-    }
-    ok = !br->error_;
-    if (!ok) goto End;
-  }
-  // Process the remaining rows corresponding to last row-block.
-  if (process_func != NULL) process_func(dec, row);
-
- End:
-  if (br->error_ || !ok || (br->eos_ && src < src_end)) {
-    ok = 0;
-    dec->status_ = (!br->eos_) ?
-        VP8_STATUS_BITSTREAM_ERROR : VP8_STATUS_SUSPENDED;
-  } else if (src == src_end) {
-    dec->state_ = READ_DATA;
-  }
-
-  return ok;
-}
-
-// -----------------------------------------------------------------------------
-// VP8LTransform
-
-static void ClearTransform(VP8LTransform* const transform) {
-  free(transform->data_);
-  transform->data_ = NULL;
-}
-
-// For security reason, we need to remap the color map to span
-// the total possible bundled values, and not just the num_colors.
-static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
-  int i;
-  const int final_num_colors = 1 << (8 >> transform->bits_);
-  uint32_t* const new_color_map =
-      (uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors,
-                                sizeof(*new_color_map));
-  if (new_color_map == NULL) {
-    return 0;
-  } else {
-    uint8_t* const data = (uint8_t*)transform->data_;
-    uint8_t* const new_data = (uint8_t*)new_color_map;
-    new_color_map[0] = transform->data_[0];
-    for (i = 4; i < 4 * num_colors; ++i) {
-      // Equivalent to AddPixelEq(), on a byte-basis.
-      new_data[i] = (data[i] + new_data[i - 4]) & 0xff;
-    }
-    for (; i < 4 * final_num_colors; ++i)
-      new_data[i] = 0;  // black tail.
-    free(transform->data_);
-    transform->data_ = new_color_map;
-  }
-  return 1;
-}
-
-static int ReadTransform(int* const xsize, int const* ysize,
-                         VP8LDecoder* const dec) {
-  int ok = 1;
-  VP8LBitReader* const br = &dec->br_;
-  VP8LTransform* transform = &dec->transforms_[dec->next_transform_];
-  const VP8LImageTransformType type =
-      (VP8LImageTransformType)VP8LReadBits(br, 2);
-
-  // Each transform type can only be present once in the stream.
-  if (dec->transforms_seen_ & (1U << type)) {
-    return 0;  // Already there, let's not accept the second same transform.
-  }
-  dec->transforms_seen_ |= (1U << type);
-
-  transform->type_ = type;
-  transform->xsize_ = *xsize;
-  transform->ysize_ = *ysize;
-  transform->data_ = NULL;
-  ++dec->next_transform_;
-  assert(dec->next_transform_ <= NUM_TRANSFORMS);
-
-  switch (type) {
-    case PREDICTOR_TRANSFORM:
-    case CROSS_COLOR_TRANSFORM:
-      transform->bits_ = VP8LReadBits(br, 3) + 2;
-      ok = DecodeImageStream(VP8LSubSampleSize(transform->xsize_,
-                                               transform->bits_),
-                             VP8LSubSampleSize(transform->ysize_,
-                                               transform->bits_),
-                             0, dec, &transform->data_);
-      break;
-    case COLOR_INDEXING_TRANSFORM: {
-       const int num_colors = VP8LReadBits(br, 8) + 1;
-       const int bits = (num_colors > 16) ? 0
-                      : (num_colors > 4) ? 1
-                      : (num_colors > 2) ? 2
-                      : 3;
-       *xsize = VP8LSubSampleSize(transform->xsize_, bits);
-       transform->bits_ = bits;
-       ok = DecodeImageStream(num_colors, 1, 0, dec, &transform->data_);
-       ok = ok && ExpandColorMap(num_colors, transform);
-      break;
-    }
-    case SUBTRACT_GREEN:
-      break;
-    default:
-      assert(0);    // can't happen
-      break;
-  }
-
-  return ok;
-}
-
-// -----------------------------------------------------------------------------
-// VP8LMetadata
-
-static void InitMetadata(VP8LMetadata* const hdr) {
-  assert(hdr);
-  memset(hdr, 0, sizeof(*hdr));
-}
-
-static void ClearMetadata(VP8LMetadata* const hdr) {
-  assert(hdr);
-
-  free(hdr->huffman_image_);
-  DeleteHtreeGroups(hdr->htree_groups_, hdr->num_htree_groups_);
-  VP8LColorCacheClear(&hdr->color_cache_);
-  InitMetadata(hdr);
-}
-
-// -----------------------------------------------------------------------------
-// VP8LDecoder
-
-VP8LDecoder* VP8LNew(void) {
-  VP8LDecoder* const dec = (VP8LDecoder*)calloc(1, sizeof(*dec));
-  if (dec == NULL) return NULL;
-  dec->status_ = VP8_STATUS_OK;
-  dec->action_ = READ_DIM;
-  dec->state_ = READ_DIM;
-  return dec;
-}
-
-void VP8LClear(VP8LDecoder* const dec) {
-  int i;
-  if (dec == NULL) return;
-  ClearMetadata(&dec->hdr_);
-
-  free(dec->argb_);
-  dec->argb_ = NULL;
-  for (i = 0; i < dec->next_transform_; ++i) {
-    ClearTransform(&dec->transforms_[i]);
-  }
-  dec->next_transform_ = 0;
-  dec->transforms_seen_ = 0;
-
-  free(dec->rescaler_memory);
-  dec->rescaler_memory = NULL;
-
-  dec->output_ = NULL;   // leave no trace behind
-}
-
-void VP8LDelete(VP8LDecoder* const dec) {
-  if (dec != NULL) {
-    VP8LClear(dec);
-    free(dec);
-  }
-}
-
-static void UpdateDecoder(VP8LDecoder* const dec, int width, int height) {
-  VP8LMetadata* const hdr = &dec->hdr_;
-  const int num_bits = hdr->huffman_subsample_bits_;
-  dec->width_ = width;
-  dec->height_ = height;
-
-  hdr->huffman_xsize_ = VP8LSubSampleSize(width, num_bits);
-  hdr->huffman_mask_ = (num_bits == 0) ? ~0 : (1 << num_bits) - 1;
-}
-
-static int DecodeImageStream(int xsize, int ysize,
-                             int is_level0,
-                             VP8LDecoder* const dec,
-                             uint32_t** const decoded_data) {
-  int ok = 1;
-  int transform_xsize = xsize;
-  int transform_ysize = ysize;
-  VP8LBitReader* const br = &dec->br_;
-  VP8LMetadata* const hdr = &dec->hdr_;
-  uint32_t* data = NULL;
-  int color_cache_bits = 0;
-
-  // Read the transforms (may recurse).
-  if (is_level0) {
-    while (ok && VP8LReadBits(br, 1)) {
-      ok = ReadTransform(&transform_xsize, &transform_ysize, dec);
-    }
-  }
-
-  // Color cache
-  if (ok && VP8LReadBits(br, 1)) {
-    color_cache_bits = VP8LReadBits(br, 4);
-    ok = (color_cache_bits >= 1 && color_cache_bits <= MAX_CACHE_BITS);
-    if (!ok) {
-      dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-      goto End;
-    }
-  }
-
-  // Read the Huffman codes (may recurse).
-  ok = ok && ReadHuffmanCodes(dec, transform_xsize, transform_ysize,
-                              color_cache_bits, is_level0);
-  if (!ok) {
-    dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-    goto End;
-  }
-
-  // Finish setting up the color-cache
-  if (color_cache_bits > 0) {
-    hdr->color_cache_size_ = 1 << color_cache_bits;
-    if (!VP8LColorCacheInit(&hdr->color_cache_, color_cache_bits)) {
-      dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
-      ok = 0;
-      goto End;
-    }
-  } else {
-    hdr->color_cache_size_ = 0;
-  }
-  UpdateDecoder(dec, transform_xsize, transform_ysize);
-
-  if (is_level0) {   // level 0 complete
-    dec->state_ = READ_HDR;
-    goto End;
-  }
-
-  {
-    const uint64_t total_size = (uint64_t)transform_xsize * transform_ysize;
-    data = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*data));
-    if (data == NULL) {
-      dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
-      ok = 0;
-      goto End;
-    }
-  }
-
-  // Use the Huffman trees to decode the LZ77 encoded data.
-  ok = DecodeImageData(dec, data, transform_xsize, transform_ysize, NULL);
-  ok = ok && !br->error_;
-
- End:
-
-  if (!ok) {
-    free(data);
-    ClearMetadata(hdr);
-    // If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the
-    // status appropriately.
-    if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR && dec->br_.eos_) {
-      dec->status_ = VP8_STATUS_SUSPENDED;
-    }
-  } else {
-    if (decoded_data != NULL) {
-      *decoded_data = data;
-    } else {
-      // We allocate image data in this function only for transforms. At level 0
-      // (that is: not the transforms), we shouldn't have allocated anything.
-      assert(data == NULL);
-      assert(is_level0);
-    }
-    if (!is_level0) ClearMetadata(hdr);  // Clean up temporary data behind.
-  }
-  return ok;
-}
-
-//------------------------------------------------------------------------------
-// Allocate dec->argb_ and dec->argb_cache_ using dec->width_ and dec->height_
-
-static int AllocateARGBBuffers(VP8LDecoder* const dec, int final_width) {
-  const uint64_t num_pixels = (uint64_t)dec->width_ * dec->height_;
-  // Scratch buffer corresponding to top-prediction row for transforming the
-  // first row in the row-blocks.
-  const uint64_t cache_top_pixels = final_width;
-  // Scratch buffer for temporary BGRA storage.
-  const uint64_t cache_pixels = (uint64_t)final_width * NUM_ARGB_CACHE_ROWS;
-  const uint64_t total_num_pixels =
-      num_pixels + cache_top_pixels + cache_pixels;
-
-  assert(dec->width_ <= final_width);
-  dec->argb_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(*dec->argb_));
-  if (dec->argb_ == NULL) {
-    dec->argb_cache_ = NULL;    // for sanity check
-    dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
-    return 0;
-  }
-  dec->argb_cache_ = dec->argb_ + num_pixels + cache_top_pixels;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Special row-processing that only stores the alpha data.
-
-static void ExtractAlphaRows(VP8LDecoder* const dec, int row) {
-  const int num_rows = row - dec->last_row_;
-  const uint32_t* const in = dec->argb_ + dec->width_ * dec->last_row_;
-
-  if (num_rows <= 0) return;  // Nothing to be done.
-  ApplyInverseTransforms(dec, num_rows, in);
-
-  // Extract alpha (which is stored in the green plane).
-  {
-    const int width = dec->io_->width;      // the final width (!= dec->width_)
-    const int cache_pixs = width * num_rows;
-    uint8_t* const dst = (uint8_t*)dec->io_->opaque + width * dec->last_row_;
-    const uint32_t* const src = dec->argb_cache_;
-    int i;
-    for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff;
-  }
-
-  dec->last_row_ = dec->last_out_row_ = row;
-}
-
-int VP8LDecodeAlphaImageStream(int width, int height, const uint8_t* const data,
-                               size_t data_size, uint8_t* const output) {
-  VP8Io io;
-  int ok = 0;
-  VP8LDecoder* const dec = VP8LNew();
-  if (dec == NULL) return 0;
-
-  dec->width_ = width;
-  dec->height_ = height;
-  dec->io_ = &io;
-
-  VP8InitIo(&io);
-  WebPInitCustomIo(NULL, &io);    // Just a sanity Init. io won't be used.
-  io.opaque = output;
-  io.width = width;
-  io.height = height;
-
-  dec->status_ = VP8_STATUS_OK;
-  VP8LInitBitReader(&dec->br_, data, data_size);
-
-  dec->action_ = READ_HDR;
-  if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Err;
-
-  // Allocate output (note that dec->width_ may have changed here).
-  if (!AllocateARGBBuffers(dec, width)) goto Err;
-
-  // Decode (with special row processing).
-  dec->action_ = READ_DATA;
-  ok = DecodeImageData(dec, dec->argb_, dec->width_, dec->height_,
-                       ExtractAlphaRows);
-
- Err:
-  VP8LDelete(dec);
-  return ok;
-}
-
-//------------------------------------------------------------------------------
-
-int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) {
-  int width, height, has_alpha;
-
-  if (dec == NULL) return 0;
-  if (io == NULL) {
-    dec->status_ = VP8_STATUS_INVALID_PARAM;
-    return 0;
-  }
-
-  dec->io_ = io;
-  dec->status_ = VP8_STATUS_OK;
-  VP8LInitBitReader(&dec->br_, io->data, io->data_size);
-  if (!ReadImageInfo(&dec->br_, &width, &height, &has_alpha)) {
-    dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
-    goto Error;
-  }
-  dec->state_ = READ_DIM;
-  io->width = width;
-  io->height = height;
-
-  dec->action_ = READ_HDR;
-  if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Error;
-  return 1;
-
- Error:
-   VP8LClear(dec);
-   assert(dec->status_ != VP8_STATUS_OK);
-   return 0;
-}
-
-int VP8LDecodeImage(VP8LDecoder* const dec) {
-  VP8Io* io = NULL;
-  WebPDecParams* params = NULL;
-
-  // Sanity checks.
-  if (dec == NULL) return 0;
-
-  io = dec->io_;
-  assert(io != NULL);
-  params = (WebPDecParams*)io->opaque;
-  assert(params != NULL);
-  dec->output_ = params->output;
-  assert(dec->output_ != NULL);
-
-  // Initialization.
-  if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) {
-    dec->status_ = VP8_STATUS_INVALID_PARAM;
-    goto Err;
-  }
-
-  if (!AllocateARGBBuffers(dec, io->width)) goto Err;
-
-  if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
-
-  // Decode.
-  dec->action_ = READ_DATA;
-  if (!DecodeImageData(dec, dec->argb_, dec->width_, dec->height_,
-                       ProcessRows)) {
-    goto Err;
-  }
-
-  // Cleanup.
-  params->last_y = dec->last_out_row_;
-  VP8LClear(dec);
-  return 1;
-
- Err:
-  VP8LClear(dec);
-  assert(dec->status_ != VP8_STATUS_OK);
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 121
drivers/webpold/dec/vp8li.h

@@ -1,121 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Lossless decoder: internal header.
-//
-// Author: Skal ([email protected])
-//         Vikas Arora([email protected])
-
-#ifndef WEBP_DEC_VP8LI_H_
-#define WEBP_DEC_VP8LI_H_
-
-#include <string.h>     // for memcpy()
-#include "./webpi.h"
-#include "../utils/bit_reader.h"
-#include "../utils/color_cache.h"
-#include "../utils/huffman.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-typedef enum {
-  READ_DATA = 0,
-  READ_HDR = 1,
-  READ_DIM = 2
-} VP8LDecodeState;
-
-typedef struct VP8LTransform VP8LTransform;
-struct VP8LTransform {
-  VP8LImageTransformType type_;   // transform type.
-  int                    bits_;   // subsampling bits defining transform window.
-  int                    xsize_;  // transform window X index.
-  int                    ysize_;  // transform window Y index.
-  uint32_t              *data_;   // transform data.
-};
-
-typedef struct {
-  HuffmanTree htrees_[HUFFMAN_CODES_PER_META_CODE];
-} HTreeGroup;
-
-typedef struct {
-  int             color_cache_size_;
-  VP8LColorCache  color_cache_;
-
-  int             huffman_mask_;
-  int             huffman_subsample_bits_;
-  int             huffman_xsize_;
-  uint32_t       *huffman_image_;
-  int             num_htree_groups_;
-  HTreeGroup     *htree_groups_;
-} VP8LMetadata;
-
-typedef struct {
-  VP8StatusCode    status_;
-  VP8LDecodeState  action_;
-  VP8LDecodeState  state_;
-  VP8Io           *io_;
-
-  const WebPDecBuffer *output_;    // shortcut to io->opaque->output
-
-  uint32_t        *argb_;          // Internal data: always in BGRA color mode.
-  uint32_t        *argb_cache_;    // Scratch buffer for temporary BGRA storage.
-
-  VP8LBitReader    br_;
-
-  int              width_;
-  int              height_;
-  int              last_row_;      // last input row decoded so far.
-  int              last_out_row_;  // last row output so far.
-
-  VP8LMetadata     hdr_;
-
-  int              next_transform_;
-  VP8LTransform    transforms_[NUM_TRANSFORMS];
-  // or'd bitset storing the transforms types.
-  uint32_t         transforms_seen_;
-
-  uint8_t         *rescaler_memory;  // Working memory for rescaling work.
-  WebPRescaler    *rescaler;         // Common rescaler for all channels.
-} VP8LDecoder;
-
-//------------------------------------------------------------------------------
-// internal functions. Not public.
-
-// in vp8l.c
-
-// Decodes a raw image stream (without header) and store the alpha data
-// into *output, which must be of size width x height. Returns false in case
-// of error.
-int VP8LDecodeAlphaImageStream(int width, int height, const uint8_t* const data,
-                               size_t data_size, uint8_t* const output);
-
-// Allocates and initialize a new lossless decoder instance.
-VP8LDecoder* VP8LNew(void);
-
-// Decodes the image header. Returns false in case of error.
-int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io);
-
-// Decodes an image. It's required to decode the lossless header before calling
-// this function. Returns false in case of error, with updated dec->status_.
-int VP8LDecodeImage(VP8LDecoder* const dec);
-
-// Resets the decoder in its initial state, reclaiming memory.
-// Preserves the dec->status_ value.
-void VP8LClear(VP8LDecoder* const dec);
-
-// Clears and deallocate a lossless decoder instance.
-void VP8LDelete(VP8LDecoder* const dec);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_DEC_VP8LI_H_ */

+ 0 - 771
drivers/webpold/dec/webp.c

@@ -1,771 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Main decoding functions for WEBP images.
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-
-#include "./vp8i.h"
-#include "./vp8li.h"
-#include "./webpi.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// RIFF layout is:
-//   Offset  tag
-//   0...3   "RIFF" 4-byte tag
-//   4...7   size of image data (including metadata) starting at offset 8
-//   8...11  "WEBP"   our form-type signature
-// The RIFF container (12 bytes) is followed by appropriate chunks:
-//   12..15  "VP8 ": 4-bytes tags, signaling the use of VP8 video format
-//   16..19  size of the raw VP8 image data, starting at offset 20
-//   20....  the VP8 bytes
-// Or,
-//   12..15  "VP8L": 4-bytes tags, signaling the use of VP8L lossless format
-//   16..19  size of the raw VP8L image data, starting at offset 20
-//   20....  the VP8L bytes
-// Or,
-//   12..15  "VP8X": 4-bytes tags, describing the extended-VP8 chunk.
-//   16..19  size of the VP8X chunk starting at offset 20.
-//   20..23  VP8X flags bit-map corresponding to the chunk-types present.
-//   24..26  Width of the Canvas Image.
-//   27..29  Height of the Canvas Image.
-// There can be extra chunks after the "VP8X" chunk (ICCP, TILE, FRM, VP8,
-// META  ...)
-// All sizes are in little-endian order.
-// Note: chunk data size must be padded to multiple of 2 when written.
-
-static WEBP_INLINE uint32_t get_le24(const uint8_t* const data) {
-  return data[0] | (data[1] << 8) | (data[2] << 16);
-}
-
-static WEBP_INLINE uint32_t get_le32(const uint8_t* const data) {
-  return (uint32_t)get_le24(data) | (data[3] << 24);
-}
-
-// Validates the RIFF container (if detected) and skips over it.
-// If a RIFF container is detected,
-// Returns VP8_STATUS_BITSTREAM_ERROR for invalid header, and
-//         VP8_STATUS_OK otherwise.
-// In case there are not enough bytes (partial RIFF container), return 0 for
-// *riff_size. Else return the RIFF size extracted from the header.
-static VP8StatusCode ParseRIFF(const uint8_t** const data,
-                               size_t* const data_size,
-                               size_t* const riff_size) {
-  assert(data != NULL);
-  assert(data_size != NULL);
-  assert(riff_size != NULL);
-
-  *riff_size = 0;  // Default: no RIFF present.
-  if (*data_size >= RIFF_HEADER_SIZE && !memcmp(*data, "RIFF", TAG_SIZE)) {
-    if (memcmp(*data + 8, "WEBP", TAG_SIZE)) {
-      return VP8_STATUS_BITSTREAM_ERROR;  // Wrong image file signature.
-    } else {
-      const uint32_t size = get_le32(*data + TAG_SIZE);
-      // Check that we have at least one chunk (i.e "WEBP" + "VP8?nnnn").
-      if (size < TAG_SIZE + CHUNK_HEADER_SIZE) {
-        return VP8_STATUS_BITSTREAM_ERROR;
-      }
-      // We have a RIFF container. Skip it.
-      *riff_size = size;
-      *data += RIFF_HEADER_SIZE;
-      *data_size -= RIFF_HEADER_SIZE;
-    }
-  }
-  return VP8_STATUS_OK;
-}
-
-// Validates the VP8X header and skips over it.
-// Returns VP8_STATUS_BITSTREAM_ERROR for invalid VP8X header,
-//         VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
-//         VP8_STATUS_OK otherwise.
-// If a VP8X chunk is found, found_vp8x is set to true and *width_ptr,
-// *height_ptr and *flags_ptr are set to the corresponding values extracted
-// from the VP8X chunk.
-static VP8StatusCode ParseVP8X(const uint8_t** const data,
-                               size_t* const data_size,
-                               int* const found_vp8x,
-                               int* const width_ptr, int* const height_ptr,
-                               uint32_t* const flags_ptr) {
-  const uint32_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
-  assert(data != NULL);
-  assert(data_size != NULL);
-  assert(found_vp8x != NULL);
-
-  *found_vp8x = 0;
-
-  if (*data_size < CHUNK_HEADER_SIZE) {
-    return VP8_STATUS_NOT_ENOUGH_DATA;  // Insufficient data.
-  }
-
-  if (!memcmp(*data, "VP8X", TAG_SIZE)) {
-    int width, height;
-    uint32_t flags;
-    const uint32_t chunk_size = get_le32(*data + TAG_SIZE);
-    if (chunk_size != VP8X_CHUNK_SIZE) {
-      return VP8_STATUS_BITSTREAM_ERROR;  // Wrong chunk size.
-    }
-
-    // Verify if enough data is available to validate the VP8X chunk.
-    if (*data_size < vp8x_size) {
-      return VP8_STATUS_NOT_ENOUGH_DATA;  // Insufficient data.
-    }
-    flags = get_le32(*data + 8);
-    width = 1 + get_le24(*data + 12);
-    height = 1 + get_le24(*data + 15);
-    if (width * (uint64_t)height >= MAX_IMAGE_AREA) {
-      return VP8_STATUS_BITSTREAM_ERROR;  // image is too large
-    }
-
-    if (flags_ptr != NULL) *flags_ptr = flags;
-    if (width_ptr != NULL) *width_ptr = width;
-    if (height_ptr != NULL) *height_ptr = height;
-    // Skip over VP8X header bytes.
-    *data += vp8x_size;
-    *data_size -= vp8x_size;
-    *found_vp8x = 1;
-  }
-  return VP8_STATUS_OK;
-}
-
-// Skips to the next VP8/VP8L chunk header in the data given the size of the
-// RIFF chunk 'riff_size'.
-// Returns VP8_STATUS_BITSTREAM_ERROR if any invalid chunk size is encountered,
-//         VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
-//         VP8_STATUS_OK otherwise.
-// If an alpha chunk is found, *alpha_data and *alpha_size are set
-// appropriately.
-static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
-                                         size_t* const data_size,
-                                         size_t const riff_size,
-                                         const uint8_t** const alpha_data,
-                                         size_t* const alpha_size) {
-  const uint8_t* buf;
-  size_t buf_size;
-  uint32_t total_size = TAG_SIZE +           // "WEBP".
-                        CHUNK_HEADER_SIZE +  // "VP8Xnnnn".
-                        VP8X_CHUNK_SIZE;     // data.
-  assert(data != NULL);
-  assert(data_size != NULL);
-  buf = *data;
-  buf_size = *data_size;
-
-  assert(alpha_data != NULL);
-  assert(alpha_size != NULL);
-  *alpha_data = NULL;
-  *alpha_size = 0;
-
-  while (1) {
-    uint32_t chunk_size;
-    uint32_t disk_chunk_size;   // chunk_size with padding
-
-    *data = buf;
-    *data_size = buf_size;
-
-    if (buf_size < CHUNK_HEADER_SIZE) {  // Insufficient data.
-      return VP8_STATUS_NOT_ENOUGH_DATA;
-    }
-
-    chunk_size = get_le32(buf + TAG_SIZE);
-    // For odd-sized chunk-payload, there's one byte padding at the end.
-    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
-    total_size += disk_chunk_size;
-
-    // Check that total bytes skipped so far does not exceed riff_size.
-    if (riff_size > 0 && (total_size > riff_size)) {
-      return VP8_STATUS_BITSTREAM_ERROR;          // Not a valid chunk size.
-    }
-
-    if (buf_size < disk_chunk_size) {             // Insufficient data.
-      return VP8_STATUS_NOT_ENOUGH_DATA;
-    }
-
-    if (!memcmp(buf, "ALPH", TAG_SIZE)) {         // A valid ALPH header.
-      *alpha_data = buf + CHUNK_HEADER_SIZE;
-      *alpha_size = chunk_size;
-    } else if (!memcmp(buf, "VP8 ", TAG_SIZE) ||
-               !memcmp(buf, "VP8L", TAG_SIZE)) {  // A valid VP8/VP8L header.
-      return VP8_STATUS_OK;  // Found.
-    }
-
-    // We have a full and valid chunk; skip it.
-    buf += disk_chunk_size;
-    buf_size -= disk_chunk_size;
-  }
-}
-
-// Validates the VP8/VP8L Header ("VP8 nnnn" or "VP8L nnnn") and skips over it.
-// Returns VP8_STATUS_BITSTREAM_ERROR for invalid (chunk larger than
-//         riff_size) VP8/VP8L header,
-//         VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
-//         VP8_STATUS_OK otherwise.
-// If a VP8/VP8L chunk is found, *chunk_size is set to the total number of bytes
-// extracted from the VP8/VP8L chunk header.
-// The flag '*is_lossless' is set to 1 in case of VP8L chunk / raw VP8L data.
-static VP8StatusCode ParseVP8Header(const uint8_t** const data_ptr,
-                                    size_t* const data_size,
-                                    size_t riff_size,
-                                    size_t* const chunk_size,
-                                    int* const is_lossless) {
-  const uint8_t* const data = *data_ptr;
-  const int is_vp8 = !memcmp(data, "VP8 ", TAG_SIZE);
-  const int is_vp8l = !memcmp(data, "VP8L", TAG_SIZE);
-  const uint32_t minimal_size =
-      TAG_SIZE + CHUNK_HEADER_SIZE;  // "WEBP" + "VP8 nnnn" OR
-                                     // "WEBP" + "VP8Lnnnn"
-  assert(data != NULL);
-  assert(data_size != NULL);
-  assert(chunk_size != NULL);
-  assert(is_lossless != NULL);
-
-  if (*data_size < CHUNK_HEADER_SIZE) {
-    return VP8_STATUS_NOT_ENOUGH_DATA;  // Insufficient data.
-  }
-
-  if (is_vp8 || is_vp8l) {
-    // Bitstream contains VP8/VP8L header.
-    const uint32_t size = get_le32(data + TAG_SIZE);
-    if ((riff_size >= minimal_size) && (size > riff_size - minimal_size)) {
-      return VP8_STATUS_BITSTREAM_ERROR;  // Inconsistent size information.
-    }
-    // Skip over CHUNK_HEADER_SIZE bytes from VP8/VP8L Header.
-    *chunk_size = size;
-    *data_ptr += CHUNK_HEADER_SIZE;
-    *data_size -= CHUNK_HEADER_SIZE;
-    *is_lossless = is_vp8l;
-  } else {
-    // Raw VP8/VP8L bitstream (no header).
-    *is_lossless = VP8LCheckSignature(data, *data_size);
-    *chunk_size = *data_size;
-  }
-
-  return VP8_STATUS_OK;
-}
-
-//------------------------------------------------------------------------------
-
-// Fetch '*width', '*height', '*has_alpha' and fill out 'headers' based on
-// 'data'. All the output parameters may be NULL. If 'headers' is NULL only the
-// minimal amount will be read to fetch the remaining parameters.
-// If 'headers' is non-NULL this function will attempt to locate both alpha
-// data (with or without a VP8X chunk) and the bitstream chunk (VP8/VP8L).
-// Note: The following chunk sequences (before the raw VP8/VP8L data) are
-// considered valid by this function:
-// RIFF + VP8(L)
-// RIFF + VP8X + (optional chunks) + VP8(L)
-// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
-// VP8(L)     <-- Not a valid WebP format: only allowed for internal purpose.
-static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
-                                          size_t data_size,
-                                          int* const width,
-                                          int* const height,
-                                          int* const has_alpha,
-                                          WebPHeaderStructure* const headers) {
-  int found_riff = 0;
-  int found_vp8x = 0;
-  VP8StatusCode status;
-  WebPHeaderStructure hdrs;
-
-  if (data == NULL || data_size < RIFF_HEADER_SIZE) {
-    return VP8_STATUS_NOT_ENOUGH_DATA;
-  }
-  memset(&hdrs, 0, sizeof(hdrs));
-  hdrs.data = data;
-  hdrs.data_size = data_size;
-
-  // Skip over RIFF header.
-  status = ParseRIFF(&data, &data_size, &hdrs.riff_size);
-  if (status != VP8_STATUS_OK) {
-    return status;   // Wrong RIFF header / insufficient data.
-  }
-  found_riff = (hdrs.riff_size > 0);
-
-  // Skip over VP8X.
-  {
-    uint32_t flags = 0;
-    status = ParseVP8X(&data, &data_size, &found_vp8x, width, height, &flags);
-    if (status != VP8_STATUS_OK) {
-      return status;  // Wrong VP8X / insufficient data.
-    }
-    if (!found_riff && found_vp8x) {
-      // Note: This restriction may be removed in the future, if it becomes
-      // necessary to send VP8X chunk to the decoder.
-      return VP8_STATUS_BITSTREAM_ERROR;
-    }
-    if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG_BIT);
-    if (found_vp8x && headers == NULL) {
-      return VP8_STATUS_OK;  // Return features from VP8X header.
-    }
-  }
-
-  if (data_size < TAG_SIZE) return VP8_STATUS_NOT_ENOUGH_DATA;
-
-  // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH".
-  if ((found_riff && found_vp8x) ||
-      (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) {
-    status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size,
-                                 &hdrs.alpha_data, &hdrs.alpha_data_size);
-    if (status != VP8_STATUS_OK) {
-      return status;  // Found an invalid chunk size / insufficient data.
-    }
-  }
-
-  // Skip over VP8/VP8L header.
-  status = ParseVP8Header(&data, &data_size, hdrs.riff_size,
-                          &hdrs.compressed_size, &hdrs.is_lossless);
-  if (status != VP8_STATUS_OK) {
-    return status;  // Wrong VP8/VP8L chunk-header / insufficient data.
-  }
-  if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) {
-    return VP8_STATUS_BITSTREAM_ERROR;
-  }
-
-  if (!hdrs.is_lossless) {
-    if (data_size < VP8_FRAME_HEADER_SIZE) {
-      return VP8_STATUS_NOT_ENOUGH_DATA;
-    }
-    // Validates raw VP8 data.
-    if (!VP8GetInfo(data, data_size,
-                    (uint32_t)hdrs.compressed_size, width, height)) {
-      return VP8_STATUS_BITSTREAM_ERROR;
-    }
-  } else {
-    if (data_size < VP8L_FRAME_HEADER_SIZE) {
-      return VP8_STATUS_NOT_ENOUGH_DATA;
-    }
-    // Validates raw VP8L data.
-    if (!VP8LGetInfo(data, data_size, width, height, has_alpha)) {
-      return VP8_STATUS_BITSTREAM_ERROR;
-    }
-  }
-
-  if (has_alpha != NULL) {
-    // If the data did not contain a VP8X/VP8L chunk the only definitive way
-    // to set this is by looking for alpha data (from an ALPH chunk).
-    *has_alpha |= (hdrs.alpha_data != NULL);
-  }
-  if (headers != NULL) {
-    *headers = hdrs;
-    headers->offset = data - headers->data;
-    assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD);
-    assert(headers->offset == headers->data_size - data_size);
-  }
-  return VP8_STATUS_OK;  // Return features from VP8 header.
-}
-
-VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
-  assert(headers != NULL);
-  // fill out headers, ignore width/height/has_alpha.
-  return ParseHeadersInternal(headers->data, headers->data_size,
-                              NULL, NULL, NULL, headers);
-}
-
-//------------------------------------------------------------------------------
-// WebPDecParams
-
-void WebPResetDecParams(WebPDecParams* const params) {
-  if (params) {
-    memset(params, 0, sizeof(*params));
-  }
-}
-
-//------------------------------------------------------------------------------
-// "Into" decoding variants
-
-// Main flow
-static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size,
-                                WebPDecParams* const params) {
-  VP8StatusCode status;
-  VP8Io io;
-  WebPHeaderStructure headers;
-
-  headers.data = data;
-  headers.data_size = data_size;
-  status = WebPParseHeaders(&headers);   // Process Pre-VP8 chunks.
-  if (status != VP8_STATUS_OK) {
-    return status;
-  }
-
-  assert(params != NULL);
-  VP8InitIo(&io);
-  io.data = headers.data + headers.offset;
-  io.data_size = headers.data_size - headers.offset;
-  WebPInitCustomIo(params, &io);  // Plug the I/O functions.
-
-  if (!headers.is_lossless) {
-    VP8Decoder* const dec = VP8New();
-    if (dec == NULL) {
-      return VP8_STATUS_OUT_OF_MEMORY;
-    }
-#ifdef WEBP_USE_THREAD
-    dec->use_threads_ = params->options && (params->options->use_threads > 0);
-#else
-    dec->use_threads_ = 0;
-#endif
-    dec->alpha_data_ = headers.alpha_data;
-    dec->alpha_data_size_ = headers.alpha_data_size;
-
-    // Decode bitstream header, update io->width/io->height.
-    if (!VP8GetHeaders(dec, &io)) {
-      status = dec->status_;   // An error occurred. Grab error status.
-    } else {
-      // Allocate/check output buffers.
-      status = WebPAllocateDecBuffer(io.width, io.height, params->options,
-                                     params->output);
-      if (status == VP8_STATUS_OK) {  // Decode
-        if (!VP8Decode(dec, &io)) {
-          status = dec->status_;
-        }
-      }
-    }
-    VP8Delete(dec);
-  } else {
-    VP8LDecoder* const dec = VP8LNew();
-    if (dec == NULL) {
-      return VP8_STATUS_OUT_OF_MEMORY;
-    }
-    if (!VP8LDecodeHeader(dec, &io)) {
-      status = dec->status_;   // An error occurred. Grab error status.
-    } else {
-      // Allocate/check output buffers.
-      status = WebPAllocateDecBuffer(io.width, io.height, params->options,
-                                     params->output);
-      if (status == VP8_STATUS_OK) {  // Decode
-        if (!VP8LDecodeImage(dec)) {
-          status = dec->status_;
-        }
-      }
-    }
-    VP8LDelete(dec);
-  }
-
-  if (status != VP8_STATUS_OK) {
-    WebPFreeDecBuffer(params->output);
-  }
-  return status;
-}
-
-// Helpers
-static uint8_t* DecodeIntoRGBABuffer(WEBP_CSP_MODE colorspace,
-                                     const uint8_t* const data,
-                                     size_t data_size,
-                                     uint8_t* const rgba,
-                                     int stride, size_t size) {
-  WebPDecParams params;
-  WebPDecBuffer buf;
-  if (rgba == NULL) {
-    return NULL;
-  }
-  WebPInitDecBuffer(&buf);
-  WebPResetDecParams(&params);
-  params.output = &buf;
-  buf.colorspace    = colorspace;
-  buf.u.RGBA.rgba   = rgba;
-  buf.u.RGBA.stride = stride;
-  buf.u.RGBA.size   = size;
-  buf.is_external_memory = 1;
-  if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
-    return NULL;
-  }
-  return rgba;
-}
-
-uint8_t* WebPDecodeRGBInto(const uint8_t* data, size_t data_size,
-                           uint8_t* output, size_t size, int stride) {
-  return DecodeIntoRGBABuffer(MODE_RGB, data, data_size, output, stride, size);
-}
-
-uint8_t* WebPDecodeRGBAInto(const uint8_t* data, size_t data_size,
-                            uint8_t* output, size_t size, int stride) {
-  return DecodeIntoRGBABuffer(MODE_RGBA, data, data_size, output, stride, size);
-}
-
-uint8_t* WebPDecodeARGBInto(const uint8_t* data, size_t data_size,
-                            uint8_t* output, size_t size, int stride) {
-  return DecodeIntoRGBABuffer(MODE_ARGB, data, data_size, output, stride, size);
-}
-
-uint8_t* WebPDecodeBGRInto(const uint8_t* data, size_t data_size,
-                           uint8_t* output, size_t size, int stride) {
-  return DecodeIntoRGBABuffer(MODE_BGR, data, data_size, output, stride, size);
-}
-
-uint8_t* WebPDecodeBGRAInto(const uint8_t* data, size_t data_size,
-                            uint8_t* output, size_t size, int stride) {
-  return DecodeIntoRGBABuffer(MODE_BGRA, data, data_size, output, stride, size);
-}
-
-uint8_t* WebPDecodeYUVInto(const uint8_t* data, size_t data_size,
-                           uint8_t* luma, size_t luma_size, int luma_stride,
-                           uint8_t* u, size_t u_size, int u_stride,
-                           uint8_t* v, size_t v_size, int v_stride) {
-  WebPDecParams params;
-  WebPDecBuffer output;
-  if (luma == NULL) return NULL;
-  WebPInitDecBuffer(&output);
-  WebPResetDecParams(&params);
-  params.output = &output;
-  output.colorspace      = MODE_YUV;
-  output.u.YUVA.y        = luma;
-  output.u.YUVA.y_stride = luma_stride;
-  output.u.YUVA.y_size   = luma_size;
-  output.u.YUVA.u        = u;
-  output.u.YUVA.u_stride = u_stride;
-  output.u.YUVA.u_size   = u_size;
-  output.u.YUVA.v        = v;
-  output.u.YUVA.v_stride = v_stride;
-  output.u.YUVA.v_size   = v_size;
-  output.is_external_memory = 1;
-  if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
-    return NULL;
-  }
-  return luma;
-}
-
-//------------------------------------------------------------------------------
-
-static uint8_t* Decode(WEBP_CSP_MODE mode, const uint8_t* const data,
-                       size_t data_size, int* const width, int* const height,
-                       WebPDecBuffer* const keep_info) {
-  WebPDecParams params;
-  WebPDecBuffer output;
-
-  WebPInitDecBuffer(&output);
-  WebPResetDecParams(&params);
-  params.output = &output;
-  output.colorspace = mode;
-
-  // Retrieve (and report back) the required dimensions from bitstream.
-  if (!WebPGetInfo(data, data_size, &output.width, &output.height)) {
-    return NULL;
-  }
-  if (width != NULL) *width = output.width;
-  if (height != NULL) *height = output.height;
-
-  // Decode
-  if (DecodeInto(data, data_size, &params) != VP8_STATUS_OK) {
-    return NULL;
-  }
-  if (keep_info != NULL) {    // keep track of the side-info
-    WebPCopyDecBuffer(&output, keep_info);
-  }
-  // return decoded samples (don't clear 'output'!)
-  return WebPIsRGBMode(mode) ? output.u.RGBA.rgba : output.u.YUVA.y;
-}
-
-uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
-                       int* width, int* height) {
-  return Decode(MODE_RGB, data, data_size, width, height, NULL);
-}
-
-uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
-                        int* width, int* height) {
-  return Decode(MODE_RGBA, data, data_size, width, height, NULL);
-}
-
-uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
-                        int* width, int* height) {
-  return Decode(MODE_ARGB, data, data_size, width, height, NULL);
-}
-
-uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
-                       int* width, int* height) {
-  return Decode(MODE_BGR, data, data_size, width, height, NULL);
-}
-
-uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
-                        int* width, int* height) {
-  return Decode(MODE_BGRA, data, data_size, width, height, NULL);
-}
-
-uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
-                       int* width, int* height, uint8_t** u, uint8_t** v,
-                       int* stride, int* uv_stride) {
-  WebPDecBuffer output;   // only to preserve the side-infos
-  uint8_t* const out = Decode(MODE_YUV, data, data_size,
-                              width, height, &output);
-
-  if (out != NULL) {
-    const WebPYUVABuffer* const buf = &output.u.YUVA;
-    *u = buf->u;
-    *v = buf->v;
-    *stride = buf->y_stride;
-    *uv_stride = buf->u_stride;
-    assert(buf->u_stride == buf->v_stride);
-  }
-  return out;
-}
-
-static void DefaultFeatures(WebPBitstreamFeatures* const features) {
-  assert(features != NULL);
-  memset(features, 0, sizeof(*features));
-  features->bitstream_version = 0;
-}
-
-static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size,
-                                 WebPBitstreamFeatures* const features) {
-  if (features == NULL || data == NULL) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-  DefaultFeatures(features);
-
-  // Only parse enough of the data to retrieve width/height/has_alpha.
-  return ParseHeadersInternal(data, data_size,
-                              &features->width, &features->height,
-                              &features->has_alpha, NULL);
-}
-
-//------------------------------------------------------------------------------
-// WebPGetInfo()
-
-int WebPGetInfo(const uint8_t* data, size_t data_size,
-                int* width, int* height) {
-  WebPBitstreamFeatures features;
-
-  if (GetFeatures(data, data_size, &features) != VP8_STATUS_OK) {
-    return 0;
-  }
-
-  if (width != NULL) {
-    *width  = features.width;
-  }
-  if (height != NULL) {
-    *height = features.height;
-  }
-
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Advance decoding API
-
-int WebPInitDecoderConfigInternal(WebPDecoderConfig* config,
-                                  int version) {
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
-    return 0;   // version mismatch
-  }
-  if (config == NULL) {
-    return 0;
-  }
-  memset(config, 0, sizeof(*config));
-  DefaultFeatures(&config->input);
-  WebPInitDecBuffer(&config->output);
-  return 1;
-}
-
-VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size,
-                                      WebPBitstreamFeatures* features,
-                                      int version) {
-  VP8StatusCode status;
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
-    return VP8_STATUS_INVALID_PARAM;   // version mismatch
-  }
-  if (features == NULL) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-
-  status = GetFeatures(data, data_size, features);
-  if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
-    return VP8_STATUS_BITSTREAM_ERROR;  // Not-enough-data treated as error.
-  }
-  return status;
-}
-
-VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
-                         WebPDecoderConfig* config) {
-  WebPDecParams params;
-  VP8StatusCode status;
-
-  if (config == NULL) {
-    return VP8_STATUS_INVALID_PARAM;
-  }
-
-  status = GetFeatures(data, data_size, &config->input);
-  if (status != VP8_STATUS_OK) {
-    if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
-      return VP8_STATUS_BITSTREAM_ERROR;  // Not-enough-data treated as error.
-    }
-    return status;
-  }
-
-  WebPResetDecParams(&params);
-  params.output = &config->output;
-  params.options = &config->options;
-  status = DecodeInto(data, data_size, &params);
-
-  return status;
-}
-
-//------------------------------------------------------------------------------
-// Cropping and rescaling.
-
-int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
-                          VP8Io* const io, WEBP_CSP_MODE src_colorspace) {
-  const int W = io->width;
-  const int H = io->height;
-  int x = 0, y = 0, w = W, h = H;
-
-  // Cropping
-  io->use_cropping = (options != NULL) && (options->use_cropping > 0);
-  if (io->use_cropping) {
-    w = options->crop_width;
-    h = options->crop_height;
-    x = options->crop_left;
-    y = options->crop_top;
-    if (!WebPIsRGBMode(src_colorspace)) {   // only snap for YUV420 or YUV422
-      x &= ~1;
-      y &= ~1;    // TODO(later): only for YUV420, not YUV422.
-    }
-    if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) {
-      return 0;  // out of frame boundary error
-    }
-  }
-  io->crop_left   = x;
-  io->crop_top    = y;
-  io->crop_right  = x + w;
-  io->crop_bottom = y + h;
-  io->mb_w = w;
-  io->mb_h = h;
-
-  // Scaling
-  io->use_scaling = (options != NULL) && (options->use_scaling > 0);
-  if (io->use_scaling) {
-    if (options->scaled_width <= 0 || options->scaled_height <= 0) {
-      return 0;
-    }
-    io->scaled_width = options->scaled_width;
-    io->scaled_height = options->scaled_height;
-  }
-
-  // Filter
-  io->bypass_filtering = options && options->bypass_filtering;
-
-  // Fancy upsampler
-#ifdef FANCY_UPSAMPLING
-  io->fancy_upsampling = (options == NULL) || (!options->no_fancy_upsampling);
-#endif
-
-  if (io->use_scaling) {
-    // disable filter (only for large downscaling ratio).
-    io->bypass_filtering = (io->scaled_width < W * 3 / 4) &&
-                           (io->scaled_height < H * 3 / 4);
-    io->fancy_upsampling = 0;
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 114
drivers/webpold/dec/webpi.h

@@ -1,114 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Internal header: WebP decoding parameters and custom IO on buffer
-//
-// Author: [email protected] (Somnath Banerjee)
-
-#ifndef WEBP_DEC_WEBPI_H_
-#define WEBP_DEC_WEBPI_H_
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include "../utils/rescaler.h"
-#include "./decode_vp8.h"
-
-//------------------------------------------------------------------------------
-// WebPDecParams: Decoding output parameters. Transient internal object.
-
-typedef struct WebPDecParams WebPDecParams;
-typedef int (*OutputFunc)(const VP8Io* const io, WebPDecParams* const p);
-typedef int (*OutputRowFunc)(WebPDecParams* const p, int y_pos);
-
-struct WebPDecParams {
-  WebPDecBuffer* output;             // output buffer.
-  uint8_t* tmp_y, *tmp_u, *tmp_v;    // cache for the fancy upsampler
-                                     // or used for tmp rescaling
-
-  int last_y;                 // coordinate of the line that was last output
-  const WebPDecoderOptions* options;  // if not NULL, use alt decoding features
-  // rescalers
-  WebPRescaler scaler_y, scaler_u, scaler_v, scaler_a;
-  void* memory;                  // overall scratch memory for the output work.
-
-  OutputFunc emit;               // output RGB or YUV samples
-  OutputFunc emit_alpha;         // output alpha channel
-  OutputRowFunc emit_alpha_row;  // output one line of rescaled alpha values
-};
-
-// Should be called first, before any use of the WebPDecParams object.
-void WebPResetDecParams(WebPDecParams* const params);
-
-//------------------------------------------------------------------------------
-// Header parsing helpers
-
-// Structure storing a description of the RIFF headers.
-typedef struct {
-  const uint8_t* data;         // input buffer
-  size_t data_size;            // input buffer size
-  size_t offset;               // offset to main data chunk (VP8 or VP8L)
-  const uint8_t* alpha_data;   // points to alpha chunk (if present)
-  size_t alpha_data_size;      // alpha chunk size
-  size_t compressed_size;      // VP8/VP8L compressed data size
-  size_t riff_size;            // size of the riff payload (or 0 if absent)
-  int is_lossless;             // true if a VP8L chunk is present
-} WebPHeaderStructure;
-
-// Skips over all valid chunks prior to the first VP8/VP8L frame header.
-// Returns VP8_STATUS_OK on success,
-//         VP8_STATUS_BITSTREAM_ERROR if an invalid header/chunk is found, and
-//         VP8_STATUS_NOT_ENOUGH_DATA if case of insufficient data.
-// In 'headers', compressed_size, offset, alpha_data, alpha_size and lossless
-// fields are updated appropriately upon success.
-VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers);
-
-//------------------------------------------------------------------------------
-// Misc utils
-
-// Initializes VP8Io with custom setup, io and teardown functions. The default
-// hooks will use the supplied 'params' as io->opaque handle.
-void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
-
-// Setup crop_xxx fields, mb_w and mb_h in io. 'src_colorspace' refers
-// to the *compressed* format, not the output one.
-int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
-                          VP8Io* const io, WEBP_CSP_MODE src_colorspace);
-
-//------------------------------------------------------------------------------
-// Internal functions regarding WebPDecBuffer memory (in buffer.c).
-// Don't really need to be externally visible for now.
-
-// Prepare 'buffer' with the requested initial dimensions width/height.
-// If no external storage is supplied, initializes buffer by allocating output
-// memory and setting up the stride information. Validate the parameters. Return
-// an error code in case of problem (no memory, or invalid stride / size /
-// dimension / etc.). If *options is not NULL, also verify that the options'
-// parameters are valid and apply them to the width/height dimensions of the
-// output buffer. This takes cropping / scaling / rotation into account.
-VP8StatusCode WebPAllocateDecBuffer(int width, int height,
-                                    const WebPDecoderOptions* const options,
-                                    WebPDecBuffer* const buffer);
-
-// Copy 'src' into 'dst' buffer, making sure 'dst' is not marked as owner of the
-// memory (still held by 'src').
-void WebPCopyDecBuffer(const WebPDecBuffer* const src,
-                       WebPDecBuffer* const dst);
-
-// Copy and transfer ownership from src to dst (beware of parameter order!)
-void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst);
-
-
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_DEC_WEBPI_H_ */

+ 0 - 454
drivers/webpold/decode.h

@@ -1,454 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//  Main decoding functions for WebP images.
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_WEBP_DECODE_H_
-#define WEBP_WEBP_DECODE_H_
-
-#include "./types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define WEBP_DECODER_ABI_VERSION 0x0200    // MAJOR(8b) + MINOR(8b)
-
-// Return the decoder's version number, packed in hexadecimal using 8bits for
-// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
-WEBP_EXTERN(int) WebPGetDecoderVersion(void);
-
-// Retrieve basic header information: width, height.
-// This function will also validate the header and return 0 in
-// case of formatting error.
-// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
-WEBP_EXTERN(int) WebPGetInfo(const uint8_t* data, size_t data_size,
-                             int* width, int* height);
-
-// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
-// with the dimensions in *width and *height. The ordering of samples in
-// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
-// The returned pointer should be deleted calling free().
-// Returns NULL in case of error.
-WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size,
-                                     int* width, int* height);
-
-// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
-WEBP_EXTERN(uint8_t*) WebPDecodeARGB(const uint8_t* data, size_t data_size,
-                                     int* width, int* height);
-
-// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
-WEBP_EXTERN(uint8_t*) WebPDecodeBGRA(const uint8_t* data, size_t data_size,
-                                     int* width, int* height);
-
-// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
-// If the bitstream contains transparency, it is ignored.
-WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size,
-                                    int* width, int* height);
-
-// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
-WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size,
-                                    int* width, int* height);
-
-
-// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
-// returned is the Y samples buffer. Upon return, *u and *v will point to
-// the U and V chroma data. These U and V buffers need NOT be free()'d,
-// unlike the returned Y luma one. The dimension of the U and V planes
-// are both (*width + 1) / 2 and (*height + 1)/ 2.
-// Upon return, the Y buffer has a stride returned as '*stride', while U and V
-// have a common stride returned as '*uv_stride'.
-// Return NULL in case of error.
-// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
-WEBP_EXTERN(uint8_t*) WebPDecodeYUV(const uint8_t* data, size_t data_size,
-                                    int* width, int* height,
-                                    uint8_t** u, uint8_t** v,
-                                    int* stride, int* uv_stride);
-
-// These five functions are variants of the above ones, that decode the image
-// directly into a pre-allocated buffer 'output_buffer'. The maximum storage
-// available in this buffer is indicated by 'output_buffer_size'. If this
-// storage is not sufficient (or an error occurred), NULL is returned.
-// Otherwise, output_buffer is returned, for convenience.
-// The parameter 'output_stride' specifies the distance (in bytes)
-// between scanlines. Hence, output_buffer_size is expected to be at least
-// output_stride x picture-height.
-WEBP_EXTERN(uint8_t*) WebPDecodeRGBAInto(
-    const uint8_t* data, size_t data_size,
-    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
-WEBP_EXTERN(uint8_t*) WebPDecodeARGBInto(
-    const uint8_t* data, size_t data_size,
-    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
-WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto(
-    const uint8_t* data, size_t data_size,
-    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
-
-// RGB and BGR variants. Here too the transparency information, if present,
-// will be dropped and ignored.
-WEBP_EXTERN(uint8_t*) WebPDecodeRGBInto(
-    const uint8_t* data, size_t data_size,
-    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
-WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto(
-    const uint8_t* data, size_t data_size,
-    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
-
-// WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
-// into pre-allocated luma/chroma plane buffers. This function requires the
-// strides to be passed: one for the luma plane and one for each of the
-// chroma ones. The size of each plane buffer is passed as 'luma_size',
-// 'u_size' and 'v_size' respectively.
-// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
-// during decoding (or because some buffers were found to be too small).
-WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto(
-    const uint8_t* data, size_t data_size,
-    uint8_t* luma, size_t luma_size, int luma_stride,
-    uint8_t* u, size_t u_size, int u_stride,
-    uint8_t* v, size_t v_size, int v_stride);
-
-//------------------------------------------------------------------------------
-// Output colorspaces and buffer
-
-// Colorspaces
-// Note: the naming describes the byte-ordering of packed samples in memory.
-// For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
-// Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
-// RGB-565 and RGBA-4444 are also endian-agnostic and byte-oriented.
-typedef enum { MODE_RGB = 0, MODE_RGBA = 1,
-               MODE_BGR = 2, MODE_BGRA = 3,
-               MODE_ARGB = 4, MODE_RGBA_4444 = 5,
-               MODE_RGB_565 = 6,
-               // RGB-premultiplied transparent modes (alpha value is preserved)
-               MODE_rgbA = 7,
-               MODE_bgrA = 8,
-               MODE_Argb = 9,
-               MODE_rgbA_4444 = 10,
-               // YUV modes must come after RGB ones.
-               MODE_YUV = 11, MODE_YUVA = 12,  // yuv 4:2:0
-               MODE_LAST = 13
-             } WEBP_CSP_MODE;
-
-// Some useful macros:
-static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) {
-  return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb ||
-          mode == MODE_rgbA_4444);
-}
-
-static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) {
-  return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
-          mode == MODE_RGBA_4444 || mode == MODE_YUVA ||
-          WebPIsPremultipliedMode(mode));
-}
-
-static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
-  return (mode < MODE_YUV);
-}
-
-//------------------------------------------------------------------------------
-// WebPDecBuffer: Generic structure for describing the output sample buffer.
-
-typedef struct {    // view as RGBA
-  uint8_t* rgba;    // pointer to RGBA samples
-  int stride;       // stride in bytes from one scanline to the next.
-  size_t size;      // total size of the *rgba buffer.
-} WebPRGBABuffer;
-
-typedef struct {              // view as YUVA
-  uint8_t* y, *u, *v, *a;     // pointer to luma, chroma U/V, alpha samples
-  int y_stride;               // luma stride
-  int u_stride, v_stride;     // chroma strides
-  int a_stride;               // alpha stride
-  size_t y_size;              // luma plane size
-  size_t u_size, v_size;      // chroma planes size
-  size_t a_size;              // alpha-plane size
-} WebPYUVABuffer;
-
-// Output buffer
-typedef struct {
-  WEBP_CSP_MODE colorspace;  // Colorspace.
-  int width, height;         // Dimensions.
-  int is_external_memory;    // If true, 'internal_memory' pointer is not used.
-  union {
-    WebPRGBABuffer RGBA;
-    WebPYUVABuffer YUVA;
-  } u;                       // Nameless union of buffer parameters.
-  uint32_t       pad[4];     // padding for later use
-
-  uint8_t* private_memory;   // Internally allocated memory (only when
-                             // is_external_memory is false). Should not be used
-                             // externally, but accessed via the buffer union.
-} WebPDecBuffer;
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer*, int);
-
-// Initialize the structure as empty. Must be called before any other use.
-// Returns false in case of version mismatch
-static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
-  return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
-}
-
-// Free any memory associated with the buffer. Must always be called last.
-// Note: doesn't free the 'buffer' structure itself.
-WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer);
-
-//------------------------------------------------------------------------------
-// Enumeration of the status codes
-
-typedef enum {
-  VP8_STATUS_OK = 0,
-  VP8_STATUS_OUT_OF_MEMORY,
-  VP8_STATUS_INVALID_PARAM,
-  VP8_STATUS_BITSTREAM_ERROR,
-  VP8_STATUS_UNSUPPORTED_FEATURE,
-  VP8_STATUS_SUSPENDED,
-  VP8_STATUS_USER_ABORT,
-  VP8_STATUS_NOT_ENOUGH_DATA
-} VP8StatusCode;
-
-//------------------------------------------------------------------------------
-// Incremental decoding
-//
-// This API allows streamlined decoding of partial data.
-// Picture can be incrementally decoded as data become available thanks to the
-// WebPIDecoder object. This object can be left in a SUSPENDED state if the
-// picture is only partially decoded, pending additional input.
-// Code example:
-//
-//   WebPInitDecBuffer(&buffer);
-//   buffer.colorspace = mode;
-//   ...
-//   WebPIDecoder* idec = WebPINewDecoder(&buffer);
-//   while (has_more_data) {
-//     // ... (get additional data)
-//     status = WebPIAppend(idec, new_data, new_data_size);
-//     if (status != VP8_STATUS_SUSPENDED ||
-//       break;
-//     }
-//
-//     // The above call decodes the current available buffer.
-//     // Part of the image can now be refreshed by calling to
-//     // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
-//   }
-//   WebPIDelete(idec);
-
-typedef struct WebPIDecoder WebPIDecoder;
-
-// Creates a new incremental decoder with the supplied buffer parameter.
-// This output_buffer can be passed NULL, in which case a default output buffer
-// is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
-// is kept, which means that the lifespan of 'output_buffer' must be larger than
-// that of the returned WebPIDecoder object.
-// Returns NULL if the allocation failed.
-WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer);
-
-// This function allocates and initializes an incremental-decoder object, which
-// will output the RGB/A samples specified by 'csp' into a preallocated
-// buffer 'output_buffer'. The size of this buffer is at least
-// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
-// is specified by 'output_stride'. Returns NULL if the allocation failed.
-WEBP_EXTERN(WebPIDecoder*) WebPINewRGB(
-    WEBP_CSP_MODE csp,
-    uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
-
-// This function allocates and initializes an incremental-decoder object, which
-// will output the raw luma/chroma samples into a preallocated planes. The luma
-// plane is specified by its pointer 'luma', its size 'luma_size' and its stride
-// 'luma_stride'. Similarly, the chroma-u plane is specified by the 'u',
-// 'u_size' and 'u_stride' parameters, and the chroma-v plane by 'v'
-// and 'v_size'. And same for the alpha-plane. The 'a' pointer can be pass
-// NULL in case one is not interested in the transparency plane.
-// Returns NULL if the allocation failed.
-WEBP_EXTERN(WebPIDecoder*) WebPINewYUVA(
-    uint8_t* luma, size_t luma_size, int luma_stride,
-    uint8_t* u, size_t u_size, int u_stride,
-    uint8_t* v, size_t v_size, int v_stride,
-    uint8_t* a, size_t a_size, int a_stride);
-
-// Deprecated version of the above, without the alpha plane.
-// Kept for backward compatibility.
-WEBP_EXTERN(WebPIDecoder*) WebPINewYUV(
-    uint8_t* luma, size_t luma_size, int luma_stride,
-    uint8_t* u, size_t u_size, int u_stride,
-    uint8_t* v, size_t v_size, int v_stride);
-
-// Deletes the WebPIDecoder object and associated memory. Must always be called
-// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
-WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec);
-
-// Copies and decodes the next available data. Returns VP8_STATUS_OK when
-// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
-// data is expected. Returns error in other cases.
-WEBP_EXTERN(VP8StatusCode) WebPIAppend(
-    WebPIDecoder* idec, const uint8_t* data, size_t data_size);
-
-// A variant of the above function to be used when data buffer contains
-// partial data from the beginning. In this case data buffer is not copied
-// to the internal memory.
-// Note that the value of the 'data' pointer can change between calls to
-// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
-WEBP_EXTERN(VP8StatusCode) WebPIUpdate(
-    WebPIDecoder* idec, const uint8_t* data, size_t data_size);
-
-// Returns the RGB/A image decoded so far. Returns NULL if output params
-// are not initialized yet. The RGB/A output type corresponds to the colorspace
-// specified during call to WebPINewDecoder() or WebPINewRGB().
-// *last_y is the index of last decoded row in raster scan order. Some pointers
-// (*last_y, *width etc.) can be NULL if corresponding information is not
-// needed.
-WEBP_EXTERN(uint8_t*) WebPIDecGetRGB(
-    const WebPIDecoder* idec, int* last_y,
-    int* width, int* height, int* stride);
-
-// Same as above function to get a YUVA image. Returns pointer to the luma
-// plane or NULL in case of error. If there is no alpha information
-// the alpha pointer '*a' will be returned NULL.
-WEBP_EXTERN(uint8_t*) WebPIDecGetYUVA(
-    const WebPIDecoder* idec, int* last_y,
-    uint8_t** u, uint8_t** v, uint8_t** a,
-    int* width, int* height, int* stride, int* uv_stride, int* a_stride);
-
-// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
-// alpha information (if present). Kept for backward compatibility.
-static WEBP_INLINE uint8_t* WebPIDecGetYUV(
-    const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
-    int* width, int* height, int* stride, int* uv_stride) {
-  return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
-                         stride, uv_stride, NULL);
-}
-
-// Generic call to retrieve information about the displayable area.
-// If non NULL, the left/right/width/height pointers are filled with the visible
-// rectangular area so far.
-// Returns NULL in case the incremental decoder object is in an invalid state.
-// Otherwise returns the pointer to the internal representation. This structure
-// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
-WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea(
-    const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
-
-//------------------------------------------------------------------------------
-// Advanced decoding parametrization
-//
-//  Code sample for using the advanced decoding API
-/*
-     // A) Init a configuration object
-     WebPDecoderConfig config;
-     CHECK(WebPInitDecoderConfig(&config));
-
-     // B) optional: retrieve the bitstream's features.
-     CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
-
-     // C) Adjust 'config', if needed
-     config.no_fancy = 1;
-     config.output.colorspace = MODE_BGRA;
-     // etc.
-
-     // Note that you can also make config.output point to an externally
-     // supplied memory buffer, provided it's big enough to store the decoded
-     // picture. Otherwise, config.output will just be used to allocate memory
-     // and store the decoded picture.
-
-     // D) Decode!
-     CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
-
-     // E) Decoded image is now in config.output (and config.output.u.RGBA)
-
-     // F) Reclaim memory allocated in config's object. It's safe to call
-     // this function even if the memory is external and wasn't allocated
-     // by WebPDecode().
-     WebPFreeDecBuffer(&config.output);
-*/
-
-// Features gathered from the bitstream
-typedef struct {
-  int width;        // Width in pixels, as read from the bitstream.
-  int height;       // Height in pixels, as read from the bitstream.
-  int has_alpha;    // True if the bitstream contains an alpha channel.
-
-  // Unused for now:
-  int bitstream_version;        // should be 0 for now. TODO(later)
-  int no_incremental_decoding;  // if true, using incremental decoding is not
-                                // recommended.
-  int rotate;                   // TODO(later)
-  int uv_sampling;              // should be 0 for now. TODO(later)
-  uint32_t pad[3];              // padding for later use
-} WebPBitstreamFeatures;
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal(
-    const uint8_t*, size_t, WebPBitstreamFeatures*, int);
-
-// Retrieve features from the bitstream. The *features structure is filled
-// with information gathered from the bitstream.
-// Returns false in case of error or version mismatch.
-// In case of error, features->bitstream_status will reflect the error code.
-static WEBP_INLINE VP8StatusCode WebPGetFeatures(
-    const uint8_t* data, size_t data_size,
-    WebPBitstreamFeatures* features) {
-  return WebPGetFeaturesInternal(data, data_size, features,
-                                 WEBP_DECODER_ABI_VERSION);
-}
-
-// Decoding options
-typedef struct {
-  int bypass_filtering;               // if true, skip the in-loop filtering
-  int no_fancy_upsampling;            // if true, use faster pointwise upsampler
-  int use_cropping;                   // if true, cropping is applied _first_
-  int crop_left, crop_top;            // top-left position for cropping.
-                                      // Will be snapped to even values.
-  int crop_width, crop_height;        // dimension of the cropping area
-  int use_scaling;                    // if true, scaling is applied _afterward_
-  int scaled_width, scaled_height;    // final resolution
-  int use_threads;                    // if true, use multi-threaded decoding
-
-  // Unused for now:
-  int force_rotation;                 // forced rotation (to be applied _last_)
-  int no_enhancement;                 // if true, discard enhancement layer
-  uint32_t pad[6];                    // padding for later use
-} WebPDecoderOptions;
-
-// Main object storing the configuration for advanced decoding.
-typedef struct {
-  WebPBitstreamFeatures input;  // Immutable bitstream features (optional)
-  WebPDecBuffer output;         // Output buffer (can point to external mem)
-  WebPDecoderOptions options;   // Decoding options
-} WebPDecoderConfig;
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
-
-// Initialize the configuration as empty. This function must always be
-// called first, unless WebPGetFeatures() is to be called.
-// Returns false in case of mismatched version.
-static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
-  return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
-}
-
-// Instantiate a new incremental decoder object with the requested
-// configuration. The bitstream can be passed using 'data' and 'data_size'
-// parameter, in which case the features will be parsed and stored into
-// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
-// Note that 'config' can be NULL too, in which case a default configuration
-// is used.
-// The return WebPIDecoder object must always be deleted calling WebPIDelete().
-// Returns NULL in case of error (and config->status will then reflect
-// the error condition).
-WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size,
-                                       WebPDecoderConfig* config);
-
-// Non-incremental version. This version decodes the full data at once, taking
-// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
-// if the decoding was successful).
-WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size,
-                                      WebPDecoderConfig* config);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_WEBP_DECODE_H_ */

+ 0 - 85
drivers/webpold/dsp/cpu.c

@@ -1,85 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// CPU detection
-//
-// Author: Christian Duvivier ([email protected])
-
-#include "./dsp.h"
-
-#if defined(__ANDROID__)
-#include <cpu-features.h>
-#endif
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// SSE2 detection.
-//
-
-// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
-#if (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
-static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
-  __asm__ volatile (
-    "mov %%ebx, %%edi\n"
-    "cpuid\n"
-    "xchg %%edi, %%ebx\n"
-    : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
-    : "a"(info_type));
-}
-#elif defined(__i386__) || defined(__x86_64__)
-static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
-  __asm__ volatile (
-    "cpuid\n"
-    : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
-    : "a"(info_type));
-}
-#elif defined(WEBP_MSC_SSE2)
-#define GetCPUInfo __cpuid
-#endif
-
-#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
-static int x86CPUInfo(CPUFeature feature) {
-  int cpu_info[4];
-  GetCPUInfo(cpu_info, 1);
-  if (feature == kSSE2) {
-    return 0 != (cpu_info[3] & 0x04000000);
-  }
-  if (feature == kSSE3) {
-    return 0 != (cpu_info[2] & 0x00000001);
-  }
-  return 0;
-}
-VP8CPUInfo VP8GetCPUInfo = x86CPUInfo;
-#elif defined(WEBP_ANDROID_NEON)
-static int AndroidCPUInfo(CPUFeature feature) {
-  const AndroidCpuFamily cpu_family = android_getCpuFamily();
-  const uint64_t cpu_features = android_getCpuFeatures();
-  if (feature == kNEON) {
-    return (cpu_family == ANDROID_CPU_FAMILY_ARM &&
-            0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON));
-  }
-  return 0;
-}
-VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
-#elif defined(__ARM_NEON__)
-// define a dummy function to enable turning off NEON at runtime by setting
-// VP8DecGetCPUInfo = NULL
-static int armCPUInfo(CPUFeature feature) {
-  (void)feature;
-  return 1;
-}
-VP8CPUInfo VP8GetCPUInfo = armCPUInfo;
-#else
-VP8CPUInfo VP8GetCPUInfo = NULL;
-#endif
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 732
drivers/webpold/dsp/dec.c

@@ -1,732 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Speed-critical decoding functions.
-//
-// Author: Skal ([email protected])
-
-#include "./dsp.h"
-#include "../dec/vp8i.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// run-time tables (~4k)
-
-static uint8_t abs0[255 + 255 + 1];     // abs(i)
-static uint8_t abs1[255 + 255 + 1];     // abs(i)>>1
-static int8_t sclip1[1020 + 1020 + 1];  // clips [-1020, 1020] to [-128, 127]
-static int8_t sclip2[112 + 112 + 1];    // clips [-112, 112] to [-16, 15]
-static uint8_t clip1[255 + 510 + 1];    // clips [-255,510] to [0,255]
-
-// We declare this variable 'volatile' to prevent instruction reordering
-// and make sure it's set to true _last_ (so as to be thread-safe)
-static volatile int tables_ok = 0;
-
-static void DspInitTables(void) {
-  if (!tables_ok) {
-    int i;
-    for (i = -255; i <= 255; ++i) {
-      abs0[255 + i] = (i < 0) ? -i : i;
-      abs1[255 + i] = abs0[255 + i] >> 1;
-    }
-    for (i = -1020; i <= 1020; ++i) {
-      sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i;
-    }
-    for (i = -112; i <= 112; ++i) {
-      sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i;
-    }
-    for (i = -255; i <= 255 + 255; ++i) {
-      clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
-    }
-    tables_ok = 1;
-  }
-}
-
-static WEBP_INLINE uint8_t clip_8b(int v) {
-  return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
-}
-
-//------------------------------------------------------------------------------
-// Transforms (Paragraph 14.4)
-
-#define STORE(x, y, v) \
-  dst[x + y * BPS] = clip_8b(dst[x + y * BPS] + ((v) >> 3))
-
-static const int kC1 = 20091 + (1 << 16);
-static const int kC2 = 35468;
-#define MUL(a, b) (((a) * (b)) >> 16)
-
-static void TransformOne(const int16_t* in, uint8_t* dst) {
-  int C[4 * 4], *tmp;
-  int i;
-  tmp = C;
-  for (i = 0; i < 4; ++i) {    // vertical pass
-    const int a = in[0] + in[8];    // [-4096, 4094]
-    const int b = in[0] - in[8];    // [-4095, 4095]
-    const int c = MUL(in[4], kC2) - MUL(in[12], kC1);   // [-3783, 3783]
-    const int d = MUL(in[4], kC1) + MUL(in[12], kC2);   // [-3785, 3781]
-    tmp[0] = a + d;   // [-7881, 7875]
-    tmp[1] = b + c;   // [-7878, 7878]
-    tmp[2] = b - c;   // [-7878, 7878]
-    tmp[3] = a - d;   // [-7877, 7879]
-    tmp += 4;
-    in++;
-  }
-  // Each pass is expanding the dynamic range by ~3.85 (upper bound).
-  // The exact value is (2. + (kC1 + kC2) / 65536).
-  // After the second pass, maximum interval is [-3794, 3794], assuming
-  // an input in [-2048, 2047] interval. We then need to add a dst value
-  // in the [0, 255] range.
-  // In the worst case scenario, the input to clip_8b() can be as large as
-  // [-60713, 60968].
-  tmp = C;
-  for (i = 0; i < 4; ++i) {    // horizontal pass
-    const int dc = tmp[0] + 4;
-    const int a =  dc +  tmp[8];
-    const int b =  dc -  tmp[8];
-    const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1);
-    const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2);
-    STORE(0, 0, a + d);
-    STORE(1, 0, b + c);
-    STORE(2, 0, b - c);
-    STORE(3, 0, a - d);
-    tmp++;
-    dst += BPS;
-  }
-}
-#undef MUL
-
-static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
-  TransformOne(in, dst);
-  if (do_two) {
-    TransformOne(in + 16, dst + 4);
-  }
-}
-
-static void TransformUV(const int16_t* in, uint8_t* dst) {
-  VP8Transform(in + 0 * 16, dst, 1);
-  VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
-}
-
-static void TransformDC(const int16_t *in, uint8_t* dst) {
-  const int DC = in[0] + 4;
-  int i, j;
-  for (j = 0; j < 4; ++j) {
-    for (i = 0; i < 4; ++i) {
-      STORE(i, j, DC);
-    }
-  }
-}
-
-static void TransformDCUV(const int16_t* in, uint8_t* dst) {
-  if (in[0 * 16]) TransformDC(in + 0 * 16, dst);
-  if (in[1 * 16]) TransformDC(in + 1 * 16, dst + 4);
-  if (in[2 * 16]) TransformDC(in + 2 * 16, dst + 4 * BPS);
-  if (in[3 * 16]) TransformDC(in + 3 * 16, dst + 4 * BPS + 4);
-}
-
-#undef STORE
-
-//------------------------------------------------------------------------------
-// Paragraph 14.3
-
-static void TransformWHT(const int16_t* in, int16_t* out) {
-  int tmp[16];
-  int i;
-  for (i = 0; i < 4; ++i) {
-    const int a0 = in[0 + i] + in[12 + i];
-    const int a1 = in[4 + i] + in[ 8 + i];
-    const int a2 = in[4 + i] - in[ 8 + i];
-    const int a3 = in[0 + i] - in[12 + i];
-    tmp[0  + i] = a0 + a1;
-    tmp[8  + i] = a0 - a1;
-    tmp[4  + i] = a3 + a2;
-    tmp[12 + i] = a3 - a2;
-  }
-  for (i = 0; i < 4; ++i) {
-    const int dc = tmp[0 + i * 4] + 3;    // w/ rounder
-    const int a0 = dc             + tmp[3 + i * 4];
-    const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4];
-    const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4];
-    const int a3 = dc             - tmp[3 + i * 4];
-    out[ 0] = (a0 + a1) >> 3;
-    out[16] = (a3 + a2) >> 3;
-    out[32] = (a0 - a1) >> 3;
-    out[48] = (a3 - a2) >> 3;
-    out += 64;
-  }
-}
-
-void (*VP8TransformWHT)(const int16_t* in, int16_t* out) = TransformWHT;
-
-//------------------------------------------------------------------------------
-// Intra predictions
-
-#define DST(x, y) dst[(x) + (y) * BPS]
-
-static WEBP_INLINE void TrueMotion(uint8_t *dst, int size) {
-  const uint8_t* top = dst - BPS;
-  const uint8_t* const clip0 = clip1 + 255 - top[-1];
-  int y;
-  for (y = 0; y < size; ++y) {
-    const uint8_t* const clip = clip0 + dst[-1];
-    int x;
-    for (x = 0; x < size; ++x) {
-      dst[x] = clip[top[x]];
-    }
-    dst += BPS;
-  }
-}
-static void TM4(uint8_t *dst)   { TrueMotion(dst, 4); }
-static void TM8uv(uint8_t *dst) { TrueMotion(dst, 8); }
-static void TM16(uint8_t *dst)  { TrueMotion(dst, 16); }
-
-//------------------------------------------------------------------------------
-// 16x16
-
-static void VE16(uint8_t *dst) {     // vertical
-  int j;
-  for (j = 0; j < 16; ++j) {
-    memcpy(dst + j * BPS, dst - BPS, 16);
-  }
-}
-
-static void HE16(uint8_t *dst) {     // horizontal
-  int j;
-  for (j = 16; j > 0; --j) {
-    memset(dst, dst[-1], 16);
-    dst += BPS;
-  }
-}
-
-static WEBP_INLINE void Put16(int v, uint8_t* dst) {
-  int j;
-  for (j = 0; j < 16; ++j) {
-    memset(dst + j * BPS, v, 16);
-  }
-}
-
-static void DC16(uint8_t *dst) {    // DC
-  int DC = 16;
-  int j;
-  for (j = 0; j < 16; ++j) {
-    DC += dst[-1 + j * BPS] + dst[j - BPS];
-  }
-  Put16(DC >> 5, dst);
-}
-
-static void DC16NoTop(uint8_t *dst) {   // DC with top samples not available
-  int DC = 8;
-  int j;
-  for (j = 0; j < 16; ++j) {
-    DC += dst[-1 + j * BPS];
-  }
-  Put16(DC >> 4, dst);
-}
-
-static void DC16NoLeft(uint8_t *dst) {  // DC with left samples not available
-  int DC = 8;
-  int i;
-  for (i = 0; i < 16; ++i) {
-    DC += dst[i - BPS];
-  }
-  Put16(DC >> 4, dst);
-}
-
-static void DC16NoTopLeft(uint8_t *dst) {  // DC with no top and left samples
-  Put16(0x80, dst);
-}
-
-//------------------------------------------------------------------------------
-// 4x4
-
-#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
-#define AVG2(a, b) (((a) + (b) + 1) >> 1)
-
-static void VE4(uint8_t *dst) {    // vertical
-  const uint8_t* top = dst - BPS;
-  const uint8_t vals[4] = {
-    AVG3(top[-1], top[0], top[1]),
-    AVG3(top[ 0], top[1], top[2]),
-    AVG3(top[ 1], top[2], top[3]),
-    AVG3(top[ 2], top[3], top[4])
-  };
-  int i;
-  for (i = 0; i < 4; ++i) {
-    memcpy(dst + i * BPS, vals, sizeof(vals));
-  }
-}
-
-static void HE4(uint8_t *dst) {    // horizontal
-  const int A = dst[-1 - BPS];
-  const int B = dst[-1];
-  const int C = dst[-1 + BPS];
-  const int D = dst[-1 + 2 * BPS];
-  const int E = dst[-1 + 3 * BPS];
-  *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(A, B, C);
-  *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(B, C, D);
-  *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(C, D, E);
-  *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(D, E, E);
-}
-
-static void DC4(uint8_t *dst) {   // DC
-  uint32_t dc = 4;
-  int i;
-  for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS];
-  dc >>= 3;
-  for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4);
-}
-
-static void RD4(uint8_t *dst) {   // Down-right
-  const int I = dst[-1 + 0 * BPS];
-  const int J = dst[-1 + 1 * BPS];
-  const int K = dst[-1 + 2 * BPS];
-  const int L = dst[-1 + 3 * BPS];
-  const int X = dst[-1 - BPS];
-  const int A = dst[0 - BPS];
-  const int B = dst[1 - BPS];
-  const int C = dst[2 - BPS];
-  const int D = dst[3 - BPS];
-  DST(0, 3)                                     = AVG3(J, K, L);
-  DST(0, 2) = DST(1, 3)                         = AVG3(I, J, K);
-  DST(0, 1) = DST(1, 2) = DST(2, 3)             = AVG3(X, I, J);
-  DST(0, 0) = DST(1, 1) = DST(2, 2) = DST(3, 3) = AVG3(A, X, I);
-  DST(1, 0) = DST(2, 1) = DST(3, 2)             = AVG3(B, A, X);
-  DST(2, 0) = DST(3, 1)                         = AVG3(C, B, A);
-  DST(3, 0)                                     = AVG3(D, C, B);
-}
-
-static void LD4(uint8_t *dst) {   // Down-Left
-  const int A = dst[0 - BPS];
-  const int B = dst[1 - BPS];
-  const int C = dst[2 - BPS];
-  const int D = dst[3 - BPS];
-  const int E = dst[4 - BPS];
-  const int F = dst[5 - BPS];
-  const int G = dst[6 - BPS];
-  const int H = dst[7 - BPS];
-  DST(0, 0)                                     = AVG3(A, B, C);
-  DST(1, 0) = DST(0, 1)                         = AVG3(B, C, D);
-  DST(2, 0) = DST(1, 1) = DST(0, 2)             = AVG3(C, D, E);
-  DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
-  DST(3, 1) = DST(2, 2) = DST(1, 3)             = AVG3(E, F, G);
-  DST(3, 2) = DST(2, 3)                         = AVG3(F, G, H);
-  DST(3, 3)                                     = AVG3(G, H, H);
-}
-
-static void VR4(uint8_t *dst) {   // Vertical-Right
-  const int I = dst[-1 + 0 * BPS];
-  const int J = dst[-1 + 1 * BPS];
-  const int K = dst[-1 + 2 * BPS];
-  const int X = dst[-1 - BPS];
-  const int A = dst[0 - BPS];
-  const int B = dst[1 - BPS];
-  const int C = dst[2 - BPS];
-  const int D = dst[3 - BPS];
-  DST(0, 0) = DST(1, 2) = AVG2(X, A);
-  DST(1, 0) = DST(2, 2) = AVG2(A, B);
-  DST(2, 0) = DST(3, 2) = AVG2(B, C);
-  DST(3, 0)             = AVG2(C, D);
-
-  DST(0, 3) =             AVG3(K, J, I);
-  DST(0, 2) =             AVG3(J, I, X);
-  DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
-  DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
-  DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
-  DST(3, 1) =             AVG3(B, C, D);
-}
-
-static void VL4(uint8_t *dst) {   // Vertical-Left
-  const int A = dst[0 - BPS];
-  const int B = dst[1 - BPS];
-  const int C = dst[2 - BPS];
-  const int D = dst[3 - BPS];
-  const int E = dst[4 - BPS];
-  const int F = dst[5 - BPS];
-  const int G = dst[6 - BPS];
-  const int H = dst[7 - BPS];
-  DST(0, 0) =             AVG2(A, B);
-  DST(1, 0) = DST(0, 2) = AVG2(B, C);
-  DST(2, 0) = DST(1, 2) = AVG2(C, D);
-  DST(3, 0) = DST(2, 2) = AVG2(D, E);
-
-  DST(0, 1) =             AVG3(A, B, C);
-  DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
-  DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
-  DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
-              DST(3, 2) = AVG3(E, F, G);
-              DST(3, 3) = AVG3(F, G, H);
-}
-
-static void HU4(uint8_t *dst) {   // Horizontal-Up
-  const int I = dst[-1 + 0 * BPS];
-  const int J = dst[-1 + 1 * BPS];
-  const int K = dst[-1 + 2 * BPS];
-  const int L = dst[-1 + 3 * BPS];
-  DST(0, 0) =             AVG2(I, J);
-  DST(2, 0) = DST(0, 1) = AVG2(J, K);
-  DST(2, 1) = DST(0, 2) = AVG2(K, L);
-  DST(1, 0) =             AVG3(I, J, K);
-  DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
-  DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
-  DST(3, 2) = DST(2, 2) =
-    DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
-}
-
-static void HD4(uint8_t *dst) {  // Horizontal-Down
-  const int I = dst[-1 + 0 * BPS];
-  const int J = dst[-1 + 1 * BPS];
-  const int K = dst[-1 + 2 * BPS];
-  const int L = dst[-1 + 3 * BPS];
-  const int X = dst[-1 - BPS];
-  const int A = dst[0 - BPS];
-  const int B = dst[1 - BPS];
-  const int C = dst[2 - BPS];
-
-  DST(0, 0) = DST(2, 1) = AVG2(I, X);
-  DST(0, 1) = DST(2, 2) = AVG2(J, I);
-  DST(0, 2) = DST(2, 3) = AVG2(K, J);
-  DST(0, 3)             = AVG2(L, K);
-
-  DST(3, 0)             = AVG3(A, B, C);
-  DST(2, 0)             = AVG3(X, A, B);
-  DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
-  DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
-  DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
-  DST(1, 3)             = AVG3(L, K, J);
-}
-
-#undef DST
-#undef AVG3
-#undef AVG2
-
-//------------------------------------------------------------------------------
-// Chroma
-
-static void VE8uv(uint8_t *dst) {    // vertical
-  int j;
-  for (j = 0; j < 8; ++j) {
-    memcpy(dst + j * BPS, dst - BPS, 8);
-  }
-}
-
-static void HE8uv(uint8_t *dst) {    // horizontal
-  int j;
-  for (j = 0; j < 8; ++j) {
-    memset(dst, dst[-1], 8);
-    dst += BPS;
-  }
-}
-
-// helper for chroma-DC predictions
-static WEBP_INLINE void Put8x8uv(uint64_t v, uint8_t* dst) {
-  int j;
-  for (j = 0; j < 8; ++j) {
-    *(uint64_t*)(dst + j * BPS) = v;
-  }
-}
-
-static void DC8uv(uint8_t *dst) {     // DC
-  int dc0 = 8;
-  int i;
-  for (i = 0; i < 8; ++i) {
-    dc0 += dst[i - BPS] + dst[-1 + i * BPS];
-  }
-  Put8x8uv((uint64_t)((dc0 >> 4) * 0x0101010101010101ULL), dst);
-}
-
-static void DC8uvNoLeft(uint8_t *dst) {   // DC with no left samples
-  int dc0 = 4;
-  int i;
-  for (i = 0; i < 8; ++i) {
-    dc0 += dst[i - BPS];
-  }
-  Put8x8uv((uint64_t)((dc0 >> 3) * 0x0101010101010101ULL), dst);
-}
-
-static void DC8uvNoTop(uint8_t *dst) {  // DC with no top samples
-  int dc0 = 4;
-  int i;
-  for (i = 0; i < 8; ++i) {
-    dc0 += dst[-1 + i * BPS];
-  }
-  Put8x8uv((uint64_t)((dc0 >> 3) * 0x0101010101010101ULL), dst);
-}
-
-static void DC8uvNoTopLeft(uint8_t *dst) {    // DC with nothing
-  Put8x8uv(0x8080808080808080ULL, dst);
-}
-
-//------------------------------------------------------------------------------
-// default C implementations
-
-const VP8PredFunc VP8PredLuma4[NUM_BMODES] = {
-  DC4, TM4, VE4, HE4, RD4, VR4, LD4, VL4, HD4, HU4
-};
-
-const VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES] = {
-  DC16, TM16, VE16, HE16,
-  DC16NoTop, DC16NoLeft, DC16NoTopLeft
-};
-
-const VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES] = {
-  DC8uv, TM8uv, VE8uv, HE8uv,
-  DC8uvNoTop, DC8uvNoLeft, DC8uvNoTopLeft
-};
-
-//------------------------------------------------------------------------------
-// Edge filtering functions
-
-// 4 pixels in, 2 pixels out
-static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  const int a = 3 * (q0 - p0) + sclip1[1020 + p1 - q1];
-  const int a1 = sclip2[112 + ((a + 4) >> 3)];
-  const int a2 = sclip2[112 + ((a + 3) >> 3)];
-  p[-step] = clip1[255 + p0 + a2];
-  p[    0] = clip1[255 + q0 - a1];
-}
-
-// 4 pixels in, 4 pixels out
-static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  const int a = 3 * (q0 - p0);
-  const int a1 = sclip2[112 + ((a + 4) >> 3)];
-  const int a2 = sclip2[112 + ((a + 3) >> 3)];
-  const int a3 = (a1 + 1) >> 1;
-  p[-2*step] = clip1[255 + p1 + a3];
-  p[-  step] = clip1[255 + p0 + a2];
-  p[      0] = clip1[255 + q0 - a1];
-  p[   step] = clip1[255 + q1 - a3];
-}
-
-// 6 pixels in, 6 pixels out
-static WEBP_INLINE void do_filter6(uint8_t* p, int step) {
-  const int p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
-  const int q0 = p[0], q1 = p[step], q2 = p[2*step];
-  const int a = sclip1[1020 + 3 * (q0 - p0) + sclip1[1020 + p1 - q1]];
-  const int a1 = (27 * a + 63) >> 7;  // eq. to ((3 * a + 7) * 9) >> 7
-  const int a2 = (18 * a + 63) >> 7;  // eq. to ((2 * a + 7) * 9) >> 7
-  const int a3 = (9  * a + 63) >> 7;  // eq. to ((1 * a + 7) * 9) >> 7
-  p[-3*step] = clip1[255 + p2 + a3];
-  p[-2*step] = clip1[255 + p1 + a2];
-  p[-  step] = clip1[255 + p0 + a1];
-  p[      0] = clip1[255 + q0 - a1];
-  p[   step] = clip1[255 + q1 - a2];
-  p[ 2*step] = clip1[255 + q2 - a3];
-}
-
-static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  return (abs0[255 + p1 - p0] > thresh) || (abs0[255 + q1 - q0] > thresh);
-}
-
-static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int thresh) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  return (2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) <= thresh;
-}
-
-static WEBP_INLINE int needs_filter2(const uint8_t* p,
-                                     int step, int t, int it) {
-  const int p3 = p[-4*step], p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
-  const int q0 = p[0], q1 = p[step], q2 = p[2*step], q3 = p[3*step];
-  if ((2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) > t)
-    return 0;
-  return abs0[255 + p3 - p2] <= it && abs0[255 + p2 - p1] <= it &&
-         abs0[255 + p1 - p0] <= it && abs0[255 + q3 - q2] <= it &&
-         abs0[255 + q2 - q1] <= it && abs0[255 + q1 - q0] <= it;
-}
-
-//------------------------------------------------------------------------------
-// Simple In-loop filtering (Paragraph 15.2)
-
-static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
-  int i;
-  for (i = 0; i < 16; ++i) {
-    if (needs_filter(p + i, stride, thresh)) {
-      do_filter2(p + i, stride);
-    }
-  }
-}
-
-static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
-  int i;
-  for (i = 0; i < 16; ++i) {
-    if (needs_filter(p + i * stride, 1, thresh)) {
-      do_filter2(p + i * stride, 1);
-    }
-  }
-}
-
-static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4 * stride;
-    SimpleVFilter16(p, stride, thresh);
-  }
-}
-
-static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4;
-    SimpleHFilter16(p, stride, thresh);
-  }
-}
-
-//------------------------------------------------------------------------------
-// Complex In-loop filtering (Paragraph 15.3)
-
-static WEBP_INLINE void FilterLoop26(uint8_t* p,
-                                     int hstride, int vstride, int size,
-                                     int thresh, int ithresh, int hev_thresh) {
-  while (size-- > 0) {
-    if (needs_filter2(p, hstride, thresh, ithresh)) {
-      if (hev(p, hstride, hev_thresh)) {
-        do_filter2(p, hstride);
-      } else {
-        do_filter6(p, hstride);
-      }
-    }
-    p += vstride;
-  }
-}
-
-static WEBP_INLINE void FilterLoop24(uint8_t* p,
-                                     int hstride, int vstride, int size,
-                                     int thresh, int ithresh, int hev_thresh) {
-  while (size-- > 0) {
-    if (needs_filter2(p, hstride, thresh, ithresh)) {
-      if (hev(p, hstride, hev_thresh)) {
-        do_filter2(p, hstride);
-      } else {
-        do_filter4(p, hstride);
-      }
-    }
-    p += vstride;
-  }
-}
-
-// on macroblock edges
-static void VFilter16(uint8_t* p, int stride,
-                      int thresh, int ithresh, int hev_thresh) {
-  FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh);
-}
-
-static void HFilter16(uint8_t* p, int stride,
-                      int thresh, int ithresh, int hev_thresh) {
-  FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh);
-}
-
-// on three inner edges
-static void VFilter16i(uint8_t* p, int stride,
-                       int thresh, int ithresh, int hev_thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4 * stride;
-    FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
-  }
-}
-
-static void HFilter16i(uint8_t* p, int stride,
-                       int thresh, int ithresh, int hev_thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4;
-    FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
-  }
-}
-
-// 8-pixels wide variant, for chroma filtering
-static void VFilter8(uint8_t* u, uint8_t* v, int stride,
-                     int thresh, int ithresh, int hev_thresh) {
-  FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
-  FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh);
-}
-
-static void HFilter8(uint8_t* u, uint8_t* v, int stride,
-                     int thresh, int ithresh, int hev_thresh) {
-  FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
-  FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
-}
-
-static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
-                      int thresh, int ithresh, int hev_thresh) {
-  FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
-  FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
-}
-
-static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
-                      int thresh, int ithresh, int hev_thresh) {
-  FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
-  FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
-}
-
-//------------------------------------------------------------------------------
-
-VP8DecIdct2 VP8Transform;
-VP8DecIdct VP8TransformUV;
-VP8DecIdct VP8TransformDC;
-VP8DecIdct VP8TransformDCUV;
-
-VP8LumaFilterFunc VP8VFilter16;
-VP8LumaFilterFunc VP8HFilter16;
-VP8ChromaFilterFunc VP8VFilter8;
-VP8ChromaFilterFunc VP8HFilter8;
-VP8LumaFilterFunc VP8VFilter16i;
-VP8LumaFilterFunc VP8HFilter16i;
-VP8ChromaFilterFunc VP8VFilter8i;
-VP8ChromaFilterFunc VP8HFilter8i;
-VP8SimpleFilterFunc VP8SimpleVFilter16;
-VP8SimpleFilterFunc VP8SimpleHFilter16;
-VP8SimpleFilterFunc VP8SimpleVFilter16i;
-VP8SimpleFilterFunc VP8SimpleHFilter16i;
-
-extern void VP8DspInitSSE2(void);
-extern void VP8DspInitNEON(void);
-
-void VP8DspInit(void) {
-  DspInitTables();
-
-  VP8Transform = TransformTwo;
-  VP8TransformUV = TransformUV;
-  VP8TransformDC = TransformDC;
-  VP8TransformDCUV = TransformDCUV;
-
-  VP8VFilter16 = VFilter16;
-  VP8HFilter16 = HFilter16;
-  VP8VFilter8 = VFilter8;
-  VP8HFilter8 = HFilter8;
-  VP8VFilter16i = VFilter16i;
-  VP8HFilter16i = HFilter16i;
-  VP8VFilter8i = VFilter8i;
-  VP8HFilter8i = HFilter8i;
-  VP8SimpleVFilter16 = SimpleVFilter16;
-  VP8SimpleHFilter16 = SimpleHFilter16;
-  VP8SimpleVFilter16i = SimpleVFilter16i;
-  VP8SimpleHFilter16i = SimpleHFilter16i;
-
-  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
-  if (VP8GetCPUInfo) {
-#if defined(WEBP_USE_SSE2)
-    if (VP8GetCPUInfo(kSSE2)) {
-      VP8DspInitSSE2();
-    }
-#elif defined(WEBP_USE_NEON)
-    if (VP8GetCPUInfo(kNEON)) {
-      VP8DspInitNEON();
-    }
-#endif
-  }
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 329
drivers/webpold/dsp/dec_neon.c

@@ -1,329 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// ARM NEON version of dsp functions and loop filtering.
-//
-// Authors: Somnath Banerjee ([email protected])
-//          Johann Koenig ([email protected])
-
-#include "./dsp.h"
-
-#if defined(WEBP_USE_NEON)
-
-#include "../dec/vp8i.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define QRegs "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",                  \
-              "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
-
-#define FLIP_SIGN_BIT2(a, b, s)                                                \
-  "veor     " #a "," #a "," #s "               \n"                             \
-  "veor     " #b "," #b "," #s "               \n"                             \
-
-#define FLIP_SIGN_BIT4(a, b, c, d, s)                                          \
-  FLIP_SIGN_BIT2(a, b, s)                                                      \
-  FLIP_SIGN_BIT2(c, d, s)                                                      \
-
-#define NEEDS_FILTER(p1, p0, q0, q1, thresh, mask)                             \
-  "vabd.u8    q15," #p0 "," #q0 "         \n"  /* abs(p0 - q0) */              \
-  "vabd.u8    q14," #p1 "," #q1 "         \n"  /* abs(p1 - q1) */              \
-  "vqadd.u8   q15, q15, q15               \n"  /* abs(p0 - q0) * 2 */          \
-  "vshr.u8    q14, q14, #1                \n"  /* abs(p1 - q1) / 2 */          \
-  "vqadd.u8   q15, q15, q14     \n"  /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 */ \
-  "vdup.8     q14, " #thresh "            \n"                                  \
-  "vcge.u8   " #mask ", q14, q15          \n"  /* mask <= thresh */
-
-#define GET_BASE_DELTA(p1, p0, q0, q1, o)                                      \
-  "vqsub.s8   q15," #q0 "," #p0 "         \n"  /* (q0 - p0) */                 \
-  "vqsub.s8  " #o "," #p1 "," #q1 "       \n"  /* (p1 - q1) */                 \
-  "vqadd.s8  " #o "," #o ", q15           \n"  /* (p1 - q1) + 1 * (p0 - q0) */ \
-  "vqadd.s8  " #o "," #o ", q15           \n"  /* (p1 - q1) + 2 * (p0 - q0) */ \
-  "vqadd.s8  " #o "," #o ", q15           \n"  /* (p1 - q1) + 3 * (p0 - q0) */
-
-#define DO_SIMPLE_FILTER(p0, q0, fl)                                           \
-  "vmov.i8    q15, #0x03                  \n"                                  \
-  "vqadd.s8   q15, q15, " #fl "           \n"  /* filter1 = filter + 3 */      \
-  "vshr.s8    q15, q15, #3                \n"  /* filter1 >> 3 */              \
-  "vqadd.s8  " #p0 "," #p0 ", q15         \n"  /* p0 += filter1 */             \
-                                                                               \
-  "vmov.i8    q15, #0x04                  \n"                                  \
-  "vqadd.s8   q15, q15, " #fl "           \n"  /* filter1 = filter + 4 */      \
-  "vshr.s8    q15, q15, #3                \n"  /* filter2 >> 3 */              \
-  "vqsub.s8  " #q0 "," #q0 ", q15         \n"  /* q0 -= filter2 */
-
-// Applies filter on 2 pixels (p0 and q0)
-#define DO_FILTER2(p1, p0, q0, q1, thresh)                                     \
-  NEEDS_FILTER(p1, p0, q0, q1, thresh, q9)     /* filter mask in q9 */         \
-  "vmov.i8    q10, #0x80                  \n"  /* sign bit */                  \
-  FLIP_SIGN_BIT4(p1, p0, q0, q1, q10)          /* convert to signed value */   \
-  GET_BASE_DELTA(p1, p0, q0, q1, q11)          /* get filter level  */         \
-  "vand       q9, q9, q11                 \n"  /* apply filter mask */         \
-  DO_SIMPLE_FILTER(p0, q0, q9)                 /* apply filter */              \
-  FLIP_SIGN_BIT2(p0, q0, q10)
-
-// Load/Store vertical edge
-#define LOAD8x4(c1, c2, c3, c4, b1, b2, stride)                                \
-  "vld4.8   {" #c1"[0], " #c2"[0], " #c3"[0], " #c4"[0]}," #b1 "," #stride"\n" \
-  "vld4.8   {" #c1"[1], " #c2"[1], " #c3"[1], " #c4"[1]}," #b2 "," #stride"\n" \
-  "vld4.8   {" #c1"[2], " #c2"[2], " #c3"[2], " #c4"[2]}," #b1 "," #stride"\n" \
-  "vld4.8   {" #c1"[3], " #c2"[3], " #c3"[3], " #c4"[3]}," #b2 "," #stride"\n" \
-  "vld4.8   {" #c1"[4], " #c2"[4], " #c3"[4], " #c4"[4]}," #b1 "," #stride"\n" \
-  "vld4.8   {" #c1"[5], " #c2"[5], " #c3"[5], " #c4"[5]}," #b2 "," #stride"\n" \
-  "vld4.8   {" #c1"[6], " #c2"[6], " #c3"[6], " #c4"[6]}," #b1 "," #stride"\n" \
-  "vld4.8   {" #c1"[7], " #c2"[7], " #c3"[7], " #c4"[7]}," #b2 "," #stride"\n"
-
-#define STORE8x2(c1, c2, p,stride)                                             \
-  "vst2.8   {" #c1"[0], " #c2"[0]}," #p "," #stride " \n"                      \
-  "vst2.8   {" #c1"[1], " #c2"[1]}," #p "," #stride " \n"                      \
-  "vst2.8   {" #c1"[2], " #c2"[2]}," #p "," #stride " \n"                      \
-  "vst2.8   {" #c1"[3], " #c2"[3]}," #p "," #stride " \n"                      \
-  "vst2.8   {" #c1"[4], " #c2"[4]}," #p "," #stride " \n"                      \
-  "vst2.8   {" #c1"[5], " #c2"[5]}," #p "," #stride " \n"                      \
-  "vst2.8   {" #c1"[6], " #c2"[6]}," #p "," #stride " \n"                      \
-  "vst2.8   {" #c1"[7], " #c2"[7]}," #p "," #stride " \n"
-
-//-----------------------------------------------------------------------------
-// Simple In-loop filtering (Paragraph 15.2)
-
-static void SimpleVFilter16NEON(uint8_t* p, int stride, int thresh) {
-  __asm__ volatile (
-    "sub        %[p], %[p], %[stride], lsl #1  \n"  // p -= 2 * stride
-
-    "vld1.u8    {q1}, [%[p]], %[stride]        \n"  // p1
-    "vld1.u8    {q2}, [%[p]], %[stride]        \n"  // p0
-    "vld1.u8    {q3}, [%[p]], %[stride]        \n"  // q0
-    "vld1.u8    {q4}, [%[p]]                   \n"  // q1
-
-    DO_FILTER2(q1, q2, q3, q4, %[thresh])
-
-    "sub        %[p], %[p], %[stride], lsl #1  \n"  // p -= 2 * stride
-
-    "vst1.u8    {q2}, [%[p]], %[stride]        \n"  // store op0
-    "vst1.u8    {q3}, [%[p]]                   \n"  // store oq0
-    : [p] "+r"(p)
-    : [stride] "r"(stride), [thresh] "r"(thresh)
-    : "memory", QRegs
-  );
-}
-
-static void SimpleHFilter16NEON(uint8_t* p, int stride, int thresh) {
-  __asm__ volatile (
-    "sub        r4, %[p], #2                   \n"  // base1 = p - 2
-    "lsl        r6, %[stride], #1              \n"  // r6 = 2 * stride
-    "add        r5, r4, %[stride]              \n"  // base2 = base1 + stride
-
-    LOAD8x4(d2, d3, d4, d5, [r4], [r5], r6)
-    LOAD8x4(d6, d7, d8, d9, [r4], [r5], r6)
-    "vswp       d3, d6                         \n"  // p1:q1 p0:q3
-    "vswp       d5, d8                         \n"  // q0:q2 q1:q4
-    "vswp       q2, q3                         \n"  // p1:q1 p0:q2 q0:q3 q1:q4
-
-    DO_FILTER2(q1, q2, q3, q4, %[thresh])
-
-    "sub        %[p], %[p], #1                 \n"  // p - 1
-
-    "vswp        d5, d6                        \n"
-    STORE8x2(d4, d5, [%[p]], %[stride])
-    STORE8x2(d6, d7, [%[p]], %[stride])
-
-    : [p] "+r"(p)
-    : [stride] "r"(stride), [thresh] "r"(thresh)
-    : "memory", "r4", "r5", "r6", QRegs
-  );
-}
-
-static void SimpleVFilter16iNEON(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4 * stride;
-    SimpleVFilter16NEON(p, stride, thresh);
-  }
-}
-
-static void SimpleHFilter16iNEON(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4;
-    SimpleHFilter16NEON(p, stride, thresh);
-  }
-}
-
-static void TransformOneNEON(const int16_t *in, uint8_t *dst) {
-  const int kBPS = BPS;
-  const int16_t constants[] = {20091, 17734, 0, 0};
-  /* kC1, kC2. Padded because vld1.16 loads 8 bytes
-   * Technically these are unsigned but vqdmulh is only available in signed.
-   * vqdmulh returns high half (effectively >> 16) but also doubles the value,
-   * changing the >> 16 to >> 15 and requiring an additional >> 1.
-   * We use this to our advantage with kC2. The canonical value is 35468.
-   * However, the high bit is set so treating it as signed will give incorrect
-   * results. We avoid this by down shifting by 1 here to clear the highest bit.
-   * Combined with the doubling effect of vqdmulh we get >> 16.
-   * This can not be applied to kC1 because the lowest bit is set. Down shifting
-   * the constant would reduce precision.
-   */
-
-  /* libwebp uses a trick to avoid some extra addition that libvpx does.
-   * Instead of:
-   * temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1) >> 16);
-   * libwebp adds 1 << 16 to cospi8sqrt2minus1 (kC1). However, this causes the
-   * same issue with kC1 and vqdmulh that we work around by down shifting kC2
-   */
-
-  /* Adapted from libvpx: vp8/common/arm/neon/shortidct4x4llm_neon.asm */
-  __asm__ volatile (
-    "vld1.16         {q1, q2}, [%[in]]           \n"
-    "vld1.16         {d0}, [%[constants]]        \n"
-
-    /* d2: in[0]
-     * d3: in[8]
-     * d4: in[4]
-     * d5: in[12]
-     */
-    "vswp            d3, d4                      \n"
-
-    /* q8 = {in[4], in[12]} * kC1 * 2 >> 16
-     * q9 = {in[4], in[12]} * kC2 >> 16
-     */
-    "vqdmulh.s16     q8, q2, d0[0]               \n"
-    "vqdmulh.s16     q9, q2, d0[1]               \n"
-
-    /* d22 = a = in[0] + in[8]
-     * d23 = b = in[0] - in[8]
-     */
-    "vqadd.s16       d22, d2, d3                 \n"
-    "vqsub.s16       d23, d2, d3                 \n"
-
-    /* The multiplication should be x * kC1 >> 16
-     * However, with vqdmulh we get x * kC1 * 2 >> 16
-     * (multiply, double, return high half)
-     * We avoided this in kC2 by pre-shifting the constant.
-     * q8 = in[4]/[12] * kC1 >> 16
-     */
-    "vshr.s16        q8, q8, #1                  \n"
-
-    /* Add {in[4], in[12]} back after the multiplication. This is handled by
-     * adding 1 << 16 to kC1 in the libwebp C code.
-     */
-    "vqadd.s16       q8, q2, q8                  \n"
-
-    /* d20 = c = in[4]*kC2 - in[12]*kC1
-     * d21 = d = in[4]*kC1 + in[12]*kC2
-     */
-    "vqsub.s16       d20, d18, d17               \n"
-    "vqadd.s16       d21, d19, d16               \n"
-
-    /* d2 = tmp[0] = a + d
-     * d3 = tmp[1] = b + c
-     * d4 = tmp[2] = b - c
-     * d5 = tmp[3] = a - d
-     */
-    "vqadd.s16       d2, d22, d21                \n"
-    "vqadd.s16       d3, d23, d20                \n"
-    "vqsub.s16       d4, d23, d20                \n"
-    "vqsub.s16       d5, d22, d21                \n"
-
-    "vzip.16         q1, q2                      \n"
-    "vzip.16         q1, q2                      \n"
-
-    "vswp            d3, d4                      \n"
-
-    /* q8 = {tmp[4], tmp[12]} * kC1 * 2 >> 16
-     * q9 = {tmp[4], tmp[12]} * kC2 >> 16
-     */
-    "vqdmulh.s16     q8, q2, d0[0]               \n"
-    "vqdmulh.s16     q9, q2, d0[1]               \n"
-
-    /* d22 = a = tmp[0] + tmp[8]
-     * d23 = b = tmp[0] - tmp[8]
-     */
-    "vqadd.s16       d22, d2, d3                 \n"
-    "vqsub.s16       d23, d2, d3                 \n"
-
-    /* See long winded explanations prior */
-    "vshr.s16        q8, q8, #1                  \n"
-    "vqadd.s16       q8, q2, q8                  \n"
-
-    /* d20 = c = in[4]*kC2 - in[12]*kC1
-     * d21 = d = in[4]*kC1 + in[12]*kC2
-     */
-    "vqsub.s16       d20, d18, d17               \n"
-    "vqadd.s16       d21, d19, d16               \n"
-
-    /* d2 = tmp[0] = a + d
-     * d3 = tmp[1] = b + c
-     * d4 = tmp[2] = b - c
-     * d5 = tmp[3] = a - d
-     */
-    "vqadd.s16       d2, d22, d21                \n"
-    "vqadd.s16       d3, d23, d20                \n"
-    "vqsub.s16       d4, d23, d20                \n"
-    "vqsub.s16       d5, d22, d21                \n"
-
-    "vld1.32         d6[0], [%[dst]], %[kBPS]    \n"
-    "vld1.32         d6[1], [%[dst]], %[kBPS]    \n"
-    "vld1.32         d7[0], [%[dst]], %[kBPS]    \n"
-    "vld1.32         d7[1], [%[dst]], %[kBPS]    \n"
-
-    "sub         %[dst], %[dst], %[kBPS], lsl #2 \n"
-
-    /* (val) + 4 >> 3 */
-    "vrshr.s16       d2, d2, #3                  \n"
-    "vrshr.s16       d3, d3, #3                  \n"
-    "vrshr.s16       d4, d4, #3                  \n"
-    "vrshr.s16       d5, d5, #3                  \n"
-
-    "vzip.16         q1, q2                      \n"
-    "vzip.16         q1, q2                      \n"
-
-    /* Must accumulate before saturating */
-    "vmovl.u8        q8, d6                      \n"
-    "vmovl.u8        q9, d7                      \n"
-
-    "vqadd.s16       q1, q1, q8                  \n"
-    "vqadd.s16       q2, q2, q9                  \n"
-
-    "vqmovun.s16     d0, q1                      \n"
-    "vqmovun.s16     d1, q2                      \n"
-
-    "vst1.32         d0[0], [%[dst]], %[kBPS]    \n"
-    "vst1.32         d0[1], [%[dst]], %[kBPS]    \n"
-    "vst1.32         d1[0], [%[dst]], %[kBPS]    \n"
-    "vst1.32         d1[1], [%[dst]]             \n"
-
-    : [in] "+r"(in), [dst] "+r"(dst)  /* modified registers */
-    : [kBPS] "r"(kBPS), [constants] "r"(constants)  /* constants */
-    : "memory", "q0", "q1", "q2", "q8", "q9", "q10", "q11"  /* clobbered */
-  );
-}
-
-static void TransformTwoNEON(const int16_t* in, uint8_t* dst, int do_two) {
-  TransformOneNEON(in, dst);
-  if (do_two) {
-    TransformOneNEON(in + 16, dst + 4);
-  }
-}
-
-extern void VP8DspInitNEON(void);
-
-void VP8DspInitNEON(void) {
-  VP8Transform = TransformTwoNEON;
-
-  VP8SimpleVFilter16 = SimpleVFilter16NEON;
-  VP8SimpleHFilter16 = SimpleHFilter16NEON;
-  VP8SimpleVFilter16i = SimpleVFilter16iNEON;
-  VP8SimpleHFilter16i = SimpleHFilter16iNEON;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif   // WEBP_USE_NEON

+ 0 - 903
drivers/webpold/dsp/dec_sse2.c

@@ -1,903 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// SSE2 version of some decoding functions (idct, loop filtering).
-//
-// Author: [email protected] (Somnath Banerjee)
-//         [email protected] (Christian Duvivier)
-
-#include "./dsp.h"
-
-#if defined(WEBP_USE_SSE2)
-
-#include <emmintrin.h>
-#include "../dec/vp8i.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Transforms (Paragraph 14.4)
-
-static void TransformSSE2(const int16_t* in, uint8_t* dst, int do_two) {
-  // This implementation makes use of 16-bit fixed point versions of two
-  // multiply constants:
-  //    K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
-  //    K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16
-  //
-  // To be able to use signed 16-bit integers, we use the following trick to
-  // have constants within range:
-  // - Associated constants are obtained by subtracting the 16-bit fixed point
-  //   version of one:
-  //      k = K - (1 << 16)  =>  K = k + (1 << 16)
-  //      K1 = 85267  =>  k1 =  20091
-  //      K2 = 35468  =>  k2 = -30068
-  // - The multiplication of a variable by a constant become the sum of the
-  //   variable and the multiplication of that variable by the associated
-  //   constant:
-  //      (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x
-  const __m128i k1 = _mm_set1_epi16(20091);
-  const __m128i k2 = _mm_set1_epi16(-30068);
-  __m128i T0, T1, T2, T3;
-
-  // Load and concatenate the transform coefficients (we'll do two transforms
-  // in parallel). In the case of only one transform, the second half of the
-  // vectors will just contain random value we'll never use nor store.
-  __m128i in0, in1, in2, in3;
-  {
-    in0 = _mm_loadl_epi64((__m128i*)&in[0]);
-    in1 = _mm_loadl_epi64((__m128i*)&in[4]);
-    in2 = _mm_loadl_epi64((__m128i*)&in[8]);
-    in3 = _mm_loadl_epi64((__m128i*)&in[12]);
-    // a00 a10 a20 a30   x x x x
-    // a01 a11 a21 a31   x x x x
-    // a02 a12 a22 a32   x x x x
-    // a03 a13 a23 a33   x x x x
-    if (do_two) {
-      const __m128i inB0 = _mm_loadl_epi64((__m128i*)&in[16]);
-      const __m128i inB1 = _mm_loadl_epi64((__m128i*)&in[20]);
-      const __m128i inB2 = _mm_loadl_epi64((__m128i*)&in[24]);
-      const __m128i inB3 = _mm_loadl_epi64((__m128i*)&in[28]);
-      in0 = _mm_unpacklo_epi64(in0, inB0);
-      in1 = _mm_unpacklo_epi64(in1, inB1);
-      in2 = _mm_unpacklo_epi64(in2, inB2);
-      in3 = _mm_unpacklo_epi64(in3, inB3);
-      // a00 a10 a20 a30   b00 b10 b20 b30
-      // a01 a11 a21 a31   b01 b11 b21 b31
-      // a02 a12 a22 a32   b02 b12 b22 b32
-      // a03 a13 a23 a33   b03 b13 b23 b33
-    }
-  }
-
-  // Vertical pass and subsequent transpose.
-  {
-    // First pass, c and d calculations are longer because of the "trick"
-    // multiplications.
-    const __m128i a = _mm_add_epi16(in0, in2);
-    const __m128i b = _mm_sub_epi16(in0, in2);
-    // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3
-    const __m128i c1 = _mm_mulhi_epi16(in1, k2);
-    const __m128i c2 = _mm_mulhi_epi16(in3, k1);
-    const __m128i c3 = _mm_sub_epi16(in1, in3);
-    const __m128i c4 = _mm_sub_epi16(c1, c2);
-    const __m128i c = _mm_add_epi16(c3, c4);
-    // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3
-    const __m128i d1 = _mm_mulhi_epi16(in1, k1);
-    const __m128i d2 = _mm_mulhi_epi16(in3, k2);
-    const __m128i d3 = _mm_add_epi16(in1, in3);
-    const __m128i d4 = _mm_add_epi16(d1, d2);
-    const __m128i d = _mm_add_epi16(d3, d4);
-
-    // Second pass.
-    const __m128i tmp0 = _mm_add_epi16(a, d);
-    const __m128i tmp1 = _mm_add_epi16(b, c);
-    const __m128i tmp2 = _mm_sub_epi16(b, c);
-    const __m128i tmp3 = _mm_sub_epi16(a, d);
-
-    // Transpose the two 4x4.
-    // a00 a01 a02 a03   b00 b01 b02 b03
-    // a10 a11 a12 a13   b10 b11 b12 b13
-    // a20 a21 a22 a23   b20 b21 b22 b23
-    // a30 a31 a32 a33   b30 b31 b32 b33
-    const __m128i transpose0_0 = _mm_unpacklo_epi16(tmp0, tmp1);
-    const __m128i transpose0_1 = _mm_unpacklo_epi16(tmp2, tmp3);
-    const __m128i transpose0_2 = _mm_unpackhi_epi16(tmp0, tmp1);
-    const __m128i transpose0_3 = _mm_unpackhi_epi16(tmp2, tmp3);
-    // a00 a10 a01 a11   a02 a12 a03 a13
-    // a20 a30 a21 a31   a22 a32 a23 a33
-    // b00 b10 b01 b11   b02 b12 b03 b13
-    // b20 b30 b21 b31   b22 b32 b23 b33
-    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
-    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
-    // a00 a10 a20 a30 a01 a11 a21 a31
-    // b00 b10 b20 b30 b01 b11 b21 b31
-    // a02 a12 a22 a32 a03 a13 a23 a33
-    // b02 b12 a22 b32 b03 b13 b23 b33
-    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
-    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
-    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
-    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
-    // a00 a10 a20 a30   b00 b10 b20 b30
-    // a01 a11 a21 a31   b01 b11 b21 b31
-    // a02 a12 a22 a32   b02 b12 b22 b32
-    // a03 a13 a23 a33   b03 b13 b23 b33
-  }
-
-  // Horizontal pass and subsequent transpose.
-  {
-    // First pass, c and d calculations are longer because of the "trick"
-    // multiplications.
-    const __m128i four = _mm_set1_epi16(4);
-    const __m128i dc = _mm_add_epi16(T0, four);
-    const __m128i a =  _mm_add_epi16(dc, T2);
-    const __m128i b =  _mm_sub_epi16(dc, T2);
-    // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3
-    const __m128i c1 = _mm_mulhi_epi16(T1, k2);
-    const __m128i c2 = _mm_mulhi_epi16(T3, k1);
-    const __m128i c3 = _mm_sub_epi16(T1, T3);
-    const __m128i c4 = _mm_sub_epi16(c1, c2);
-    const __m128i c = _mm_add_epi16(c3, c4);
-    // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3
-    const __m128i d1 = _mm_mulhi_epi16(T1, k1);
-    const __m128i d2 = _mm_mulhi_epi16(T3, k2);
-    const __m128i d3 = _mm_add_epi16(T1, T3);
-    const __m128i d4 = _mm_add_epi16(d1, d2);
-    const __m128i d = _mm_add_epi16(d3, d4);
-
-    // Second pass.
-    const __m128i tmp0 = _mm_add_epi16(a, d);
-    const __m128i tmp1 = _mm_add_epi16(b, c);
-    const __m128i tmp2 = _mm_sub_epi16(b, c);
-    const __m128i tmp3 = _mm_sub_epi16(a, d);
-    const __m128i shifted0 = _mm_srai_epi16(tmp0, 3);
-    const __m128i shifted1 = _mm_srai_epi16(tmp1, 3);
-    const __m128i shifted2 = _mm_srai_epi16(tmp2, 3);
-    const __m128i shifted3 = _mm_srai_epi16(tmp3, 3);
-
-    // Transpose the two 4x4.
-    // a00 a01 a02 a03   b00 b01 b02 b03
-    // a10 a11 a12 a13   b10 b11 b12 b13
-    // a20 a21 a22 a23   b20 b21 b22 b23
-    // a30 a31 a32 a33   b30 b31 b32 b33
-    const __m128i transpose0_0 = _mm_unpacklo_epi16(shifted0, shifted1);
-    const __m128i transpose0_1 = _mm_unpacklo_epi16(shifted2, shifted3);
-    const __m128i transpose0_2 = _mm_unpackhi_epi16(shifted0, shifted1);
-    const __m128i transpose0_3 = _mm_unpackhi_epi16(shifted2, shifted3);
-    // a00 a10 a01 a11   a02 a12 a03 a13
-    // a20 a30 a21 a31   a22 a32 a23 a33
-    // b00 b10 b01 b11   b02 b12 b03 b13
-    // b20 b30 b21 b31   b22 b32 b23 b33
-    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
-    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
-    // a00 a10 a20 a30 a01 a11 a21 a31
-    // b00 b10 b20 b30 b01 b11 b21 b31
-    // a02 a12 a22 a32 a03 a13 a23 a33
-    // b02 b12 a22 b32 b03 b13 b23 b33
-    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
-    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
-    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
-    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
-    // a00 a10 a20 a30   b00 b10 b20 b30
-    // a01 a11 a21 a31   b01 b11 b21 b31
-    // a02 a12 a22 a32   b02 b12 b22 b32
-    // a03 a13 a23 a33   b03 b13 b23 b33
-  }
-
-  // Add inverse transform to 'dst' and store.
-  {
-    const __m128i zero = _mm_set1_epi16(0);
-    // Load the reference(s).
-    __m128i dst0, dst1, dst2, dst3;
-    if (do_two) {
-      // Load eight bytes/pixels per line.
-      dst0 = _mm_loadl_epi64((__m128i*)&dst[0 * BPS]);
-      dst1 = _mm_loadl_epi64((__m128i*)&dst[1 * BPS]);
-      dst2 = _mm_loadl_epi64((__m128i*)&dst[2 * BPS]);
-      dst3 = _mm_loadl_epi64((__m128i*)&dst[3 * BPS]);
-    } else {
-      // Load four bytes/pixels per line.
-      dst0 = _mm_cvtsi32_si128(*(int*)&dst[0 * BPS]);
-      dst1 = _mm_cvtsi32_si128(*(int*)&dst[1 * BPS]);
-      dst2 = _mm_cvtsi32_si128(*(int*)&dst[2 * BPS]);
-      dst3 = _mm_cvtsi32_si128(*(int*)&dst[3 * BPS]);
-    }
-    // Convert to 16b.
-    dst0 = _mm_unpacklo_epi8(dst0, zero);
-    dst1 = _mm_unpacklo_epi8(dst1, zero);
-    dst2 = _mm_unpacklo_epi8(dst2, zero);
-    dst3 = _mm_unpacklo_epi8(dst3, zero);
-    // Add the inverse transform(s).
-    dst0 = _mm_add_epi16(dst0, T0);
-    dst1 = _mm_add_epi16(dst1, T1);
-    dst2 = _mm_add_epi16(dst2, T2);
-    dst3 = _mm_add_epi16(dst3, T3);
-    // Unsigned saturate to 8b.
-    dst0 = _mm_packus_epi16(dst0, dst0);
-    dst1 = _mm_packus_epi16(dst1, dst1);
-    dst2 = _mm_packus_epi16(dst2, dst2);
-    dst3 = _mm_packus_epi16(dst3, dst3);
-    // Store the results.
-    if (do_two) {
-      // Store eight bytes/pixels per line.
-      _mm_storel_epi64((__m128i*)&dst[0 * BPS], dst0);
-      _mm_storel_epi64((__m128i*)&dst[1 * BPS], dst1);
-      _mm_storel_epi64((__m128i*)&dst[2 * BPS], dst2);
-      _mm_storel_epi64((__m128i*)&dst[3 * BPS], dst3);
-    } else {
-      // Store four bytes/pixels per line.
-      *((int32_t *)&dst[0 * BPS]) = _mm_cvtsi128_si32(dst0);
-      *((int32_t *)&dst[1 * BPS]) = _mm_cvtsi128_si32(dst1);
-      *((int32_t *)&dst[2 * BPS]) = _mm_cvtsi128_si32(dst2);
-      *((int32_t *)&dst[3 * BPS]) = _mm_cvtsi128_si32(dst3);
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// Loop Filter (Paragraph 15)
-
-// Compute abs(p - q) = subs(p - q) OR subs(q - p)
-#define MM_ABS(p, q)  _mm_or_si128(                                            \
-    _mm_subs_epu8((q), (p)),                                                   \
-    _mm_subs_epu8((p), (q)))
-
-// Shift each byte of "a" by N bits while preserving by the sign bit.
-//
-// It first shifts the lower bytes of the words and then the upper bytes and
-// then merges the results together.
-#define SIGNED_SHIFT_N(a, N) {                                                 \
-  __m128i t = a;                                                               \
-  t = _mm_slli_epi16(t, 8);                                                    \
-  t = _mm_srai_epi16(t, N);                                                    \
-  t = _mm_srli_epi16(t, 8);                                                    \
-                                                                               \
-  a = _mm_srai_epi16(a, N + 8);                                                \
-  a = _mm_slli_epi16(a, 8);                                                    \
-                                                                               \
-  a = _mm_or_si128(t, a);                                                      \
-}
-
-#define FLIP_SIGN_BIT2(a, b) {                                                 \
-  a = _mm_xor_si128(a, sign_bit);                                              \
-  b = _mm_xor_si128(b, sign_bit);                                              \
-}
-
-#define FLIP_SIGN_BIT4(a, b, c, d) {                                           \
-  FLIP_SIGN_BIT2(a, b);                                                        \
-  FLIP_SIGN_BIT2(c, d);                                                        \
-}
-
-#define GET_NOTHEV(p1, p0, q0, q1, hev_thresh, not_hev) {                      \
-  const __m128i zero = _mm_setzero_si128();                                    \
-  const __m128i t1 = MM_ABS(p1, p0);                                           \
-  const __m128i t2 = MM_ABS(q1, q0);                                           \
-                                                                               \
-  const __m128i h = _mm_set1_epi8(hev_thresh);                                 \
-  const __m128i t3 = _mm_subs_epu8(t1, h);  /* abs(p1 - p0) - hev_tresh */     \
-  const __m128i t4 = _mm_subs_epu8(t2, h);  /* abs(q1 - q0) - hev_tresh */     \
-                                                                               \
-  not_hev = _mm_or_si128(t3, t4);                                              \
-  not_hev = _mm_cmpeq_epi8(not_hev, zero); /* not_hev <= t1 && not_hev <= t2 */\
-}
-
-#define GET_BASE_DELTA(p1, p0, q0, q1, o) {                                    \
-  const __m128i qp0 = _mm_subs_epi8(q0, p0);  /* q0 - p0 */                    \
-  o = _mm_subs_epi8(p1, q1);            /* p1 - q1 */                          \
-  o = _mm_adds_epi8(o, qp0);            /* p1 - q1 + 1 * (q0 - p0) */          \
-  o = _mm_adds_epi8(o, qp0);            /* p1 - q1 + 2 * (q0 - p0) */          \
-  o = _mm_adds_epi8(o, qp0);            /* p1 - q1 + 3 * (q0 - p0) */          \
-}
-
-#define DO_SIMPLE_FILTER(p0, q0, fl) {                                         \
-  const __m128i three = _mm_set1_epi8(3);                                      \
-  const __m128i four = _mm_set1_epi8(4);                                       \
-  __m128i v3 = _mm_adds_epi8(fl, three);                                       \
-  __m128i v4 = _mm_adds_epi8(fl, four);                                        \
-                                                                               \
-  /* Do +4 side */                                                             \
-  SIGNED_SHIFT_N(v4, 3);                /* v4 >> 3  */                         \
-  q0 = _mm_subs_epi8(q0, v4);           /* q0 -= v4 */                         \
-                                                                               \
-  /* Now do +3 side */                                                         \
-  SIGNED_SHIFT_N(v3, 3);                /* v3 >> 3  */                         \
-  p0 = _mm_adds_epi8(p0, v3);           /* p0 += v3 */                         \
-}
-
-// Updates values of 2 pixels at MB edge during complex filtering.
-// Update operations:
-// q = q - a and p = p + a; where a = [(a_hi >> 7), (a_lo >> 7)]
-#define UPDATE_2PIXELS(pi, qi, a_lo, a_hi) {                                   \
-  const __m128i a_lo7 = _mm_srai_epi16(a_lo, 7);                               \
-  const __m128i a_hi7 = _mm_srai_epi16(a_hi, 7);                               \
-  const __m128i a = _mm_packs_epi16(a_lo7, a_hi7);                             \
-  pi = _mm_adds_epi8(pi, a);                                                   \
-  qi = _mm_subs_epi8(qi, a);                                                   \
-}
-
-static void NeedsFilter(const __m128i* p1, const __m128i* p0, const __m128i* q0,
-                        const __m128i* q1, int thresh, __m128i *mask) {
-  __m128i t1 = MM_ABS(*p1, *q1);        // abs(p1 - q1)
-  *mask = _mm_set1_epi8(0xFE);
-  t1 = _mm_and_si128(t1, *mask);        // set lsb of each byte to zero
-  t1 = _mm_srli_epi16(t1, 1);           // abs(p1 - q1) / 2
-
-  *mask = MM_ABS(*p0, *q0);             // abs(p0 - q0)
-  *mask = _mm_adds_epu8(*mask, *mask);  // abs(p0 - q0) * 2
-  *mask = _mm_adds_epu8(*mask, t1);     // abs(p0 - q0) * 2 + abs(p1 - q1) / 2
-
-  t1 = _mm_set1_epi8(thresh);
-  *mask = _mm_subs_epu8(*mask, t1);     // mask <= thresh
-  *mask = _mm_cmpeq_epi8(*mask, _mm_setzero_si128());
-}
-
-//------------------------------------------------------------------------------
-// Edge filtering functions
-
-// Applies filter on 2 pixels (p0 and q0)
-static WEBP_INLINE void DoFilter2(const __m128i* p1, __m128i* p0, __m128i* q0,
-                                  const __m128i* q1, int thresh) {
-  __m128i a, mask;
-  const __m128i sign_bit = _mm_set1_epi8(0x80);
-  const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
-  const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
-
-  NeedsFilter(p1, p0, q0, q1, thresh, &mask);
-
-  // convert to signed values
-  FLIP_SIGN_BIT2(*p0, *q0);
-
-  GET_BASE_DELTA(p1s, *p0, *q0, q1s, a);
-  a = _mm_and_si128(a, mask);     // mask filter values we don't care about
-  DO_SIMPLE_FILTER(*p0, *q0, a);
-
-  // unoffset
-  FLIP_SIGN_BIT2(*p0, *q0);
-}
-
-// Applies filter on 4 pixels (p1, p0, q0 and q1)
-static WEBP_INLINE void DoFilter4(__m128i* p1, __m128i *p0,
-                                  __m128i* q0, __m128i* q1,
-                                  const __m128i* mask, int hev_thresh) {
-  __m128i not_hev;
-  __m128i t1, t2, t3;
-  const __m128i sign_bit = _mm_set1_epi8(0x80);
-
-  // compute hev mask
-  GET_NOTHEV(*p1, *p0, *q0, *q1, hev_thresh, not_hev);
-
-  // convert to signed values
-  FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
-
-  t1 = _mm_subs_epi8(*p1, *q1);        // p1 - q1
-  t1 = _mm_andnot_si128(not_hev, t1);  // hev(p1 - q1)
-  t2 = _mm_subs_epi8(*q0, *p0);        // q0 - p0
-  t1 = _mm_adds_epi8(t1, t2);          // hev(p1 - q1) + 1 * (q0 - p0)
-  t1 = _mm_adds_epi8(t1, t2);          // hev(p1 - q1) + 2 * (q0 - p0)
-  t1 = _mm_adds_epi8(t1, t2);          // hev(p1 - q1) + 3 * (q0 - p0)
-  t1 = _mm_and_si128(t1, *mask);       // mask filter values we don't care about
-
-  // Do +4 side
-  t2 = _mm_set1_epi8(4);
-  t2 = _mm_adds_epi8(t1, t2);        // 3 * (q0 - p0) + (p1 - q1) + 4
-  SIGNED_SHIFT_N(t2, 3);             // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3
-  t3 = t2;                           // save t2
-  *q0 = _mm_subs_epi8(*q0, t2);      // q0 -= t2
-
-  // Now do +3 side
-  t2 = _mm_set1_epi8(3);
-  t2 = _mm_adds_epi8(t1, t2);        // +3 instead of +4
-  SIGNED_SHIFT_N(t2, 3);             // (3 * (q0 - p0) + hev(p1 - q1) + 3) >> 3
-  *p0 = _mm_adds_epi8(*p0, t2);      // p0 += t2
-
-  t2 = _mm_set1_epi8(1);
-  t3 = _mm_adds_epi8(t3, t2);
-  SIGNED_SHIFT_N(t3, 1);             // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 4
-
-  t3 = _mm_and_si128(not_hev, t3);   // if !hev
-  *q1 = _mm_subs_epi8(*q1, t3);      // q1 -= t3
-  *p1 = _mm_adds_epi8(*p1, t3);      // p1 += t3
-
-  // unoffset
-  FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
-}
-
-// Applies filter on 6 pixels (p2, p1, p0, q0, q1 and q2)
-static WEBP_INLINE void DoFilter6(__m128i *p2, __m128i* p1, __m128i *p0,
-                                  __m128i* q0, __m128i* q1, __m128i *q2,
-                                  const __m128i* mask, int hev_thresh) {
-  __m128i a, not_hev;
-  const __m128i sign_bit = _mm_set1_epi8(0x80);
-
-  // compute hev mask
-  GET_NOTHEV(*p1, *p0, *q0, *q1, hev_thresh, not_hev);
-
-  // convert to signed values
-  FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
-  FLIP_SIGN_BIT2(*p2, *q2);
-
-  GET_BASE_DELTA(*p1, *p0, *q0, *q1, a);
-
-  { // do simple filter on pixels with hev
-    const __m128i m = _mm_andnot_si128(not_hev, *mask);
-    const __m128i f = _mm_and_si128(a, m);
-    DO_SIMPLE_FILTER(*p0, *q0, f);
-  }
-  { // do strong filter on pixels with not hev
-    const __m128i zero = _mm_setzero_si128();
-    const __m128i nine = _mm_set1_epi16(0x0900);
-    const __m128i sixty_three = _mm_set1_epi16(63);
-
-    const __m128i m = _mm_and_si128(not_hev, *mask);
-    const __m128i f = _mm_and_si128(a, m);
-    const __m128i f_lo = _mm_unpacklo_epi8(zero, f);
-    const __m128i f_hi = _mm_unpackhi_epi8(zero, f);
-
-    const __m128i f9_lo = _mm_mulhi_epi16(f_lo, nine);   // Filter (lo) * 9
-    const __m128i f9_hi = _mm_mulhi_epi16(f_hi, nine);   // Filter (hi) * 9
-    const __m128i f18_lo = _mm_add_epi16(f9_lo, f9_lo);  // Filter (lo) * 18
-    const __m128i f18_hi = _mm_add_epi16(f9_hi, f9_hi);  // Filter (hi) * 18
-
-    const __m128i a2_lo = _mm_add_epi16(f9_lo, sixty_three);  // Filter * 9 + 63
-    const __m128i a2_hi = _mm_add_epi16(f9_hi, sixty_three);  // Filter * 9 + 63
-
-    const __m128i a1_lo = _mm_add_epi16(f18_lo, sixty_three);  // F... * 18 + 63
-    const __m128i a1_hi = _mm_add_epi16(f18_hi, sixty_three);  // F... * 18 + 63
-
-    const __m128i a0_lo = _mm_add_epi16(f18_lo, a2_lo);  // Filter * 27 + 63
-    const __m128i a0_hi = _mm_add_epi16(f18_hi, a2_hi);  // Filter * 27 + 63
-
-    UPDATE_2PIXELS(*p2, *q2, a2_lo, a2_hi);
-    UPDATE_2PIXELS(*p1, *q1, a1_lo, a1_hi);
-    UPDATE_2PIXELS(*p0, *q0, a0_lo, a0_hi);
-  }
-
-  // unoffset
-  FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
-  FLIP_SIGN_BIT2(*p2, *q2);
-}
-
-// reads 8 rows across a vertical edge.
-//
-// TODO(somnath): Investigate _mm_shuffle* also see if it can be broken into
-// two Load4x4() to avoid code duplication.
-static WEBP_INLINE void Load8x4(const uint8_t* b, int stride,
-                                __m128i* p, __m128i* q) {
-  __m128i t1, t2;
-
-  // Load 0th, 1st, 4th and 5th rows
-  __m128i r0 =  _mm_cvtsi32_si128(*((int*)&b[0 * stride]));  // 03 02 01 00
-  __m128i r1 =  _mm_cvtsi32_si128(*((int*)&b[1 * stride]));  // 13 12 11 10
-  __m128i r4 =  _mm_cvtsi32_si128(*((int*)&b[4 * stride]));  // 43 42 41 40
-  __m128i r5 =  _mm_cvtsi32_si128(*((int*)&b[5 * stride]));  // 53 52 51 50
-
-  r0 = _mm_unpacklo_epi32(r0, r4);               // 43 42 41 40 03 02 01 00
-  r1 = _mm_unpacklo_epi32(r1, r5);               // 53 52 51 50 13 12 11 10
-
-  // t1 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
-  t1 = _mm_unpacklo_epi8(r0, r1);
-
-  // Load 2nd, 3rd, 6th and 7th rows
-  r0 =  _mm_cvtsi32_si128(*((int*)&b[2 * stride]));          // 23 22 21 22
-  r1 =  _mm_cvtsi32_si128(*((int*)&b[3 * stride]));          // 33 32 31 30
-  r4 =  _mm_cvtsi32_si128(*((int*)&b[6 * stride]));          // 63 62 61 60
-  r5 =  _mm_cvtsi32_si128(*((int*)&b[7 * stride]));          // 73 72 71 70
-
-  r0 = _mm_unpacklo_epi32(r0, r4);               // 63 62 61 60 23 22 21 20
-  r1 = _mm_unpacklo_epi32(r1, r5);               // 73 72 71 70 33 32 31 30
-
-  // t2 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
-  t2 = _mm_unpacklo_epi8(r0, r1);
-
-  // t1 = 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
-  // t2 = 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40
-  r0 = t1;
-  t1 = _mm_unpacklo_epi16(t1, t2);
-  t2 = _mm_unpackhi_epi16(r0, t2);
-
-  // *p = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
-  // *q = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
-  *p = _mm_unpacklo_epi32(t1, t2);
-  *q = _mm_unpackhi_epi32(t1, t2);
-}
-
-static WEBP_INLINE void Load16x4(const uint8_t* r0, const uint8_t* r8,
-                                 int stride,
-                                 __m128i* p1, __m128i* p0,
-                                 __m128i* q0, __m128i* q1) {
-  __m128i t1, t2;
-  // Assume the pixels around the edge (|) are numbered as follows
-  //                00 01 | 02 03
-  //                10 11 | 12 13
-  //                 ...  |  ...
-  //                e0 e1 | e2 e3
-  //                f0 f1 | f2 f3
-  //
-  // r0 is pointing to the 0th row (00)
-  // r8 is pointing to the 8th row (80)
-
-  // Load
-  // p1 = 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
-  // q0 = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
-  // p0 = f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80
-  // q1 = f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
-  Load8x4(r0, stride, p1, q0);
-  Load8x4(r8, stride, p0, q1);
-
-  t1 = *p1;
-  t2 = *q0;
-  // p1 = f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
-  // p0 = f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
-  // q0 = f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
-  // q1 = f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
-  *p1 = _mm_unpacklo_epi64(t1, *p0);
-  *p0 = _mm_unpackhi_epi64(t1, *p0);
-  *q0 = _mm_unpacklo_epi64(t2, *q1);
-  *q1 = _mm_unpackhi_epi64(t2, *q1);
-}
-
-static WEBP_INLINE void Store4x4(__m128i* x, uint8_t* dst, int stride) {
-  int i;
-  for (i = 0; i < 4; ++i, dst += stride) {
-    *((int32_t*)dst) = _mm_cvtsi128_si32(*x);
-    *x = _mm_srli_si128(*x, 4);
-  }
-}
-
-// Transpose back and store
-static WEBP_INLINE void Store16x4(uint8_t* r0, uint8_t* r8, int stride,
-                                  __m128i* p1, __m128i* p0,
-                                  __m128i* q0, __m128i* q1) {
-  __m128i t1;
-
-  // p0 = 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
-  // p1 = f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80
-  t1 = *p0;
-  *p0 = _mm_unpacklo_epi8(*p1, t1);
-  *p1 = _mm_unpackhi_epi8(*p1, t1);
-
-  // q0 = 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02
-  // q1 = f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
-  t1 = *q0;
-  *q0 = _mm_unpacklo_epi8(t1, *q1);
-  *q1 = _mm_unpackhi_epi8(t1, *q1);
-
-  // p0 = 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00
-  // q0 = 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40
-  t1 = *p0;
-  *p0 = _mm_unpacklo_epi16(t1, *q0);
-  *q0 = _mm_unpackhi_epi16(t1, *q0);
-
-  // p1 = b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80
-  // q1 = f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0
-  t1 = *p1;
-  *p1 = _mm_unpacklo_epi16(t1, *q1);
-  *q1 = _mm_unpackhi_epi16(t1, *q1);
-
-  Store4x4(p0, r0, stride);
-  r0 += 4 * stride;
-  Store4x4(q0, r0, stride);
-
-  Store4x4(p1, r8, stride);
-  r8 += 4 * stride;
-  Store4x4(q1, r8, stride);
-}
-
-//------------------------------------------------------------------------------
-// Simple In-loop filtering (Paragraph 15.2)
-
-static void SimpleVFilter16SSE2(uint8_t* p, int stride, int thresh) {
-  // Load
-  __m128i p1 = _mm_loadu_si128((__m128i*)&p[-2 * stride]);
-  __m128i p0 = _mm_loadu_si128((__m128i*)&p[-stride]);
-  __m128i q0 = _mm_loadu_si128((__m128i*)&p[0]);
-  __m128i q1 = _mm_loadu_si128((__m128i*)&p[stride]);
-
-  DoFilter2(&p1, &p0, &q0, &q1, thresh);
-
-  // Store
-  _mm_storeu_si128((__m128i*)&p[-stride], p0);
-  _mm_storeu_si128((__m128i*)p, q0);
-}
-
-static void SimpleHFilter16SSE2(uint8_t* p, int stride, int thresh) {
-  __m128i p1, p0, q0, q1;
-
-  p -= 2;  // beginning of p1
-
-  Load16x4(p, p + 8 * stride,  stride, &p1, &p0, &q0, &q1);
-  DoFilter2(&p1, &p0, &q0, &q1, thresh);
-  Store16x4(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1);
-}
-
-static void SimpleVFilter16iSSE2(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4 * stride;
-    SimpleVFilter16SSE2(p, stride, thresh);
-  }
-}
-
-static void SimpleHFilter16iSSE2(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4;
-    SimpleHFilter16SSE2(p, stride, thresh);
-  }
-}
-
-//------------------------------------------------------------------------------
-// Complex In-loop filtering (Paragraph 15.3)
-
-#define MAX_DIFF1(p3, p2, p1, p0, m) {                                         \
-  m = MM_ABS(p3, p2);                                                          \
-  m = _mm_max_epu8(m, MM_ABS(p2, p1));                                         \
-  m = _mm_max_epu8(m, MM_ABS(p1, p0));                                         \
-}
-
-#define MAX_DIFF2(p3, p2, p1, p0, m) {                                         \
-  m = _mm_max_epu8(m, MM_ABS(p3, p2));                                         \
-  m = _mm_max_epu8(m, MM_ABS(p2, p1));                                         \
-  m = _mm_max_epu8(m, MM_ABS(p1, p0));                                         \
-}
-
-#define LOAD_H_EDGES4(p, stride, e1, e2, e3, e4) {                             \
-  e1 = _mm_loadu_si128((__m128i*)&(p)[0 * stride]);                            \
-  e2 = _mm_loadu_si128((__m128i*)&(p)[1 * stride]);                            \
-  e3 = _mm_loadu_si128((__m128i*)&(p)[2 * stride]);                            \
-  e4 = _mm_loadu_si128((__m128i*)&(p)[3 * stride]);                            \
-}
-
-#define LOADUV_H_EDGE(p, u, v, stride) {                                       \
-  p = _mm_loadl_epi64((__m128i*)&(u)[(stride)]);                               \
-  p = _mm_unpacklo_epi64(p, _mm_loadl_epi64((__m128i*)&(v)[(stride)]));        \
-}
-
-#define LOADUV_H_EDGES4(u, v, stride, e1, e2, e3, e4) {                        \
-  LOADUV_H_EDGE(e1, u, v, 0 * stride);                                         \
-  LOADUV_H_EDGE(e2, u, v, 1 * stride);                                         \
-  LOADUV_H_EDGE(e3, u, v, 2 * stride);                                         \
-  LOADUV_H_EDGE(e4, u, v, 3 * stride);                                         \
-}
-
-#define STOREUV(p, u, v, stride) {                                             \
-  _mm_storel_epi64((__m128i*)&u[(stride)], p);                                 \
-  p = _mm_srli_si128(p, 8);                                                    \
-  _mm_storel_epi64((__m128i*)&v[(stride)], p);                                 \
-}
-
-#define COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask) {               \
-  __m128i fl_yes;                                                              \
-  const __m128i it = _mm_set1_epi8(ithresh);                                   \
-  mask = _mm_subs_epu8(mask, it);                                              \
-  mask = _mm_cmpeq_epi8(mask, _mm_setzero_si128());                            \
-  NeedsFilter(&p1, &p0, &q0, &q1, thresh, &fl_yes);                            \
-  mask = _mm_and_si128(mask, fl_yes);                                          \
-}
-
-// on macroblock edges
-static void VFilter16SSE2(uint8_t* p, int stride,
-                          int thresh, int ithresh, int hev_thresh) {
-  __m128i t1;
-  __m128i mask;
-  __m128i p2, p1, p0, q0, q1, q2;
-
-  // Load p3, p2, p1, p0
-  LOAD_H_EDGES4(p - 4 * stride, stride, t1, p2, p1, p0);
-  MAX_DIFF1(t1, p2, p1, p0, mask);
-
-  // Load q0, q1, q2, q3
-  LOAD_H_EDGES4(p, stride, q0, q1, q2, t1);
-  MAX_DIFF2(t1, q2, q1, q0, mask);
-
-  COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
-
-  // Store
-  _mm_storeu_si128((__m128i*)&p[-3 * stride], p2);
-  _mm_storeu_si128((__m128i*)&p[-2 * stride], p1);
-  _mm_storeu_si128((__m128i*)&p[-1 * stride], p0);
-  _mm_storeu_si128((__m128i*)&p[0 * stride], q0);
-  _mm_storeu_si128((__m128i*)&p[1 * stride], q1);
-  _mm_storeu_si128((__m128i*)&p[2 * stride], q2);
-}
-
-static void HFilter16SSE2(uint8_t* p, int stride,
-                          int thresh, int ithresh, int hev_thresh) {
-  __m128i mask;
-  __m128i p3, p2, p1, p0, q0, q1, q2, q3;
-
-  uint8_t* const b = p - 4;
-  Load16x4(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0);  // p3, p2, p1, p0
-  MAX_DIFF1(p3, p2, p1, p0, mask);
-
-  Load16x4(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3);  // q0, q1, q2, q3
-  MAX_DIFF2(q3, q2, q1, q0, mask);
-
-  COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
-
-  Store16x4(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0);
-  Store16x4(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3);
-}
-
-// on three inner edges
-static void VFilter16iSSE2(uint8_t* p, int stride,
-                           int thresh, int ithresh, int hev_thresh) {
-  int k;
-  __m128i mask;
-  __m128i t1, t2, p1, p0, q0, q1;
-
-  for (k = 3; k > 0; --k) {
-    // Load p3, p2, p1, p0
-    LOAD_H_EDGES4(p, stride, t2, t1, p1, p0);
-    MAX_DIFF1(t2, t1, p1, p0, mask);
-
-    p += 4 * stride;
-
-    // Load q0, q1, q2, q3
-    LOAD_H_EDGES4(p, stride, q0, q1, t1, t2);
-    MAX_DIFF2(t2, t1, q1, q0, mask);
-
-    COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-    DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
-
-    // Store
-    _mm_storeu_si128((__m128i*)&p[-2 * stride], p1);
-    _mm_storeu_si128((__m128i*)&p[-1 * stride], p0);
-    _mm_storeu_si128((__m128i*)&p[0 * stride], q0);
-    _mm_storeu_si128((__m128i*)&p[1 * stride], q1);
-  }
-}
-
-static void HFilter16iSSE2(uint8_t* p, int stride,
-                           int thresh, int ithresh, int hev_thresh) {
-  int k;
-  uint8_t* b;
-  __m128i mask;
-  __m128i t1, t2, p1, p0, q0, q1;
-
-  for (k = 3; k > 0; --k) {
-    b = p;
-    Load16x4(b, b + 8 * stride, stride, &t2, &t1, &p1, &p0);  // p3, p2, p1, p0
-    MAX_DIFF1(t2, t1, p1, p0, mask);
-
-    b += 4;  // beginning of q0
-    Load16x4(b, b + 8 * stride, stride, &q0, &q1, &t1, &t2);  // q0, q1, q2, q3
-    MAX_DIFF2(t2, t1, q1, q0, mask);
-
-    COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-    DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
-
-    b -= 2;  // beginning of p1
-    Store16x4(b, b + 8 * stride, stride, &p1, &p0, &q0, &q1);
-
-    p += 4;
-  }
-}
-
-// 8-pixels wide variant, for chroma filtering
-static void VFilter8SSE2(uint8_t* u, uint8_t* v, int stride,
-                         int thresh, int ithresh, int hev_thresh) {
-  __m128i mask;
-  __m128i t1, p2, p1, p0, q0, q1, q2;
-
-  // Load p3, p2, p1, p0
-  LOADUV_H_EDGES4(u - 4 * stride, v - 4 * stride, stride, t1, p2, p1, p0);
-  MAX_DIFF1(t1, p2, p1, p0, mask);
-
-  // Load q0, q1, q2, q3
-  LOADUV_H_EDGES4(u, v, stride, q0, q1, q2, t1);
-  MAX_DIFF2(t1, q2, q1, q0, mask);
-
-  COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
-
-  // Store
-  STOREUV(p2, u, v, -3 * stride);
-  STOREUV(p1, u, v, -2 * stride);
-  STOREUV(p0, u, v, -1 * stride);
-  STOREUV(q0, u, v, 0 * stride);
-  STOREUV(q1, u, v, 1 * stride);
-  STOREUV(q2, u, v, 2 * stride);
-}
-
-static void HFilter8SSE2(uint8_t* u, uint8_t* v, int stride,
-                         int thresh, int ithresh, int hev_thresh) {
-  __m128i mask;
-  __m128i p3, p2, p1, p0, q0, q1, q2, q3;
-
-  uint8_t* const tu = u - 4;
-  uint8_t* const tv = v - 4;
-  Load16x4(tu, tv, stride, &p3, &p2, &p1, &p0);  // p3, p2, p1, p0
-  MAX_DIFF1(p3, p2, p1, p0, mask);
-
-  Load16x4(u, v, stride, &q0, &q1, &q2, &q3);    // q0, q1, q2, q3
-  MAX_DIFF2(q3, q2, q1, q0, mask);
-
-  COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-  DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
-
-  Store16x4(tu, tv, stride, &p3, &p2, &p1, &p0);
-  Store16x4(u, v, stride, &q0, &q1, &q2, &q3);
-}
-
-static void VFilter8iSSE2(uint8_t* u, uint8_t* v, int stride,
-                          int thresh, int ithresh, int hev_thresh) {
-  __m128i mask;
-  __m128i t1, t2, p1, p0, q0, q1;
-
-  // Load p3, p2, p1, p0
-  LOADUV_H_EDGES4(u, v, stride, t2, t1, p1, p0);
-  MAX_DIFF1(t2, t1, p1, p0, mask);
-
-  u += 4 * stride;
-  v += 4 * stride;
-
-  // Load q0, q1, q2, q3
-  LOADUV_H_EDGES4(u, v, stride, q0, q1, t1, t2);
-  MAX_DIFF2(t2, t1, q1, q0, mask);
-
-  COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-  DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
-
-  // Store
-  STOREUV(p1, u, v, -2 * stride);
-  STOREUV(p0, u, v, -1 * stride);
-  STOREUV(q0, u, v, 0 * stride);
-  STOREUV(q1, u, v, 1 * stride);
-}
-
-static void HFilter8iSSE2(uint8_t* u, uint8_t* v, int stride,
-                          int thresh, int ithresh, int hev_thresh) {
-  __m128i mask;
-  __m128i t1, t2, p1, p0, q0, q1;
-  Load16x4(u, v, stride, &t2, &t1, &p1, &p0);   // p3, p2, p1, p0
-  MAX_DIFF1(t2, t1, p1, p0, mask);
-
-  u += 4;  // beginning of q0
-  v += 4;
-  Load16x4(u, v, stride, &q0, &q1, &t1, &t2);  // q0, q1, q2, q3
-  MAX_DIFF2(t2, t1, q1, q0, mask);
-
-  COMPLEX_FL_MASK(p1, p0, q0, q1, thresh, ithresh, mask);
-  DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
-
-  u -= 2;  // beginning of p1
-  v -= 2;
-  Store16x4(u, v, stride, &p1, &p0, &q0, &q1);
-}
-
-extern void VP8DspInitSSE2(void);
-
-void VP8DspInitSSE2(void) {
-  VP8Transform = TransformSSE2;
-
-  VP8VFilter16 = VFilter16SSE2;
-  VP8HFilter16 = HFilter16SSE2;
-  VP8VFilter8 = VFilter8SSE2;
-  VP8HFilter8 = HFilter8SSE2;
-  VP8VFilter16i = VFilter16iSSE2;
-  VP8HFilter16i = HFilter16iSSE2;
-  VP8VFilter8i = VFilter8iSSE2;
-  VP8HFilter8i = HFilter8iSSE2;
-
-  VP8SimpleVFilter16 = SimpleVFilter16SSE2;
-  VP8SimpleHFilter16 = SimpleHFilter16SSE2;
-  VP8SimpleVFilter16i = SimpleVFilter16iSSE2;
-  VP8SimpleHFilter16i = SimpleHFilter16iSSE2;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif   // WEBP_USE_SSE2

+ 0 - 210
drivers/webpold/dsp/dsp.h

@@ -1,210 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//   Speed-critical functions.
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_DSP_DSP_H_
-#define WEBP_DSP_DSP_H_
-
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// CPU detection
-
-#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
-#define WEBP_MSC_SSE2  // Visual C++ SSE2 targets
-#endif
-
-#if defined(__SSE2__) || defined(WEBP_MSC_SSE2)
-#define WEBP_USE_SSE2
-#endif
-
-#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__) && defined(__ARM_NEON__)
-#define WEBP_ANDROID_NEON  // Android targets that might support NEON
-#endif
-
-#if ( (defined(__ARM_NEON__) && !defined(__aarch64__)) || defined(WEBP_ANDROID_NEON)) && !defined(PSP2_ENABLED)
-#define WEBP_USE_NEON
-#endif
-
-typedef enum {
-  kSSE2,
-  kSSE3,
-  kNEON
-} CPUFeature;
-// returns true if the CPU supports the feature.
-typedef int (*VP8CPUInfo)(CPUFeature feature);
-extern VP8CPUInfo VP8GetCPUInfo;
-
-//------------------------------------------------------------------------------
-// Encoding
-
-int VP8GetAlpha(const int histo[]);
-
-// Transforms
-// VP8Idct: Does one of two inverse transforms. If do_two is set, the transforms
-//          will be done for (ref, in, dst) and (ref + 4, in + 16, dst + 4).
-typedef void (*VP8Idct)(const uint8_t* ref, const int16_t* in, uint8_t* dst,
-                        int do_two);
-typedef void (*VP8Fdct)(const uint8_t* src, const uint8_t* ref, int16_t* out);
-typedef void (*VP8WHT)(const int16_t* in, int16_t* out);
-extern VP8Idct VP8ITransform;
-extern VP8Fdct VP8FTransform;
-extern VP8WHT VP8ITransformWHT;
-extern VP8WHT VP8FTransformWHT;
-// Predictions
-// *dst is the destination block. *top and *left can be NULL.
-typedef void (*VP8IntraPreds)(uint8_t *dst, const uint8_t* left,
-                              const uint8_t* top);
-typedef void (*VP8Intra4Preds)(uint8_t *dst, const uint8_t* top);
-extern VP8Intra4Preds VP8EncPredLuma4;
-extern VP8IntraPreds VP8EncPredLuma16;
-extern VP8IntraPreds VP8EncPredChroma8;
-
-typedef int (*VP8Metric)(const uint8_t* pix, const uint8_t* ref);
-extern VP8Metric VP8SSE16x16, VP8SSE16x8, VP8SSE8x8, VP8SSE4x4;
-typedef int (*VP8WMetric)(const uint8_t* pix, const uint8_t* ref,
-                          const uint16_t* const weights);
-extern VP8WMetric VP8TDisto4x4, VP8TDisto16x16;
-
-typedef void (*VP8BlockCopy)(const uint8_t* src, uint8_t* dst);
-extern VP8BlockCopy VP8Copy4x4;
-// Quantization
-struct VP8Matrix;   // forward declaration
-typedef int (*VP8QuantizeBlock)(int16_t in[16], int16_t out[16],
-                                int n, const struct VP8Matrix* const mtx);
-extern VP8QuantizeBlock VP8EncQuantizeBlock;
-
-// Compute susceptibility based on DCT-coeff histograms:
-// the higher, the "easier" the macroblock is to compress.
-typedef int (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
-                         int start_block, int end_block);
-extern const int VP8DspScan[16 + 4 + 4];
-extern VP8CHisto VP8CollectHistogram;
-
-void VP8EncDspInit(void);   // must be called before using any of the above
-
-//------------------------------------------------------------------------------
-// Decoding
-
-typedef void (*VP8DecIdct)(const int16_t* coeffs, uint8_t* dst);
-// when doing two transforms, coeffs is actually int16_t[2][16].
-typedef void (*VP8DecIdct2)(const int16_t* coeffs, uint8_t* dst, int do_two);
-extern VP8DecIdct2 VP8Transform;
-extern VP8DecIdct VP8TransformUV;
-extern VP8DecIdct VP8TransformDC;
-extern VP8DecIdct VP8TransformDCUV;
-extern void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
-
-// *dst is the destination block, with stride BPS. Boundary samples are
-// assumed accessible when needed.
-typedef void (*VP8PredFunc)(uint8_t* dst);
-extern const VP8PredFunc VP8PredLuma16[/* NUM_B_DC_MODES */];
-extern const VP8PredFunc VP8PredChroma8[/* NUM_B_DC_MODES */];
-extern const VP8PredFunc VP8PredLuma4[/* NUM_BMODES */];
-
-// simple filter (only for luma)
-typedef void (*VP8SimpleFilterFunc)(uint8_t* p, int stride, int thresh);
-extern VP8SimpleFilterFunc VP8SimpleVFilter16;
-extern VP8SimpleFilterFunc VP8SimpleHFilter16;
-extern VP8SimpleFilterFunc VP8SimpleVFilter16i;  // filter 3 inner edges
-extern VP8SimpleFilterFunc VP8SimpleHFilter16i;
-
-// regular filter (on both macroblock edges and inner edges)
-typedef void (*VP8LumaFilterFunc)(uint8_t* luma, int stride,
-                                  int thresh, int ithresh, int hev_t);
-typedef void (*VP8ChromaFilterFunc)(uint8_t* u, uint8_t* v, int stride,
-                                    int thresh, int ithresh, int hev_t);
-// on outer edge
-extern VP8LumaFilterFunc VP8VFilter16;
-extern VP8LumaFilterFunc VP8HFilter16;
-extern VP8ChromaFilterFunc VP8VFilter8;
-extern VP8ChromaFilterFunc VP8HFilter8;
-
-// on inner edge
-extern VP8LumaFilterFunc VP8VFilter16i;   // filtering 3 inner edges altogether
-extern VP8LumaFilterFunc VP8HFilter16i;
-extern VP8ChromaFilterFunc VP8VFilter8i;  // filtering u and v altogether
-extern VP8ChromaFilterFunc VP8HFilter8i;
-
-// must be called before anything using the above
-void VP8DspInit(void);
-
-//------------------------------------------------------------------------------
-// WebP I/O
-
-#define FANCY_UPSAMPLING   // undefined to remove fancy upsampling support
-
-typedef void (*WebPUpsampleLinePairFunc)(
-    const uint8_t* top_y, const uint8_t* bottom_y,
-    const uint8_t* top_u, const uint8_t* top_v,
-    const uint8_t* cur_u, const uint8_t* cur_v,
-    uint8_t* top_dst, uint8_t* bottom_dst, int len);
-
-#ifdef FANCY_UPSAMPLING
-
-// Fancy upsampling functions to convert YUV to RGB(A) modes
-extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
-
-// Initializes SSE2 version of the fancy upsamplers.
-void WebPInitUpsamplersSSE2(void);
-
-#endif    // FANCY_UPSAMPLING
-
-// Point-sampling methods.
-typedef void (*WebPSampleLinePairFunc)(
-    const uint8_t* top_y, const uint8_t* bottom_y,
-    const uint8_t* u, const uint8_t* v,
-    uint8_t* top_dst, uint8_t* bottom_dst, int len);
-
-extern const WebPSampleLinePairFunc WebPSamplers[/* MODE_LAST */];
-
-// General function for converting two lines of ARGB or RGBA.
-// 'alpha_is_last' should be true if 0xff000000 is stored in memory as
-// as 0x00, 0x00, 0x00, 0xff (little endian).
-WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last);
-
-// YUV444->RGB converters
-typedef void (*WebPYUV444Converter)(const uint8_t* y,
-                                    const uint8_t* u, const uint8_t* v,
-                                    uint8_t* dst, int len);
-
-extern const WebPYUV444Converter WebPYUV444Converters[/* MODE_LAST */];
-
-// Main function to be called
-void WebPInitUpsamplers(void);
-
-//------------------------------------------------------------------------------
-// Pre-multiply planes with alpha values
-
-// Apply alpha pre-multiply on an rgba, bgra or argb plane of size w * h.
-// alpha_first should be 0 for argb, 1 for rgba or bgra (where alpha is last).
-extern void (*WebPApplyAlphaMultiply)(
-    uint8_t* rgba, int alpha_first, int w, int h, int stride);
-
-// Same, buf specifically for RGBA4444 format
-extern void (*WebPApplyAlphaMultiply4444)(
-    uint8_t* rgba4444, int w, int h, int stride);
-
-// To be called first before using the above.
-void WebPInitPremultiply(void);
-
-void WebPInitPremultiplySSE2(void);   // should not be called directly.
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_DSP_DSP_H_ */

+ 0 - 743
drivers/webpold/dsp/enc.c

@@ -1,743 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Speed-critical encoding functions.
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>  // for abs()
-#include "./dsp.h"
-#include "../enc/vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Compute susceptibility based on DCT-coeff histograms:
-// the higher, the "easier" the macroblock is to compress.
-
-static int ClipAlpha(int alpha) {
-  return alpha < 0 ? 0 : alpha > 255 ? 255 : alpha;
-}
-
-int VP8GetAlpha(const int histo[MAX_COEFF_THRESH + 1]) {
-  int num = 0, den = 0, val = 0;
-  int k;
-  int alpha;
-  // note: changing this loop to avoid the numerous "k + 1" slows things down.
-  for (k = 0; k < MAX_COEFF_THRESH; ++k) {
-    if (histo[k + 1]) {
-      val += histo[k + 1];
-      num += val * (k + 1);
-      den += (k + 1) * (k + 1);
-    }
-  }
-  // we scale the value to a usable [0..255] range
-  alpha = den ? 10 * num / den - 5 : 0;
-  return ClipAlpha(alpha);
-}
-
-const int VP8DspScan[16 + 4 + 4] = {
-  // Luma
-  0 +  0 * BPS,  4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS,
-  0 +  4 * BPS,  4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS,
-  0 +  8 * BPS,  4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS,
-  0 + 12 * BPS,  4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS,
-
-  0 + 0 * BPS,   4 + 0 * BPS, 0 + 4 * BPS,  4 + 4 * BPS,    // U
-  8 + 0 * BPS,  12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS     // V
-};
-
-static int CollectHistogram(const uint8_t* ref, const uint8_t* pred,
-                            int start_block, int end_block) {
-  int histo[MAX_COEFF_THRESH + 1] = { 0 };
-  int16_t out[16];
-  int j, k;
-  for (j = start_block; j < end_block; ++j) {
-    VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
-
-    // Convert coefficients to bin (within out[]).
-    for (k = 0; k < 16; ++k) {
-      const int v = abs(out[k]) >> 2;
-      out[k] = (v > MAX_COEFF_THRESH) ? MAX_COEFF_THRESH : v;
-    }
-
-    // Use bin to update histogram.
-    for (k = 0; k < 16; ++k) {
-      histo[out[k]]++;
-    }
-  }
-
-  return VP8GetAlpha(histo);
-}
-
-//------------------------------------------------------------------------------
-// run-time tables (~4k)
-
-static uint8_t clip1[255 + 510 + 1];    // clips [-255,510] to [0,255]
-
-// We declare this variable 'volatile' to prevent instruction reordering
-// and make sure it's set to true _last_ (so as to be thread-safe)
-static volatile int tables_ok = 0;
-
-static void InitTables(void) {
-  if (!tables_ok) {
-    int i;
-    for (i = -255; i <= 255 + 255; ++i) {
-      clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
-    }
-    tables_ok = 1;
-  }
-}
-
-static WEBP_INLINE uint8_t clip_8b(int v) {
-  return (!(v & ~0xff)) ? v : v < 0 ? 0 : 255;
-}
-
-//------------------------------------------------------------------------------
-// Transforms (Paragraph 14.4)
-
-#define STORE(x, y, v) \
-  dst[(x) + (y) * BPS] = clip_8b(ref[(x) + (y) * BPS] + ((v) >> 3))
-
-static const int kC1 = 20091 + (1 << 16);
-static const int kC2 = 35468;
-#define MUL(a, b) (((a) * (b)) >> 16)
-
-static WEBP_INLINE void ITransformOne(const uint8_t* ref, const int16_t* in,
-                                      uint8_t* dst) {
-  int C[4 * 4], *tmp;
-  int i;
-  tmp = C;
-  for (i = 0; i < 4; ++i) {    // vertical pass
-    const int a = in[0] + in[8];
-    const int b = in[0] - in[8];
-    const int c = MUL(in[4], kC2) - MUL(in[12], kC1);
-    const int d = MUL(in[4], kC1) + MUL(in[12], kC2);
-    tmp[0] = a + d;
-    tmp[1] = b + c;
-    tmp[2] = b - c;
-    tmp[3] = a - d;
-    tmp += 4;
-    in++;
-  }
-
-  tmp = C;
-  for (i = 0; i < 4; ++i) {    // horizontal pass
-    const int dc = tmp[0] + 4;
-    const int a =  dc +  tmp[8];
-    const int b =  dc -  tmp[8];
-    const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1);
-    const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2);
-    STORE(0, i, a + d);
-    STORE(1, i, b + c);
-    STORE(2, i, b - c);
-    STORE(3, i, a - d);
-    tmp++;
-  }
-}
-
-static void ITransform(const uint8_t* ref, const int16_t* in, uint8_t* dst,
-                       int do_two) {
-  ITransformOne(ref, in, dst);
-  if (do_two) {
-    ITransformOne(ref + 4, in + 16, dst + 4);
-  }
-}
-
-static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) {
-  int i;
-  int tmp[16];
-  for (i = 0; i < 4; ++i, src += BPS, ref += BPS) {
-    const int d0 = src[0] - ref[0];
-    const int d1 = src[1] - ref[1];
-    const int d2 = src[2] - ref[2];
-    const int d3 = src[3] - ref[3];
-    const int a0 = (d0 + d3) << 3;
-    const int a1 = (d1 + d2) << 3;
-    const int a2 = (d1 - d2) << 3;
-    const int a3 = (d0 - d3) << 3;
-    tmp[0 + i * 4] = (a0 + a1);
-    tmp[1 + i * 4] = (a2 * 2217 + a3 * 5352 + 14500) >> 12;
-    tmp[2 + i * 4] = (a0 - a1);
-    tmp[3 + i * 4] = (a3 * 2217 - a2 * 5352 +  7500) >> 12;
-  }
-  for (i = 0; i < 4; ++i) {
-    const int a0 = (tmp[0 + i] + tmp[12 + i]);
-    const int a1 = (tmp[4 + i] + tmp[ 8 + i]);
-    const int a2 = (tmp[4 + i] - tmp[ 8 + i]);
-    const int a3 = (tmp[0 + i] - tmp[12 + i]);
-    out[0 + i] = (a0 + a1 + 7) >> 4;
-    out[4 + i] = ((a2 * 2217 + a3 * 5352 + 12000) >> 16) + (a3 != 0);
-    out[8 + i] = (a0 - a1 + 7) >> 4;
-    out[12+ i] = ((a3 * 2217 - a2 * 5352 + 51000) >> 16);
-  }
-}
-
-static void ITransformWHT(const int16_t* in, int16_t* out) {
-  int tmp[16];
-  int i;
-  for (i = 0; i < 4; ++i) {
-    const int a0 = in[0 + i] + in[12 + i];
-    const int a1 = in[4 + i] + in[ 8 + i];
-    const int a2 = in[4 + i] - in[ 8 + i];
-    const int a3 = in[0 + i] - in[12 + i];
-    tmp[0  + i] = a0 + a1;
-    tmp[8  + i] = a0 - a1;
-    tmp[4  + i] = a3 + a2;
-    tmp[12 + i] = a3 - a2;
-  }
-  for (i = 0; i < 4; ++i) {
-    const int dc = tmp[0 + i * 4] + 3;    // w/ rounder
-    const int a0 = dc             + tmp[3 + i * 4];
-    const int a1 = tmp[1 + i * 4] + tmp[2 + i * 4];
-    const int a2 = tmp[1 + i * 4] - tmp[2 + i * 4];
-    const int a3 = dc             - tmp[3 + i * 4];
-    out[ 0] = (a0 + a1) >> 3;
-    out[16] = (a3 + a2) >> 3;
-    out[32] = (a0 - a1) >> 3;
-    out[48] = (a3 - a2) >> 3;
-    out += 64;
-  }
-}
-
-static void FTransformWHT(const int16_t* in, int16_t* out) {
-  int tmp[16];
-  int i;
-  for (i = 0; i < 4; ++i, in += 64) {
-    const int a0 = (in[0 * 16] + in[2 * 16]) << 2;
-    const int a1 = (in[1 * 16] + in[3 * 16]) << 2;
-    const int a2 = (in[1 * 16] - in[3 * 16]) << 2;
-    const int a3 = (in[0 * 16] - in[2 * 16]) << 2;
-    tmp[0 + i * 4] = (a0 + a1) + (a0 != 0);
-    tmp[1 + i * 4] = a3 + a2;
-    tmp[2 + i * 4] = a3 - a2;
-    tmp[3 + i * 4] = a0 - a1;
-  }
-  for (i = 0; i < 4; ++i) {
-    const int a0 = (tmp[0 + i] + tmp[8 + i]);
-    const int a1 = (tmp[4 + i] + tmp[12+ i]);
-    const int a2 = (tmp[4 + i] - tmp[12+ i]);
-    const int a3 = (tmp[0 + i] - tmp[8 + i]);
-    const int b0 = a0 + a1;
-    const int b1 = a3 + a2;
-    const int b2 = a3 - a2;
-    const int b3 = a0 - a1;
-    out[ 0 + i] = (b0 + (b0 > 0) + 3) >> 3;
-    out[ 4 + i] = (b1 + (b1 > 0) + 3) >> 3;
-    out[ 8 + i] = (b2 + (b2 > 0) + 3) >> 3;
-    out[12 + i] = (b3 + (b3 > 0) + 3) >> 3;
-  }
-}
-
-#undef MUL
-#undef STORE
-
-//------------------------------------------------------------------------------
-// Intra predictions
-
-#define DST(x, y) dst[(x) + (y) * BPS]
-
-static WEBP_INLINE void Fill(uint8_t* dst, int value, int size) {
-  int j;
-  for (j = 0; j < size; ++j) {
-    memset(dst + j * BPS, value, size);
-  }
-}
-
-static WEBP_INLINE void VerticalPred(uint8_t* dst,
-                                     const uint8_t* top, int size) {
-  int j;
-  if (top) {
-    for (j = 0; j < size; ++j) memcpy(dst + j * BPS, top, size);
-  } else {
-    Fill(dst, 127, size);
-  }
-}
-
-static WEBP_INLINE void HorizontalPred(uint8_t* dst,
-                                       const uint8_t* left, int size) {
-  if (left) {
-    int j;
-    for (j = 0; j < size; ++j) {
-      memset(dst + j * BPS, left[j], size);
-    }
-  } else {
-    Fill(dst, 129, size);
-  }
-}
-
-static WEBP_INLINE void TrueMotion(uint8_t* dst, const uint8_t* left,
-                                   const uint8_t* top, int size) {
-  int y;
-  if (left) {
-    if (top) {
-      const uint8_t* const clip = clip1 + 255 - left[-1];
-      for (y = 0; y < size; ++y) {
-        const uint8_t* const clip_table = clip + left[y];
-        int x;
-        for (x = 0; x < size; ++x) {
-          dst[x] = clip_table[top[x]];
-        }
-        dst += BPS;
-      }
-    } else {
-      HorizontalPred(dst, left, size);
-    }
-  } else {
-    // true motion without left samples (hence: with default 129 value)
-    // is equivalent to VE prediction where you just copy the top samples.
-    // Note that if top samples are not available, the default value is
-    // then 129, and not 127 as in the VerticalPred case.
-    if (top) {
-      VerticalPred(dst, top, size);
-    } else {
-      Fill(dst, 129, size);
-    }
-  }
-}
-
-static WEBP_INLINE void DCMode(uint8_t* dst, const uint8_t* left,
-                               const uint8_t* top,
-                               int size, int round, int shift) {
-  int DC = 0;
-  int j;
-  if (top) {
-    for (j = 0; j < size; ++j) DC += top[j];
-    if (left) {   // top and left present
-      for (j = 0; j < size; ++j) DC += left[j];
-    } else {      // top, but no left
-      DC += DC;
-    }
-    DC = (DC + round) >> shift;
-  } else if (left) {   // left but no top
-    for (j = 0; j < size; ++j) DC += left[j];
-    DC += DC;
-    DC = (DC + round) >> shift;
-  } else {   // no top, no left, nothing.
-    DC = 0x80;
-  }
-  Fill(dst, DC, size);
-}
-
-//------------------------------------------------------------------------------
-// Chroma 8x8 prediction (paragraph 12.2)
-
-static void IntraChromaPreds(uint8_t* dst, const uint8_t* left,
-                             const uint8_t* top) {
-  // U block
-  DCMode(C8DC8 + dst, left, top, 8, 8, 4);
-  VerticalPred(C8VE8 + dst, top, 8);
-  HorizontalPred(C8HE8 + dst, left, 8);
-  TrueMotion(C8TM8 + dst, left, top, 8);
-  // V block
-  dst += 8;
-  if (top) top += 8;
-  if (left) left += 16;
-  DCMode(C8DC8 + dst, left, top, 8, 8, 4);
-  VerticalPred(C8VE8 + dst, top, 8);
-  HorizontalPred(C8HE8 + dst, left, 8);
-  TrueMotion(C8TM8 + dst, left, top, 8);
-}
-
-//------------------------------------------------------------------------------
-// luma 16x16 prediction (paragraph 12.3)
-
-static void Intra16Preds(uint8_t* dst,
-                         const uint8_t* left, const uint8_t* top) {
-  DCMode(I16DC16 + dst, left, top, 16, 16, 5);
-  VerticalPred(I16VE16 + dst, top, 16);
-  HorizontalPred(I16HE16 + dst, left, 16);
-  TrueMotion(I16TM16 + dst, left, top, 16);
-}
-
-//------------------------------------------------------------------------------
-// luma 4x4 prediction
-
-#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
-#define AVG2(a, b) (((a) + (b) + 1) >> 1)
-
-static void VE4(uint8_t* dst, const uint8_t* top) {    // vertical
-  const uint8_t vals[4] = {
-    AVG3(top[-1], top[0], top[1]),
-    AVG3(top[ 0], top[1], top[2]),
-    AVG3(top[ 1], top[2], top[3]),
-    AVG3(top[ 2], top[3], top[4])
-  };
-  int i;
-  for (i = 0; i < 4; ++i) {
-    memcpy(dst + i * BPS, vals, 4);
-  }
-}
-
-static void HE4(uint8_t* dst, const uint8_t* top) {    // horizontal
-  const int X = top[-1];
-  const int I = top[-2];
-  const int J = top[-3];
-  const int K = top[-4];
-  const int L = top[-5];
-  *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(X, I, J);
-  *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(I, J, K);
-  *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(J, K, L);
-  *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(K, L, L);
-}
-
-static void DC4(uint8_t* dst, const uint8_t* top) {
-  uint32_t dc = 4;
-  int i;
-  for (i = 0; i < 4; ++i) dc += top[i] + top[-5 + i];
-  Fill(dst, dc >> 3, 4);
-}
-
-static void RD4(uint8_t* dst, const uint8_t* top) {
-  const int X = top[-1];
-  const int I = top[-2];
-  const int J = top[-3];
-  const int K = top[-4];
-  const int L = top[-5];
-  const int A = top[0];
-  const int B = top[1];
-  const int C = top[2];
-  const int D = top[3];
-  DST(0, 3)                                     = AVG3(J, K, L);
-  DST(0, 2) = DST(1, 3)                         = AVG3(I, J, K);
-  DST(0, 1) = DST(1, 2) = DST(2, 3)             = AVG3(X, I, J);
-  DST(0, 0) = DST(1, 1) = DST(2, 2) = DST(3, 3) = AVG3(A, X, I);
-  DST(1, 0) = DST(2, 1) = DST(3, 2)             = AVG3(B, A, X);
-  DST(2, 0) = DST(3, 1)                         = AVG3(C, B, A);
-  DST(3, 0)                                     = AVG3(D, C, B);
-}
-
-static void LD4(uint8_t* dst, const uint8_t* top) {
-  const int A = top[0];
-  const int B = top[1];
-  const int C = top[2];
-  const int D = top[3];
-  const int E = top[4];
-  const int F = top[5];
-  const int G = top[6];
-  const int H = top[7];
-  DST(0, 0)                                     = AVG3(A, B, C);
-  DST(1, 0) = DST(0, 1)                         = AVG3(B, C, D);
-  DST(2, 0) = DST(1, 1) = DST(0, 2)             = AVG3(C, D, E);
-  DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
-  DST(3, 1) = DST(2, 2) = DST(1, 3)             = AVG3(E, F, G);
-  DST(3, 2) = DST(2, 3)                         = AVG3(F, G, H);
-  DST(3, 3)                                     = AVG3(G, H, H);
-}
-
-static void VR4(uint8_t* dst, const uint8_t* top) {
-  const int X = top[-1];
-  const int I = top[-2];
-  const int J = top[-3];
-  const int K = top[-4];
-  const int A = top[0];
-  const int B = top[1];
-  const int C = top[2];
-  const int D = top[3];
-  DST(0, 0) = DST(1, 2) = AVG2(X, A);
-  DST(1, 0) = DST(2, 2) = AVG2(A, B);
-  DST(2, 0) = DST(3, 2) = AVG2(B, C);
-  DST(3, 0)             = AVG2(C, D);
-
-  DST(0, 3) =             AVG3(K, J, I);
-  DST(0, 2) =             AVG3(J, I, X);
-  DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
-  DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
-  DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
-  DST(3, 1) =             AVG3(B, C, D);
-}
-
-static void VL4(uint8_t* dst, const uint8_t* top) {
-  const int A = top[0];
-  const int B = top[1];
-  const int C = top[2];
-  const int D = top[3];
-  const int E = top[4];
-  const int F = top[5];
-  const int G = top[6];
-  const int H = top[7];
-  DST(0, 0) =             AVG2(A, B);
-  DST(1, 0) = DST(0, 2) = AVG2(B, C);
-  DST(2, 0) = DST(1, 2) = AVG2(C, D);
-  DST(3, 0) = DST(2, 2) = AVG2(D, E);
-
-  DST(0, 1) =             AVG3(A, B, C);
-  DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
-  DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
-  DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
-              DST(3, 2) = AVG3(E, F, G);
-              DST(3, 3) = AVG3(F, G, H);
-}
-
-static void HU4(uint8_t* dst, const uint8_t* top) {
-  const int I = top[-2];
-  const int J = top[-3];
-  const int K = top[-4];
-  const int L = top[-5];
-  DST(0, 0) =             AVG2(I, J);
-  DST(2, 0) = DST(0, 1) = AVG2(J, K);
-  DST(2, 1) = DST(0, 2) = AVG2(K, L);
-  DST(1, 0) =             AVG3(I, J, K);
-  DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
-  DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
-  DST(3, 2) = DST(2, 2) =
-  DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
-}
-
-static void HD4(uint8_t* dst, const uint8_t* top) {
-  const int X = top[-1];
-  const int I = top[-2];
-  const int J = top[-3];
-  const int K = top[-4];
-  const int L = top[-5];
-  const int A = top[0];
-  const int B = top[1];
-  const int C = top[2];
-
-  DST(0, 0) = DST(2, 1) = AVG2(I, X);
-  DST(0, 1) = DST(2, 2) = AVG2(J, I);
-  DST(0, 2) = DST(2, 3) = AVG2(K, J);
-  DST(0, 3)             = AVG2(L, K);
-
-  DST(3, 0)             = AVG3(A, B, C);
-  DST(2, 0)             = AVG3(X, A, B);
-  DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
-  DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
-  DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
-  DST(1, 3)             = AVG3(L, K, J);
-}
-
-static void TM4(uint8_t* dst, const uint8_t* top) {
-  int x, y;
-  const uint8_t* const clip = clip1 + 255 - top[-1];
-  for (y = 0; y < 4; ++y) {
-    const uint8_t* const clip_table = clip + top[-2 - y];
-    for (x = 0; x < 4; ++x) {
-      dst[x] = clip_table[top[x]];
-    }
-    dst += BPS;
-  }
-}
-
-#undef DST
-#undef AVG3
-#undef AVG2
-
-// Left samples are top[-5 .. -2], top_left is top[-1], top are
-// located at top[0..3], and top right is top[4..7]
-static void Intra4Preds(uint8_t* dst, const uint8_t* top) {
-  DC4(I4DC4 + dst, top);
-  TM4(I4TM4 + dst, top);
-  VE4(I4VE4 + dst, top);
-  HE4(I4HE4 + dst, top);
-  RD4(I4RD4 + dst, top);
-  VR4(I4VR4 + dst, top);
-  LD4(I4LD4 + dst, top);
-  VL4(I4VL4 + dst, top);
-  HD4(I4HD4 + dst, top);
-  HU4(I4HU4 + dst, top);
-}
-
-//------------------------------------------------------------------------------
-// Metric
-
-static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b,
-                              int w, int h) {
-  int count = 0;
-  int y, x;
-  for (y = 0; y < h; ++y) {
-    for (x = 0; x < w; ++x) {
-      const int diff = (int)a[x] - b[x];
-      count += diff * diff;
-    }
-    a += BPS;
-    b += BPS;
-  }
-  return count;
-}
-
-static int SSE16x16(const uint8_t* a, const uint8_t* b) {
-  return GetSSE(a, b, 16, 16);
-}
-static int SSE16x8(const uint8_t* a, const uint8_t* b) {
-  return GetSSE(a, b, 16, 8);
-}
-static int SSE8x8(const uint8_t* a, const uint8_t* b) {
-  return GetSSE(a, b, 8, 8);
-}
-static int SSE4x4(const uint8_t* a, const uint8_t* b) {
-  return GetSSE(a, b, 4, 4);
-}
-
-//------------------------------------------------------------------------------
-// Texture distortion
-//
-// We try to match the spectral content (weighted) between source and
-// reconstructed samples.
-
-// Hadamard transform
-// Returns the weighted sum of the absolute value of transformed coefficients.
-static int TTransform(const uint8_t* in, const uint16_t* w) {
-  int sum = 0;
-  int tmp[16];
-  int i;
-  // horizontal pass
-  for (i = 0; i < 4; ++i, in += BPS) {
-    const int a0 = (in[0] + in[2]) << 2;
-    const int a1 = (in[1] + in[3]) << 2;
-    const int a2 = (in[1] - in[3]) << 2;
-    const int a3 = (in[0] - in[2]) << 2;
-    tmp[0 + i * 4] = a0 + a1 + (a0 != 0);
-    tmp[1 + i * 4] = a3 + a2;
-    tmp[2 + i * 4] = a3 - a2;
-    tmp[3 + i * 4] = a0 - a1;
-  }
-  // vertical pass
-  for (i = 0; i < 4; ++i, ++w) {
-    const int a0 = (tmp[0 + i] + tmp[8 + i]);
-    const int a1 = (tmp[4 + i] + tmp[12+ i]);
-    const int a2 = (tmp[4 + i] - tmp[12+ i]);
-    const int a3 = (tmp[0 + i] - tmp[8 + i]);
-    const int b0 = a0 + a1;
-    const int b1 = a3 + a2;
-    const int b2 = a3 - a2;
-    const int b3 = a0 - a1;
-    // abs((b + (b<0) + 3) >> 3) = (abs(b) + 3) >> 3
-    sum += w[ 0] * ((abs(b0) + 3) >> 3);
-    sum += w[ 4] * ((abs(b1) + 3) >> 3);
-    sum += w[ 8] * ((abs(b2) + 3) >> 3);
-    sum += w[12] * ((abs(b3) + 3) >> 3);
-  }
-  return sum;
-}
-
-static int Disto4x4(const uint8_t* const a, const uint8_t* const b,
-                    const uint16_t* const w) {
-  const int sum1 = TTransform(a, w);
-  const int sum2 = TTransform(b, w);
-  return (abs(sum2 - sum1) + 8) >> 4;
-}
-
-static int Disto16x16(const uint8_t* const a, const uint8_t* const b,
-                      const uint16_t* const w) {
-  int D = 0;
-  int x, y;
-  for (y = 0; y < 16 * BPS; y += 4 * BPS) {
-    for (x = 0; x < 16; x += 4) {
-      D += Disto4x4(a + x + y, b + x + y, w);
-    }
-  }
-  return D;
-}
-
-//------------------------------------------------------------------------------
-// Quantization
-//
-
-static const uint8_t kZigzag[16] = {
-  0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
-};
-
-// Simple quantization
-static int QuantizeBlock(int16_t in[16], int16_t out[16],
-                         int n, const VP8Matrix* const mtx) {
-  int last = -1;
-  for (; n < 16; ++n) {
-    const int j = kZigzag[n];
-    const int sign = (in[j] < 0);
-    int coeff = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
-    if (coeff > 2047) coeff = 2047;
-    if (coeff > mtx->zthresh_[j]) {
-      const int Q = mtx->q_[j];
-      const int iQ = mtx->iq_[j];
-      const int B = mtx->bias_[j];
-      out[n] = QUANTDIV(coeff, iQ, B);
-      if (sign) out[n] = -out[n];
-      in[j] = out[n] * Q;
-      if (out[n]) last = n;
-    } else {
-      out[n] = 0;
-      in[j] = 0;
-    }
-  }
-  return (last >= 0);
-}
-
-//------------------------------------------------------------------------------
-// Block copy
-
-static WEBP_INLINE void Copy(const uint8_t* src, uint8_t* dst, int size) {
-  int y;
-  for (y = 0; y < size; ++y) {
-    memcpy(dst, src, size);
-    src += BPS;
-    dst += BPS;
-  }
-}
-
-static void Copy4x4(const uint8_t* src, uint8_t* dst) { Copy(src, dst, 4); }
-
-//------------------------------------------------------------------------------
-// Initialization
-
-// Speed-critical function pointers. We have to initialize them to the default
-// implementations within VP8EncDspInit().
-VP8CHisto VP8CollectHistogram;
-VP8Idct VP8ITransform;
-VP8Fdct VP8FTransform;
-VP8WHT VP8ITransformWHT;
-VP8WHT VP8FTransformWHT;
-VP8Intra4Preds VP8EncPredLuma4;
-VP8IntraPreds VP8EncPredLuma16;
-VP8IntraPreds VP8EncPredChroma8;
-VP8Metric VP8SSE16x16;
-VP8Metric VP8SSE8x8;
-VP8Metric VP8SSE16x8;
-VP8Metric VP8SSE4x4;
-VP8WMetric VP8TDisto4x4;
-VP8WMetric VP8TDisto16x16;
-VP8QuantizeBlock VP8EncQuantizeBlock;
-VP8BlockCopy VP8Copy4x4;
-
-extern void VP8EncDspInitSSE2(void);
-
-void VP8EncDspInit(void) {
-  InitTables();
-
-  // default C implementations
-  VP8CollectHistogram = CollectHistogram;
-  VP8ITransform = ITransform;
-  VP8FTransform = FTransform;
-  VP8ITransformWHT = ITransformWHT;
-  VP8FTransformWHT = FTransformWHT;
-  VP8EncPredLuma4 = Intra4Preds;
-  VP8EncPredLuma16 = Intra16Preds;
-  VP8EncPredChroma8 = IntraChromaPreds;
-  VP8SSE16x16 = SSE16x16;
-  VP8SSE8x8 = SSE8x8;
-  VP8SSE16x8 = SSE16x8;
-  VP8SSE4x4 = SSE4x4;
-  VP8TDisto4x4 = Disto4x4;
-  VP8TDisto16x16 = Disto16x16;
-  VP8EncQuantizeBlock = QuantizeBlock;
-  VP8Copy4x4 = Copy4x4;
-
-  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
-  if (VP8GetCPUInfo) {
-#if defined(WEBP_USE_SSE2)
-    if (VP8GetCPUInfo(kSSE2)) {
-      VP8EncDspInitSSE2();
-    }
-#endif
-  }
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 837
drivers/webpold/dsp/enc_sse2.c

@@ -1,837 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// SSE2 version of speed-critical encoding functions.
-//
-// Author: Christian Duvivier ([email protected])
-
-#include "./dsp.h"
-
-#if defined(WEBP_USE_SSE2)
-#include <stdlib.h>  // for abs()
-#include <emmintrin.h>
-
-#include "../enc/vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Compute susceptibility based on DCT-coeff histograms:
-// the higher, the "easier" the macroblock is to compress.
-
-static int CollectHistogramSSE2(const uint8_t* ref, const uint8_t* pred,
-                                int start_block, int end_block) {
-  int histo[MAX_COEFF_THRESH + 1] = { 0 };
-  int16_t out[16];
-  int j, k;
-  const __m128i max_coeff_thresh = _mm_set1_epi16(MAX_COEFF_THRESH);
-  for (j = start_block; j < end_block; ++j) {
-    VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
-
-    // Convert coefficients to bin (within out[]).
-    {
-      // Load.
-      const __m128i out0 = _mm_loadu_si128((__m128i*)&out[0]);
-      const __m128i out1 = _mm_loadu_si128((__m128i*)&out[8]);
-      // sign(out) = out >> 15  (0x0000 if positive, 0xffff if negative)
-      const __m128i sign0 = _mm_srai_epi16(out0, 15);
-      const __m128i sign1 = _mm_srai_epi16(out1, 15);
-      // abs(out) = (out ^ sign) - sign
-      const __m128i xor0 = _mm_xor_si128(out0, sign0);
-      const __m128i xor1 = _mm_xor_si128(out1, sign1);
-      const __m128i abs0 = _mm_sub_epi16(xor0, sign0);
-      const __m128i abs1 = _mm_sub_epi16(xor1, sign1);
-      // v = abs(out) >> 2
-      const __m128i v0 = _mm_srai_epi16(abs0, 2);
-      const __m128i v1 = _mm_srai_epi16(abs1, 2);
-      // bin = min(v, MAX_COEFF_THRESH)
-      const __m128i bin0 = _mm_min_epi16(v0, max_coeff_thresh);
-      const __m128i bin1 = _mm_min_epi16(v1, max_coeff_thresh);
-      // Store.
-      _mm_storeu_si128((__m128i*)&out[0], bin0);
-      _mm_storeu_si128((__m128i*)&out[8], bin1);
-    }
-
-    // Use bin to update histogram.
-    for (k = 0; k < 16; ++k) {
-      histo[out[k]]++;
-    }
-  }
-
-  return VP8GetAlpha(histo);
-}
-
-//------------------------------------------------------------------------------
-// Transforms (Paragraph 14.4)
-
-// Does one or two inverse transforms.
-static void ITransformSSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
-                           int do_two) {
-  // This implementation makes use of 16-bit fixed point versions of two
-  // multiply constants:
-  //    K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
-  //    K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16
-  //
-  // To be able to use signed 16-bit integers, we use the following trick to
-  // have constants within range:
-  // - Associated constants are obtained by subtracting the 16-bit fixed point
-  //   version of one:
-  //      k = K - (1 << 16)  =>  K = k + (1 << 16)
-  //      K1 = 85267  =>  k1 =  20091
-  //      K2 = 35468  =>  k2 = -30068
-  // - The multiplication of a variable by a constant become the sum of the
-  //   variable and the multiplication of that variable by the associated
-  //   constant:
-  //      (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x
-  const __m128i k1 = _mm_set1_epi16(20091);
-  const __m128i k2 = _mm_set1_epi16(-30068);
-  __m128i T0, T1, T2, T3;
-
-  // Load and concatenate the transform coefficients (we'll do two inverse
-  // transforms in parallel). In the case of only one inverse transform, the
-  // second half of the vectors will just contain random value we'll never
-  // use nor store.
-  __m128i in0, in1, in2, in3;
-  {
-    in0 = _mm_loadl_epi64((__m128i*)&in[0]);
-    in1 = _mm_loadl_epi64((__m128i*)&in[4]);
-    in2 = _mm_loadl_epi64((__m128i*)&in[8]);
-    in3 = _mm_loadl_epi64((__m128i*)&in[12]);
-    // a00 a10 a20 a30   x x x x
-    // a01 a11 a21 a31   x x x x
-    // a02 a12 a22 a32   x x x x
-    // a03 a13 a23 a33   x x x x
-    if (do_two) {
-      const __m128i inB0 = _mm_loadl_epi64((__m128i*)&in[16]);
-      const __m128i inB1 = _mm_loadl_epi64((__m128i*)&in[20]);
-      const __m128i inB2 = _mm_loadl_epi64((__m128i*)&in[24]);
-      const __m128i inB3 = _mm_loadl_epi64((__m128i*)&in[28]);
-      in0 = _mm_unpacklo_epi64(in0, inB0);
-      in1 = _mm_unpacklo_epi64(in1, inB1);
-      in2 = _mm_unpacklo_epi64(in2, inB2);
-      in3 = _mm_unpacklo_epi64(in3, inB3);
-      // a00 a10 a20 a30   b00 b10 b20 b30
-      // a01 a11 a21 a31   b01 b11 b21 b31
-      // a02 a12 a22 a32   b02 b12 b22 b32
-      // a03 a13 a23 a33   b03 b13 b23 b33
-    }
-  }
-
-  // Vertical pass and subsequent transpose.
-  {
-    // First pass, c and d calculations are longer because of the "trick"
-    // multiplications.
-    const __m128i a = _mm_add_epi16(in0, in2);
-    const __m128i b = _mm_sub_epi16(in0, in2);
-    // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3
-    const __m128i c1 = _mm_mulhi_epi16(in1, k2);
-    const __m128i c2 = _mm_mulhi_epi16(in3, k1);
-    const __m128i c3 = _mm_sub_epi16(in1, in3);
-    const __m128i c4 = _mm_sub_epi16(c1, c2);
-    const __m128i c = _mm_add_epi16(c3, c4);
-    // d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3
-    const __m128i d1 = _mm_mulhi_epi16(in1, k1);
-    const __m128i d2 = _mm_mulhi_epi16(in3, k2);
-    const __m128i d3 = _mm_add_epi16(in1, in3);
-    const __m128i d4 = _mm_add_epi16(d1, d2);
-    const __m128i d = _mm_add_epi16(d3, d4);
-
-    // Second pass.
-    const __m128i tmp0 = _mm_add_epi16(a, d);
-    const __m128i tmp1 = _mm_add_epi16(b, c);
-    const __m128i tmp2 = _mm_sub_epi16(b, c);
-    const __m128i tmp3 = _mm_sub_epi16(a, d);
-
-    // Transpose the two 4x4.
-    // a00 a01 a02 a03   b00 b01 b02 b03
-    // a10 a11 a12 a13   b10 b11 b12 b13
-    // a20 a21 a22 a23   b20 b21 b22 b23
-    // a30 a31 a32 a33   b30 b31 b32 b33
-    const __m128i transpose0_0 = _mm_unpacklo_epi16(tmp0, tmp1);
-    const __m128i transpose0_1 = _mm_unpacklo_epi16(tmp2, tmp3);
-    const __m128i transpose0_2 = _mm_unpackhi_epi16(tmp0, tmp1);
-    const __m128i transpose0_3 = _mm_unpackhi_epi16(tmp2, tmp3);
-    // a00 a10 a01 a11   a02 a12 a03 a13
-    // a20 a30 a21 a31   a22 a32 a23 a33
-    // b00 b10 b01 b11   b02 b12 b03 b13
-    // b20 b30 b21 b31   b22 b32 b23 b33
-    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
-    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
-    // a00 a10 a20 a30 a01 a11 a21 a31
-    // b00 b10 b20 b30 b01 b11 b21 b31
-    // a02 a12 a22 a32 a03 a13 a23 a33
-    // b02 b12 a22 b32 b03 b13 b23 b33
-    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
-    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
-    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
-    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
-    // a00 a10 a20 a30   b00 b10 b20 b30
-    // a01 a11 a21 a31   b01 b11 b21 b31
-    // a02 a12 a22 a32   b02 b12 b22 b32
-    // a03 a13 a23 a33   b03 b13 b23 b33
-  }
-
-  // Horizontal pass and subsequent transpose.
-  {
-    // First pass, c and d calculations are longer because of the "trick"
-    // multiplications.
-    const __m128i four = _mm_set1_epi16(4);
-    const __m128i dc = _mm_add_epi16(T0, four);
-    const __m128i a =  _mm_add_epi16(dc, T2);
-    const __m128i b =  _mm_sub_epi16(dc, T2);
-    // c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3
-    const __m128i c1 = _mm_mulhi_epi16(T1, k2);
-    const __m128i c2 = _mm_mulhi_epi16(T3, k1);
-    const __m128i c3 = _mm_sub_epi16(T1, T3);
-    const __m128i c4 = _mm_sub_epi16(c1, c2);
-    const __m128i c = _mm_add_epi16(c3, c4);
-    // d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3
-    const __m128i d1 = _mm_mulhi_epi16(T1, k1);
-    const __m128i d2 = _mm_mulhi_epi16(T3, k2);
-    const __m128i d3 = _mm_add_epi16(T1, T3);
-    const __m128i d4 = _mm_add_epi16(d1, d2);
-    const __m128i d = _mm_add_epi16(d3, d4);
-
-    // Second pass.
-    const __m128i tmp0 = _mm_add_epi16(a, d);
-    const __m128i tmp1 = _mm_add_epi16(b, c);
-    const __m128i tmp2 = _mm_sub_epi16(b, c);
-    const __m128i tmp3 = _mm_sub_epi16(a, d);
-    const __m128i shifted0 = _mm_srai_epi16(tmp0, 3);
-    const __m128i shifted1 = _mm_srai_epi16(tmp1, 3);
-    const __m128i shifted2 = _mm_srai_epi16(tmp2, 3);
-    const __m128i shifted3 = _mm_srai_epi16(tmp3, 3);
-
-    // Transpose the two 4x4.
-    // a00 a01 a02 a03   b00 b01 b02 b03
-    // a10 a11 a12 a13   b10 b11 b12 b13
-    // a20 a21 a22 a23   b20 b21 b22 b23
-    // a30 a31 a32 a33   b30 b31 b32 b33
-    const __m128i transpose0_0 = _mm_unpacklo_epi16(shifted0, shifted1);
-    const __m128i transpose0_1 = _mm_unpacklo_epi16(shifted2, shifted3);
-    const __m128i transpose0_2 = _mm_unpackhi_epi16(shifted0, shifted1);
-    const __m128i transpose0_3 = _mm_unpackhi_epi16(shifted2, shifted3);
-    // a00 a10 a01 a11   a02 a12 a03 a13
-    // a20 a30 a21 a31   a22 a32 a23 a33
-    // b00 b10 b01 b11   b02 b12 b03 b13
-    // b20 b30 b21 b31   b22 b32 b23 b33
-    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
-    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
-    // a00 a10 a20 a30 a01 a11 a21 a31
-    // b00 b10 b20 b30 b01 b11 b21 b31
-    // a02 a12 a22 a32 a03 a13 a23 a33
-    // b02 b12 a22 b32 b03 b13 b23 b33
-    T0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
-    T1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
-    T2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
-    T3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
-    // a00 a10 a20 a30   b00 b10 b20 b30
-    // a01 a11 a21 a31   b01 b11 b21 b31
-    // a02 a12 a22 a32   b02 b12 b22 b32
-    // a03 a13 a23 a33   b03 b13 b23 b33
-  }
-
-  // Add inverse transform to 'ref' and store.
-  {
-    const __m128i zero = _mm_set1_epi16(0);
-    // Load the reference(s).
-    __m128i ref0, ref1, ref2, ref3;
-    if (do_two) {
-      // Load eight bytes/pixels per line.
-      ref0 = _mm_loadl_epi64((__m128i*)&ref[0 * BPS]);
-      ref1 = _mm_loadl_epi64((__m128i*)&ref[1 * BPS]);
-      ref2 = _mm_loadl_epi64((__m128i*)&ref[2 * BPS]);
-      ref3 = _mm_loadl_epi64((__m128i*)&ref[3 * BPS]);
-    } else {
-      // Load four bytes/pixels per line.
-      ref0 = _mm_cvtsi32_si128(*(int*)&ref[0 * BPS]);
-      ref1 = _mm_cvtsi32_si128(*(int*)&ref[1 * BPS]);
-      ref2 = _mm_cvtsi32_si128(*(int*)&ref[2 * BPS]);
-      ref3 = _mm_cvtsi32_si128(*(int*)&ref[3 * BPS]);
-    }
-    // Convert to 16b.
-    ref0 = _mm_unpacklo_epi8(ref0, zero);
-    ref1 = _mm_unpacklo_epi8(ref1, zero);
-    ref2 = _mm_unpacklo_epi8(ref2, zero);
-    ref3 = _mm_unpacklo_epi8(ref3, zero);
-    // Add the inverse transform(s).
-    ref0 = _mm_add_epi16(ref0, T0);
-    ref1 = _mm_add_epi16(ref1, T1);
-    ref2 = _mm_add_epi16(ref2, T2);
-    ref3 = _mm_add_epi16(ref3, T3);
-    // Unsigned saturate to 8b.
-    ref0 = _mm_packus_epi16(ref0, ref0);
-    ref1 = _mm_packus_epi16(ref1, ref1);
-    ref2 = _mm_packus_epi16(ref2, ref2);
-    ref3 = _mm_packus_epi16(ref3, ref3);
-    // Store the results.
-    if (do_two) {
-      // Store eight bytes/pixels per line.
-      _mm_storel_epi64((__m128i*)&dst[0 * BPS], ref0);
-      _mm_storel_epi64((__m128i*)&dst[1 * BPS], ref1);
-      _mm_storel_epi64((__m128i*)&dst[2 * BPS], ref2);
-      _mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
-    } else {
-      // Store four bytes/pixels per line.
-      *((int32_t *)&dst[0 * BPS]) = _mm_cvtsi128_si32(ref0);
-      *((int32_t *)&dst[1 * BPS]) = _mm_cvtsi128_si32(ref1);
-      *((int32_t *)&dst[2 * BPS]) = _mm_cvtsi128_si32(ref2);
-      *((int32_t *)&dst[3 * BPS]) = _mm_cvtsi128_si32(ref3);
-    }
-  }
-}
-
-static void FTransformSSE2(const uint8_t* src, const uint8_t* ref,
-                           int16_t* out) {
-  const __m128i zero = _mm_setzero_si128();
-  const __m128i seven = _mm_set1_epi16(7);
-  const __m128i k7500 = _mm_set1_epi32(7500);
-  const __m128i k14500 = _mm_set1_epi32(14500);
-  const __m128i k51000 = _mm_set1_epi32(51000);
-  const __m128i k12000_plus_one = _mm_set1_epi32(12000 + (1 << 16));
-  const __m128i k5352_2217 = _mm_set_epi16(5352,  2217, 5352,  2217,
-                                           5352,  2217, 5352,  2217);
-  const __m128i k2217_5352 = _mm_set_epi16(2217, -5352, 2217, -5352,
-                                           2217, -5352, 2217, -5352);
-
-  __m128i v01, v32;
-
-  // Difference between src and ref and initial transpose.
-  {
-    // Load src and convert to 16b.
-    const __m128i src0 = _mm_loadl_epi64((__m128i*)&src[0 * BPS]);
-    const __m128i src1 = _mm_loadl_epi64((__m128i*)&src[1 * BPS]);
-    const __m128i src2 = _mm_loadl_epi64((__m128i*)&src[2 * BPS]);
-    const __m128i src3 = _mm_loadl_epi64((__m128i*)&src[3 * BPS]);
-    const __m128i src_0 = _mm_unpacklo_epi8(src0, zero);
-    const __m128i src_1 = _mm_unpacklo_epi8(src1, zero);
-    const __m128i src_2 = _mm_unpacklo_epi8(src2, zero);
-    const __m128i src_3 = _mm_unpacklo_epi8(src3, zero);
-    // Load ref and convert to 16b.
-    const __m128i ref0 = _mm_loadl_epi64((__m128i*)&ref[0 * BPS]);
-    const __m128i ref1 = _mm_loadl_epi64((__m128i*)&ref[1 * BPS]);
-    const __m128i ref2 = _mm_loadl_epi64((__m128i*)&ref[2 * BPS]);
-    const __m128i ref3 = _mm_loadl_epi64((__m128i*)&ref[3 * BPS]);
-    const __m128i ref_0 = _mm_unpacklo_epi8(ref0, zero);
-    const __m128i ref_1 = _mm_unpacklo_epi8(ref1, zero);
-    const __m128i ref_2 = _mm_unpacklo_epi8(ref2, zero);
-    const __m128i ref_3 = _mm_unpacklo_epi8(ref3, zero);
-    // Compute difference.
-    const __m128i diff0 = _mm_sub_epi16(src_0, ref_0);
-    const __m128i diff1 = _mm_sub_epi16(src_1, ref_1);
-    const __m128i diff2 = _mm_sub_epi16(src_2, ref_2);
-    const __m128i diff3 = _mm_sub_epi16(src_3, ref_3);
-
-    // Transpose.
-    // 00 01 02 03   0 0 0 0
-    // 10 11 12 13   0 0 0 0
-    // 20 21 22 23   0 0 0 0
-    // 30 31 32 33   0 0 0 0
-    const __m128i transpose0_0 = _mm_unpacklo_epi16(diff0, diff1);
-    const __m128i transpose0_1 = _mm_unpacklo_epi16(diff2, diff3);
-    // 00 10 01 11   02 12 03 13
-    // 20 30 21 31   22 32 23 33
-    const __m128i v23 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
-    v01 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
-    v32 = _mm_shuffle_epi32(v23, _MM_SHUFFLE(1, 0, 3, 2));
-    // a02 a12 a22 a32   a03 a13 a23 a33
-    // a00 a10 a20 a30   a01 a11 a21 a31
-    // a03 a13 a23 a33   a02 a12 a22 a32
-  }
-
-  // First pass and subsequent transpose.
-  {
-    // Same operations are done on the (0,3) and (1,2) pairs.
-    // b0 = (a0 + a3) << 3
-    // b1 = (a1 + a2) << 3
-    // b3 = (a0 - a3) << 3
-    // b2 = (a1 - a2) << 3
-    const __m128i a01 = _mm_add_epi16(v01, v32);
-    const __m128i a32 = _mm_sub_epi16(v01, v32);
-    const __m128i b01 = _mm_slli_epi16(a01, 3);
-    const __m128i b32 = _mm_slli_epi16(a32, 3);
-    const __m128i b11 = _mm_unpackhi_epi64(b01, b01);
-    const __m128i b22 = _mm_unpackhi_epi64(b32, b32);
-
-    // e0 = b0 + b1
-    // e2 = b0 - b1
-    const __m128i e0 = _mm_add_epi16(b01, b11);
-    const __m128i e2 = _mm_sub_epi16(b01, b11);
-    const __m128i e02 = _mm_unpacklo_epi64(e0, e2);
-
-    // e1 = (b3 * 5352 + b2 * 2217 + 14500) >> 12
-    // e3 = (b3 * 2217 - b2 * 5352 +  7500) >> 12
-    const __m128i b23 = _mm_unpacklo_epi16(b22, b32);
-    const __m128i c1 = _mm_madd_epi16(b23, k5352_2217);
-    const __m128i c3 = _mm_madd_epi16(b23, k2217_5352);
-    const __m128i d1 = _mm_add_epi32(c1, k14500);
-    const __m128i d3 = _mm_add_epi32(c3, k7500);
-    const __m128i e1 = _mm_srai_epi32(d1, 12);
-    const __m128i e3 = _mm_srai_epi32(d3, 12);
-    const __m128i e13 = _mm_packs_epi32(e1, e3);
-
-    // Transpose.
-    // 00 01 02 03  20 21 22 23
-    // 10 11 12 13  30 31 32 33
-    const __m128i transpose0_0 = _mm_unpacklo_epi16(e02, e13);
-    const __m128i transpose0_1 = _mm_unpackhi_epi16(e02, e13);
-    // 00 10 01 11   02 12 03 13
-    // 20 30 21 31   22 32 23 33
-    const __m128i v23 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
-    v01 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
-    v32 = _mm_shuffle_epi32(v23, _MM_SHUFFLE(1, 0, 3, 2));
-    // 02 12 22 32   03 13 23 33
-    // 00 10 20 30   01 11 21 31
-    // 03 13 23 33   02 12 22 32
-  }
-
-  // Second pass
-  {
-    // Same operations are done on the (0,3) and (1,2) pairs.
-    // a0 = v0 + v3
-    // a1 = v1 + v2
-    // a3 = v0 - v3
-    // a2 = v1 - v2
-    const __m128i a01 = _mm_add_epi16(v01, v32);
-    const __m128i a32 = _mm_sub_epi16(v01, v32);
-    const __m128i a11 = _mm_unpackhi_epi64(a01, a01);
-    const __m128i a22 = _mm_unpackhi_epi64(a32, a32);
-
-    // d0 = (a0 + a1 + 7) >> 4;
-    // d2 = (a0 - a1 + 7) >> 4;
-    const __m128i b0 = _mm_add_epi16(a01, a11);
-    const __m128i b2 = _mm_sub_epi16(a01, a11);
-    const __m128i c0 = _mm_add_epi16(b0, seven);
-    const __m128i c2 = _mm_add_epi16(b2, seven);
-    const __m128i d0 = _mm_srai_epi16(c0, 4);
-    const __m128i d2 = _mm_srai_epi16(c2, 4);
-
-    // f1 = ((b3 * 5352 + b2 * 2217 + 12000) >> 16)
-    // f3 = ((b3 * 2217 - b2 * 5352 + 51000) >> 16)
-    const __m128i b23 = _mm_unpacklo_epi16(a22, a32);
-    const __m128i c1 = _mm_madd_epi16(b23, k5352_2217);
-    const __m128i c3 = _mm_madd_epi16(b23, k2217_5352);
-    const __m128i d1 = _mm_add_epi32(c1, k12000_plus_one);
-    const __m128i d3 = _mm_add_epi32(c3, k51000);
-    const __m128i e1 = _mm_srai_epi32(d1, 16);
-    const __m128i e3 = _mm_srai_epi32(d3, 16);
-    const __m128i f1 = _mm_packs_epi32(e1, e1);
-    const __m128i f3 = _mm_packs_epi32(e3, e3);
-    // f1 = f1 + (a3 != 0);
-    // The compare will return (0xffff, 0) for (==0, !=0). To turn that into the
-    // desired (0, 1), we add one earlier through k12000_plus_one.
-    const __m128i g1 = _mm_add_epi16(f1, _mm_cmpeq_epi16(a32, zero));
-
-    _mm_storel_epi64((__m128i*)&out[ 0], d0);
-    _mm_storel_epi64((__m128i*)&out[ 4], g1);
-    _mm_storel_epi64((__m128i*)&out[ 8], d2);
-    _mm_storel_epi64((__m128i*)&out[12], f3);
-  }
-}
-
-//------------------------------------------------------------------------------
-// Metric
-
-static int SSE4x4SSE2(const uint8_t* a, const uint8_t* b) {
-  const __m128i zero = _mm_set1_epi16(0);
-
-  // Load values.
-  const __m128i a0 = _mm_loadl_epi64((__m128i*)&a[BPS * 0]);
-  const __m128i a1 = _mm_loadl_epi64((__m128i*)&a[BPS * 1]);
-  const __m128i a2 = _mm_loadl_epi64((__m128i*)&a[BPS * 2]);
-  const __m128i a3 = _mm_loadl_epi64((__m128i*)&a[BPS * 3]);
-  const __m128i b0 = _mm_loadl_epi64((__m128i*)&b[BPS * 0]);
-  const __m128i b1 = _mm_loadl_epi64((__m128i*)&b[BPS * 1]);
-  const __m128i b2 = _mm_loadl_epi64((__m128i*)&b[BPS * 2]);
-  const __m128i b3 = _mm_loadl_epi64((__m128i*)&b[BPS * 3]);
-
-  // Combine pair of lines and convert to 16b.
-  const __m128i a01 = _mm_unpacklo_epi32(a0, a1);
-  const __m128i a23 = _mm_unpacklo_epi32(a2, a3);
-  const __m128i b01 = _mm_unpacklo_epi32(b0, b1);
-  const __m128i b23 = _mm_unpacklo_epi32(b2, b3);
-  const __m128i a01s = _mm_unpacklo_epi8(a01, zero);
-  const __m128i a23s = _mm_unpacklo_epi8(a23, zero);
-  const __m128i b01s = _mm_unpacklo_epi8(b01, zero);
-  const __m128i b23s = _mm_unpacklo_epi8(b23, zero);
-
-  // Compute differences; (a-b)^2 = (abs(a-b))^2 = (sat8(a-b) + sat8(b-a))^2
-  // TODO(cduvivier): Dissassemble and figure out why this is fastest. We don't
-  //                  need absolute values, there is no need to do calculation
-  //                  in 8bit as we are already in 16bit, ... Yet this is what
-  //                  benchmarks the fastest!
-  const __m128i d0 = _mm_subs_epu8(a01s, b01s);
-  const __m128i d1 = _mm_subs_epu8(b01s, a01s);
-  const __m128i d2 = _mm_subs_epu8(a23s, b23s);
-  const __m128i d3 = _mm_subs_epu8(b23s, a23s);
-
-  // Square and add them all together.
-  const __m128i madd0 = _mm_madd_epi16(d0, d0);
-  const __m128i madd1 = _mm_madd_epi16(d1, d1);
-  const __m128i madd2 = _mm_madd_epi16(d2, d2);
-  const __m128i madd3 = _mm_madd_epi16(d3, d3);
-  const __m128i sum0 = _mm_add_epi32(madd0, madd1);
-  const __m128i sum1 = _mm_add_epi32(madd2, madd3);
-  const __m128i sum2 = _mm_add_epi32(sum0, sum1);
-  int32_t tmp[4];
-  _mm_storeu_si128((__m128i*)tmp, sum2);
-  return (tmp[3] + tmp[2] + tmp[1] + tmp[0]);
-}
-
-//------------------------------------------------------------------------------
-// Texture distortion
-//
-// We try to match the spectral content (weighted) between source and
-// reconstructed samples.
-
-// Hadamard transform
-// Returns the difference between the weighted sum of the absolute value of
-// transformed coefficients.
-static int TTransformSSE2(const uint8_t* inA, const uint8_t* inB,
-                          const uint16_t* const w) {
-  int32_t sum[4];
-  __m128i tmp_0, tmp_1, tmp_2, tmp_3;
-  const __m128i zero = _mm_setzero_si128();
-  const __m128i one = _mm_set1_epi16(1);
-  const __m128i three = _mm_set1_epi16(3);
-
-  // Load, combine and tranpose inputs.
-  {
-    const __m128i inA_0 = _mm_loadl_epi64((__m128i*)&inA[BPS * 0]);
-    const __m128i inA_1 = _mm_loadl_epi64((__m128i*)&inA[BPS * 1]);
-    const __m128i inA_2 = _mm_loadl_epi64((__m128i*)&inA[BPS * 2]);
-    const __m128i inA_3 = _mm_loadl_epi64((__m128i*)&inA[BPS * 3]);
-    const __m128i inB_0 = _mm_loadl_epi64((__m128i*)&inB[BPS * 0]);
-    const __m128i inB_1 = _mm_loadl_epi64((__m128i*)&inB[BPS * 1]);
-    const __m128i inB_2 = _mm_loadl_epi64((__m128i*)&inB[BPS * 2]);
-    const __m128i inB_3 = _mm_loadl_epi64((__m128i*)&inB[BPS * 3]);
-
-    // Combine inA and inB (we'll do two transforms in parallel).
-    const __m128i inAB_0 = _mm_unpacklo_epi8(inA_0, inB_0);
-    const __m128i inAB_1 = _mm_unpacklo_epi8(inA_1, inB_1);
-    const __m128i inAB_2 = _mm_unpacklo_epi8(inA_2, inB_2);
-    const __m128i inAB_3 = _mm_unpacklo_epi8(inA_3, inB_3);
-    // a00 b00 a01 b01 a02 b03 a03 b03   0 0 0 0 0 0 0 0
-    // a10 b10 a11 b11 a12 b12 a13 b13   0 0 0 0 0 0 0 0
-    // a20 b20 a21 b21 a22 b22 a23 b23   0 0 0 0 0 0 0 0
-    // a30 b30 a31 b31 a32 b32 a33 b33   0 0 0 0 0 0 0 0
-
-    // Transpose the two 4x4, discarding the filling zeroes.
-    const __m128i transpose0_0 = _mm_unpacklo_epi8(inAB_0, inAB_2);
-    const __m128i transpose0_1 = _mm_unpacklo_epi8(inAB_1, inAB_3);
-    // a00 a20  b00 b20  a01 a21  b01 b21  a02 a22  b02 b22  a03 a23  b03 b23
-    // a10 a30  b10 b30  a11 a31  b11 b31  a12 a32  b12 b32  a13 a33  b13 b33
-    const __m128i transpose1_0 = _mm_unpacklo_epi8(transpose0_0, transpose0_1);
-    const __m128i transpose1_1 = _mm_unpackhi_epi8(transpose0_0, transpose0_1);
-    // a00 a10 a20 a30  b00 b10 b20 b30  a01 a11 a21 a31  b01 b11 b21 b31
-    // a02 a12 a22 a32  b02 b12 b22 b32  a03 a13 a23 a33  b03 b13 b23 b33
-
-    // Convert to 16b.
-    tmp_0 = _mm_unpacklo_epi8(transpose1_0, zero);
-    tmp_1 = _mm_unpackhi_epi8(transpose1_0, zero);
-    tmp_2 = _mm_unpacklo_epi8(transpose1_1, zero);
-    tmp_3 = _mm_unpackhi_epi8(transpose1_1, zero);
-    // a00 a10 a20 a30   b00 b10 b20 b30
-    // a01 a11 a21 a31   b01 b11 b21 b31
-    // a02 a12 a22 a32   b02 b12 b22 b32
-    // a03 a13 a23 a33   b03 b13 b23 b33
-  }
-
-  // Horizontal pass and subsequent transpose.
-  {
-    // Calculate a and b (two 4x4 at once).
-    const __m128i a0 = _mm_slli_epi16(_mm_add_epi16(tmp_0, tmp_2), 2);
-    const __m128i a1 = _mm_slli_epi16(_mm_add_epi16(tmp_1, tmp_3), 2);
-    const __m128i a2 = _mm_slli_epi16(_mm_sub_epi16(tmp_1, tmp_3), 2);
-    const __m128i a3 = _mm_slli_epi16(_mm_sub_epi16(tmp_0, tmp_2), 2);
-    // b0_extra = (a0 != 0);
-    const __m128i b0_extra = _mm_andnot_si128(_mm_cmpeq_epi16 (a0, zero), one);
-    const __m128i b0_base = _mm_add_epi16(a0, a1);
-    const __m128i b1 = _mm_add_epi16(a3, a2);
-    const __m128i b2 = _mm_sub_epi16(a3, a2);
-    const __m128i b3 = _mm_sub_epi16(a0, a1);
-    const __m128i b0 = _mm_add_epi16(b0_base, b0_extra);
-    // a00 a01 a02 a03   b00 b01 b02 b03
-    // a10 a11 a12 a13   b10 b11 b12 b13
-    // a20 a21 a22 a23   b20 b21 b22 b23
-    // a30 a31 a32 a33   b30 b31 b32 b33
-
-    // Transpose the two 4x4.
-    const __m128i transpose0_0 = _mm_unpacklo_epi16(b0, b1);
-    const __m128i transpose0_1 = _mm_unpacklo_epi16(b2, b3);
-    const __m128i transpose0_2 = _mm_unpackhi_epi16(b0, b1);
-    const __m128i transpose0_3 = _mm_unpackhi_epi16(b2, b3);
-    // a00 a10 a01 a11   a02 a12 a03 a13
-    // a20 a30 a21 a31   a22 a32 a23 a33
-    // b00 b10 b01 b11   b02 b12 b03 b13
-    // b20 b30 b21 b31   b22 b32 b23 b33
-    const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3);
-    const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1);
-    const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3);
-    // a00 a10 a20 a30 a01 a11 a21 a31
-    // b00 b10 b20 b30 b01 b11 b21 b31
-    // a02 a12 a22 a32 a03 a13 a23 a33
-    // b02 b12 a22 b32 b03 b13 b23 b33
-    tmp_0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1);
-    tmp_1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1);
-    tmp_2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3);
-    tmp_3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3);
-    // a00 a10 a20 a30   b00 b10 b20 b30
-    // a01 a11 a21 a31   b01 b11 b21 b31
-    // a02 a12 a22 a32   b02 b12 b22 b32
-    // a03 a13 a23 a33   b03 b13 b23 b33
-  }
-
-  // Vertical pass and difference of weighted sums.
-  {
-    // Load all inputs.
-    // TODO(cduvivier): Make variable declarations and allocations aligned so
-    //                  we can use _mm_load_si128 instead of _mm_loadu_si128.
-    const __m128i w_0 = _mm_loadu_si128((__m128i*)&w[0]);
-    const __m128i w_8 = _mm_loadu_si128((__m128i*)&w[8]);
-
-    // Calculate a and b (two 4x4 at once).
-    const __m128i a0 = _mm_add_epi16(tmp_0, tmp_2);
-    const __m128i a1 = _mm_add_epi16(tmp_1, tmp_3);
-    const __m128i a2 = _mm_sub_epi16(tmp_1, tmp_3);
-    const __m128i a3 = _mm_sub_epi16(tmp_0, tmp_2);
-    const __m128i b0 = _mm_add_epi16(a0, a1);
-    const __m128i b1 = _mm_add_epi16(a3, a2);
-    const __m128i b2 = _mm_sub_epi16(a3, a2);
-    const __m128i b3 = _mm_sub_epi16(a0, a1);
-
-    // Separate the transforms of inA and inB.
-    __m128i A_b0 = _mm_unpacklo_epi64(b0, b1);
-    __m128i A_b2 = _mm_unpacklo_epi64(b2, b3);
-    __m128i B_b0 = _mm_unpackhi_epi64(b0, b1);
-    __m128i B_b2 = _mm_unpackhi_epi64(b2, b3);
-
-    {
-      // sign(b) = b >> 15  (0x0000 if positive, 0xffff if negative)
-      const __m128i sign_A_b0 = _mm_srai_epi16(A_b0, 15);
-      const __m128i sign_A_b2 = _mm_srai_epi16(A_b2, 15);
-      const __m128i sign_B_b0 = _mm_srai_epi16(B_b0, 15);
-      const __m128i sign_B_b2 = _mm_srai_epi16(B_b2, 15);
-
-      // b = abs(b) = (b ^ sign) - sign
-      A_b0 = _mm_xor_si128(A_b0, sign_A_b0);
-      A_b2 = _mm_xor_si128(A_b2, sign_A_b2);
-      B_b0 = _mm_xor_si128(B_b0, sign_B_b0);
-      B_b2 = _mm_xor_si128(B_b2, sign_B_b2);
-      A_b0 = _mm_sub_epi16(A_b0, sign_A_b0);
-      A_b2 = _mm_sub_epi16(A_b2, sign_A_b2);
-      B_b0 = _mm_sub_epi16(B_b0, sign_B_b0);
-      B_b2 = _mm_sub_epi16(B_b2, sign_B_b2);
-    }
-
-    // b = abs(b) + 3
-    A_b0 = _mm_add_epi16(A_b0, three);
-    A_b2 = _mm_add_epi16(A_b2, three);
-    B_b0 = _mm_add_epi16(B_b0, three);
-    B_b2 = _mm_add_epi16(B_b2, three);
-
-    // abs((b + (b<0) + 3) >> 3) = (abs(b) + 3) >> 3
-    // b = (abs(b) + 3) >> 3
-    A_b0 = _mm_srai_epi16(A_b0, 3);
-    A_b2 = _mm_srai_epi16(A_b2, 3);
-    B_b0 = _mm_srai_epi16(B_b0, 3);
-    B_b2 = _mm_srai_epi16(B_b2, 3);
-
-    // weighted sums
-    A_b0 = _mm_madd_epi16(A_b0, w_0);
-    A_b2 = _mm_madd_epi16(A_b2, w_8);
-    B_b0 = _mm_madd_epi16(B_b0, w_0);
-    B_b2 = _mm_madd_epi16(B_b2, w_8);
-    A_b0 = _mm_add_epi32(A_b0, A_b2);
-    B_b0 = _mm_add_epi32(B_b0, B_b2);
-
-    // difference of weighted sums
-    A_b0 = _mm_sub_epi32(A_b0, B_b0);
-    _mm_storeu_si128((__m128i*)&sum[0], A_b0);
-  }
-  return sum[0] + sum[1] + sum[2] + sum[3];
-}
-
-static int Disto4x4SSE2(const uint8_t* const a, const uint8_t* const b,
-                        const uint16_t* const w) {
-  const int diff_sum = TTransformSSE2(a, b, w);
-  return (abs(diff_sum) + 8) >> 4;
-}
-
-static int Disto16x16SSE2(const uint8_t* const a, const uint8_t* const b,
-                          const uint16_t* const w) {
-  int D = 0;
-  int x, y;
-  for (y = 0; y < 16 * BPS; y += 4 * BPS) {
-    for (x = 0; x < 16; x += 4) {
-      D += Disto4x4SSE2(a + x + y, b + x + y, w);
-    }
-  }
-  return D;
-}
-
-
-//------------------------------------------------------------------------------
-// Quantization
-//
-
-// Simple quantization
-static int QuantizeBlockSSE2(int16_t in[16], int16_t out[16],
-                             int n, const VP8Matrix* const mtx) {
-  const __m128i max_coeff_2047 = _mm_set1_epi16(2047);
-  const __m128i zero = _mm_set1_epi16(0);
-  __m128i sign0, sign8;
-  __m128i coeff0, coeff8;
-  __m128i out0, out8;
-  __m128i packed_out;
-
-  // Load all inputs.
-  // TODO(cduvivier): Make variable declarations and allocations aligned so that
-  //                  we can use _mm_load_si128 instead of _mm_loadu_si128.
-  __m128i in0 = _mm_loadu_si128((__m128i*)&in[0]);
-  __m128i in8 = _mm_loadu_si128((__m128i*)&in[8]);
-  const __m128i sharpen0 = _mm_loadu_si128((__m128i*)&mtx->sharpen_[0]);
-  const __m128i sharpen8 = _mm_loadu_si128((__m128i*)&mtx->sharpen_[8]);
-  const __m128i iq0 = _mm_loadu_si128((__m128i*)&mtx->iq_[0]);
-  const __m128i iq8 = _mm_loadu_si128((__m128i*)&mtx->iq_[8]);
-  const __m128i bias0 = _mm_loadu_si128((__m128i*)&mtx->bias_[0]);
-  const __m128i bias8 = _mm_loadu_si128((__m128i*)&mtx->bias_[8]);
-  const __m128i q0 = _mm_loadu_si128((__m128i*)&mtx->q_[0]);
-  const __m128i q8 = _mm_loadu_si128((__m128i*)&mtx->q_[8]);
-  const __m128i zthresh0 = _mm_loadu_si128((__m128i*)&mtx->zthresh_[0]);
-  const __m128i zthresh8 = _mm_loadu_si128((__m128i*)&mtx->zthresh_[8]);
-
-  // sign(in) = in >> 15  (0x0000 if positive, 0xffff if negative)
-  sign0 = _mm_srai_epi16(in0, 15);
-  sign8 = _mm_srai_epi16(in8, 15);
-
-  // coeff = abs(in) = (in ^ sign) - sign
-  coeff0 = _mm_xor_si128(in0, sign0);
-  coeff8 = _mm_xor_si128(in8, sign8);
-  coeff0 = _mm_sub_epi16(coeff0, sign0);
-  coeff8 = _mm_sub_epi16(coeff8, sign8);
-
-  // coeff = abs(in) + sharpen
-  coeff0 = _mm_add_epi16(coeff0, sharpen0);
-  coeff8 = _mm_add_epi16(coeff8, sharpen8);
-
-  // if (coeff > 2047) coeff = 2047
-  coeff0 = _mm_min_epi16(coeff0, max_coeff_2047);
-  coeff8 = _mm_min_epi16(coeff8, max_coeff_2047);
-
-  // out = (coeff * iQ + B) >> QFIX;
-  {
-    // doing calculations with 32b precision (QFIX=17)
-    // out = (coeff * iQ)
-    __m128i coeff_iQ0H = _mm_mulhi_epu16(coeff0, iq0);
-    __m128i coeff_iQ0L = _mm_mullo_epi16(coeff0, iq0);
-    __m128i coeff_iQ8H = _mm_mulhi_epu16(coeff8, iq8);
-    __m128i coeff_iQ8L = _mm_mullo_epi16(coeff8, iq8);
-    __m128i out_00 = _mm_unpacklo_epi16(coeff_iQ0L, coeff_iQ0H);
-    __m128i out_04 = _mm_unpackhi_epi16(coeff_iQ0L, coeff_iQ0H);
-    __m128i out_08 = _mm_unpacklo_epi16(coeff_iQ8L, coeff_iQ8H);
-    __m128i out_12 = _mm_unpackhi_epi16(coeff_iQ8L, coeff_iQ8H);
-    // expand bias from 16b to 32b
-    __m128i bias_00 = _mm_unpacklo_epi16(bias0, zero);
-    __m128i bias_04 = _mm_unpackhi_epi16(bias0, zero);
-    __m128i bias_08 = _mm_unpacklo_epi16(bias8, zero);
-    __m128i bias_12 = _mm_unpackhi_epi16(bias8, zero);
-    // out = (coeff * iQ + B)
-    out_00 = _mm_add_epi32(out_00, bias_00);
-    out_04 = _mm_add_epi32(out_04, bias_04);
-    out_08 = _mm_add_epi32(out_08, bias_08);
-    out_12 = _mm_add_epi32(out_12, bias_12);
-    // out = (coeff * iQ + B) >> QFIX;
-    out_00 = _mm_srai_epi32(out_00, QFIX);
-    out_04 = _mm_srai_epi32(out_04, QFIX);
-    out_08 = _mm_srai_epi32(out_08, QFIX);
-    out_12 = _mm_srai_epi32(out_12, QFIX);
-    // pack result as 16b
-    out0 = _mm_packs_epi32(out_00, out_04);
-    out8 = _mm_packs_epi32(out_08, out_12);
-  }
-
-  // get sign back (if (sign[j]) out_n = -out_n)
-  out0 = _mm_xor_si128(out0, sign0);
-  out8 = _mm_xor_si128(out8, sign8);
-  out0 = _mm_sub_epi16(out0, sign0);
-  out8 = _mm_sub_epi16(out8, sign8);
-
-  // in = out * Q
-  in0 = _mm_mullo_epi16(out0, q0);
-  in8 = _mm_mullo_epi16(out8, q8);
-
-  // if (coeff <= mtx->zthresh_) {in=0; out=0;}
-  {
-    __m128i cmp0 = _mm_cmpgt_epi16(coeff0, zthresh0);
-    __m128i cmp8 = _mm_cmpgt_epi16(coeff8, zthresh8);
-    in0 = _mm_and_si128(in0, cmp0);
-    in8 = _mm_and_si128(in8, cmp8);
-    _mm_storeu_si128((__m128i*)&in[0], in0);
-    _mm_storeu_si128((__m128i*)&in[8], in8);
-    out0 = _mm_and_si128(out0, cmp0);
-    out8 = _mm_and_si128(out8, cmp8);
-  }
-
-  // zigzag the output before storing it.
-  //
-  // The zigzag pattern can almost be reproduced with a small sequence of
-  // shuffles. After it, we only need to swap the 7th (ending up in third
-  // position instead of twelfth) and 8th values.
-  {
-    __m128i outZ0, outZ8;
-    outZ0 = _mm_shufflehi_epi16(out0,  _MM_SHUFFLE(2, 1, 3, 0));
-    outZ0 = _mm_shuffle_epi32  (outZ0, _MM_SHUFFLE(3, 1, 2, 0));
-    outZ0 = _mm_shufflehi_epi16(outZ0, _MM_SHUFFLE(3, 1, 0, 2));
-    outZ8 = _mm_shufflelo_epi16(out8,  _MM_SHUFFLE(3, 0, 2, 1));
-    outZ8 = _mm_shuffle_epi32  (outZ8, _MM_SHUFFLE(3, 1, 2, 0));
-    outZ8 = _mm_shufflelo_epi16(outZ8, _MM_SHUFFLE(1, 3, 2, 0));
-    _mm_storeu_si128((__m128i*)&out[0], outZ0);
-    _mm_storeu_si128((__m128i*)&out[8], outZ8);
-    packed_out = _mm_packs_epi16(outZ0, outZ8);
-  }
-  {
-    const int16_t outZ_12 = out[12];
-    const int16_t outZ_3 = out[3];
-    out[3] = outZ_12;
-    out[12] = outZ_3;
-  }
-
-  // detect if all 'out' values are zeroes or not
-  {
-    int32_t tmp[4];
-    _mm_storeu_si128((__m128i*)tmp, packed_out);
-    if (n) {
-      tmp[0] &= ~0xff;
-    }
-    return (tmp[3] || tmp[2] || tmp[1] || tmp[0]);
-  }
-}
-
-extern void VP8EncDspInitSSE2(void);
-void VP8EncDspInitSSE2(void) {
-  VP8CollectHistogram = CollectHistogramSSE2;
-  VP8EncQuantizeBlock = QuantizeBlockSSE2;
-  VP8ITransform = ITransformSSE2;
-  VP8FTransform = FTransformSSE2;
-  VP8SSE4x4 = SSE4x4SSE2;
-  VP8TDisto4x4 = Disto4x4SSE2;
-  VP8TDisto16x16 = Disto16x16SSE2;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif   // WEBP_USE_SSE2

+ 0 - 1138
drivers/webpold/dsp/lossless.c

@@ -1,1138 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Image transforms and color space conversion methods for lossless decoder.
-//
-// Authors: Vikas Arora ([email protected])
-//          Jyrki Alakuijala ([email protected])
-//          Urvang Joshi ([email protected])
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <math.h>
-#include <stdlib.h>
-#include "./lossless.h"
-#include "../dec/vp8li.h"
-#include "../dsp/yuv.h"
-#include "../dsp/dsp.h"
-#include "../enc/histogram.h"
-
-#define MAX_DIFF_COST (1e30f)
-
-// lookup table for small values of log2(int)
-#define APPROX_LOG_MAX  4096
-#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086
-#define LOG_LOOKUP_IDX_MAX 256
-static const float kLog2Table[LOG_LOOKUP_IDX_MAX] = {
-  0.0000000000000000f, 0.0000000000000000f,
-  1.0000000000000000f, 1.5849625007211560f,
-  2.0000000000000000f, 2.3219280948873621f,
-  2.5849625007211560f, 2.8073549220576041f,
-  3.0000000000000000f, 3.1699250014423121f,
-  3.3219280948873621f, 3.4594316186372973f,
-  3.5849625007211560f, 3.7004397181410921f,
-  3.8073549220576041f, 3.9068905956085187f,
-  4.0000000000000000f, 4.0874628412503390f,
-  4.1699250014423121f, 4.2479275134435852f,
-  4.3219280948873626f, 4.3923174227787606f,
-  4.4594316186372973f, 4.5235619560570130f,
-  4.5849625007211560f, 4.6438561897747243f,
-  4.7004397181410917f, 4.7548875021634682f,
-  4.8073549220576037f, 4.8579809951275718f,
-  4.9068905956085187f, 4.9541963103868749f,
-  5.0000000000000000f, 5.0443941193584533f,
-  5.0874628412503390f, 5.1292830169449663f,
-  5.1699250014423121f, 5.2094533656289501f,
-  5.2479275134435852f, 5.2854022188622487f,
-  5.3219280948873626f, 5.3575520046180837f,
-  5.3923174227787606f, 5.4262647547020979f,
-  5.4594316186372973f, 5.4918530963296747f,
-  5.5235619560570130f, 5.5545888516776376f,
-  5.5849625007211560f, 5.6147098441152083f,
-  5.6438561897747243f, 5.6724253419714951f,
-  5.7004397181410917f, 5.7279204545631987f,
-  5.7548875021634682f, 5.7813597135246599f,
-  5.8073549220576037f, 5.8328900141647412f,
-  5.8579809951275718f, 5.8826430493618415f,
-  5.9068905956085187f, 5.9307373375628866f,
-  5.9541963103868749f, 5.9772799234999167f,
-  6.0000000000000000f, 6.0223678130284543f,
-  6.0443941193584533f, 6.0660891904577720f,
-  6.0874628412503390f, 6.1085244567781691f,
-  6.1292830169449663f, 6.1497471195046822f,
-  6.1699250014423121f, 6.1898245588800175f,
-  6.2094533656289501f, 6.2288186904958804f,
-  6.2479275134435852f, 6.2667865406949010f,
-  6.2854022188622487f, 6.3037807481771030f,
-  6.3219280948873626f, 6.3398500028846243f,
-  6.3575520046180837f, 6.3750394313469245f,
-  6.3923174227787606f, 6.4093909361377017f,
-  6.4262647547020979f, 6.4429434958487279f,
-  6.4594316186372973f, 6.4757334309663976f,
-  6.4918530963296747f, 6.5077946401986963f,
-  6.5235619560570130f, 6.5391588111080309f,
-  6.5545888516776376f, 6.5698556083309478f,
-  6.5849625007211560f, 6.5999128421871278f,
-  6.6147098441152083f, 6.6293566200796094f,
-  6.6438561897747243f, 6.6582114827517946f,
-  6.6724253419714951f, 6.6865005271832185f,
-  6.7004397181410917f, 6.7142455176661224f,
-  6.7279204545631987f, 6.7414669864011464f,
-  6.7548875021634682f, 6.7681843247769259f,
-  6.7813597135246599f, 6.7944158663501061f,
-  6.8073549220576037f, 6.8201789624151878f,
-  6.8328900141647412f, 6.8454900509443747f,
-  6.8579809951275718f, 6.8703647195834047f,
-  6.8826430493618415f, 6.8948177633079437f,
-  6.9068905956085187f, 6.9188632372745946f,
-  6.9307373375628866f, 6.9425145053392398f,
-  6.9541963103868749f, 6.9657842846620869f,
-  6.9772799234999167f, 6.9886846867721654f,
-  7.0000000000000000f, 7.0112272554232539f,
-  7.0223678130284543f, 7.0334230015374501f,
-  7.0443941193584533f, 7.0552824355011898f,
-  7.0660891904577720f, 7.0768155970508308f,
-  7.0874628412503390f, 7.0980320829605263f,
-  7.1085244567781691f, 7.1189410727235076f,
-  7.1292830169449663f, 7.1395513523987936f,
-  7.1497471195046822f, 7.1598713367783890f,
-  7.1699250014423121f, 7.1799090900149344f,
-  7.1898245588800175f, 7.1996723448363644f,
-  7.2094533656289501f, 7.2191685204621611f,
-  7.2288186904958804f, 7.2384047393250785f,
-  7.2479275134435852f, 7.2573878426926521f,
-  7.2667865406949010f, 7.2761244052742375f,
-  7.2854022188622487f, 7.2946207488916270f,
-  7.3037807481771030f, 7.3128829552843557f,
-  7.3219280948873626f, 7.3309168781146167f,
-  7.3398500028846243f, 7.3487281542310771f,
-  7.3575520046180837f, 7.3663222142458160f,
-  7.3750394313469245f, 7.3837042924740519f,
-  7.3923174227787606f, 7.4008794362821843f,
-  7.4093909361377017f, 7.4178525148858982f,
-  7.4262647547020979f, 7.4346282276367245f,
-  7.4429434958487279f, 7.4512111118323289f,
-  7.4594316186372973f, 7.4676055500829976f,
-  7.4757334309663976f, 7.4838157772642563f,
-  7.4918530963296747f, 7.4998458870832056f,
-  7.5077946401986963f, 7.5156998382840427f,
-  7.5235619560570130f, 7.5313814605163118f,
-  7.5391588111080309f, 7.5468944598876364f,
-  7.5545888516776376f, 7.5622424242210728f,
-  7.5698556083309478f, 7.5774288280357486f,
-  7.5849625007211560f, 7.5924570372680806f,
-  7.5999128421871278f, 7.6073303137496104f,
-  7.6147098441152083f, 7.6220518194563764f,
-  7.6293566200796094f, 7.6366246205436487f,
-  7.6438561897747243f, 7.6510516911789281f,
-  7.6582114827517946f, 7.6653359171851764f,
-  7.6724253419714951f, 7.6794800995054464f,
-  7.6865005271832185f, 7.6934869574993252f,
-  7.7004397181410917f, 7.7073591320808825f,
-  7.7142455176661224f, 7.7210991887071855f,
-  7.7279204545631987f, 7.7347096202258383f,
-  7.7414669864011464f, 7.7481928495894605f,
-  7.7548875021634682f, 7.7615512324444795f,
-  7.7681843247769259f, 7.7747870596011736f,
-  7.7813597135246599f, 7.7879025593914317f,
-  7.7944158663501061f, 7.8008998999203047f,
-  7.8073549220576037f, 7.8137811912170374f,
-  7.8201789624151878f, 7.8265484872909150f,
-  7.8328900141647412f, 7.8392037880969436f,
-  7.8454900509443747f, 7.8517490414160571f,
-  7.8579809951275718f, 7.8641861446542797f,
-  7.8703647195834047f, 7.8765169465649993f,
-  7.8826430493618415f, 7.8887432488982591f,
-  7.8948177633079437f, 7.9008668079807486f,
-  7.9068905956085187f, 7.9128893362299619f,
-  7.9188632372745946f, 7.9248125036057812f,
-  7.9307373375628866f, 7.9366379390025709f,
-  7.9425145053392398f, 7.9483672315846778f,
-  7.9541963103868749f, 7.9600019320680805f,
-  7.9657842846620869f, 7.9715435539507719f,
-  7.9772799234999167f, 7.9829935746943103f,
-  7.9886846867721654f, 7.9943534368588577f
-};
-
-float VP8LFastLog2(int v) {
-  if (v < LOG_LOOKUP_IDX_MAX) {
-    return kLog2Table[v];
-  } else if (v < APPROX_LOG_MAX) {
-    int log_cnt = 0;
-    while (v >= LOG_LOOKUP_IDX_MAX) {
-      ++log_cnt;
-      v = v >> 1;
-    }
-    return kLog2Table[v] + (float)log_cnt;
-  } else {
-    return (float)(LOG_2_RECIPROCAL * log((double)v));
-  }
-}
-
-//------------------------------------------------------------------------------
-// Image transforms.
-
-// In-place sum of each component with mod 256.
-static WEBP_INLINE void AddPixelsEq(uint32_t* a, uint32_t b) {
-  const uint32_t alpha_and_green = (*a & 0xff00ff00u) + (b & 0xff00ff00u);
-  const uint32_t red_and_blue = (*a & 0x00ff00ffu) + (b & 0x00ff00ffu);
-  *a = (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
-}
-
-static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
-  return (((a0 ^ a1) & 0xfefefefeL) >> 1) + (a0 & a1);
-}
-
-static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
-  return Average2(Average2(a0, a2), a1);
-}
-
-static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
-                                     uint32_t a2, uint32_t a3) {
-  return Average2(Average2(a0, a1), Average2(a2, a3));
-}
-
-static WEBP_INLINE uint32_t Clip255(uint32_t a) {
-  if (a < 256) {
-    return a;
-  }
-  // return 0, when a is a negative integer.
-  // return 255, when a is positive.
-  return ~a >> 24;
-}
-
-static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
-  return Clip255(a + b - c);
-}
-
-static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
-                                                   uint32_t c2) {
-  const int a = AddSubtractComponentFull(c0 >> 24, c1 >> 24, c2 >> 24);
-  const int r = AddSubtractComponentFull((c0 >> 16) & 0xff,
-                                         (c1 >> 16) & 0xff,
-                                         (c2 >> 16) & 0xff);
-  const int g = AddSubtractComponentFull((c0 >> 8) & 0xff,
-                                         (c1 >> 8) & 0xff,
-                                         (c2 >> 8) & 0xff);
-  const int b = AddSubtractComponentFull(c0 & 0xff, c1 & 0xff, c2 & 0xff);
-  return (a << 24) | (r << 16) | (g << 8) | b;
-}
-
-static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
-  return Clip255(a + (a - b) / 2);
-}
-
-static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
-                                                   uint32_t c2) {
-  const uint32_t ave = Average2(c0, c1);
-  const int a = AddSubtractComponentHalf(ave >> 24, c2 >> 24);
-  const int r = AddSubtractComponentHalf((ave >> 16) & 0xff, (c2 >> 16) & 0xff);
-  const int g = AddSubtractComponentHalf((ave >> 8) & 0xff, (c2 >> 8) & 0xff);
-  const int b = AddSubtractComponentHalf((ave >> 0) & 0xff, (c2 >> 0) & 0xff);
-  return (a << 24) | (r << 16) | (g << 8) | b;
-}
-
-static WEBP_INLINE int Sub3(int a, int b, int c) {
-  const int pa = b - c;
-  const int pb = a - c;
-  return abs(pa) - abs(pb);
-}
-
-static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
-  const int pa_minus_pb =
-      Sub3((a >> 24)       , (b >> 24)       , (c >> 24)       ) +
-      Sub3((a >> 16) & 0xff, (b >> 16) & 0xff, (c >> 16) & 0xff) +
-      Sub3((a >>  8) & 0xff, (b >>  8) & 0xff, (c >>  8) & 0xff) +
-      Sub3((a      ) & 0xff, (b      ) & 0xff, (c      ) & 0xff);
-
-  return (pa_minus_pb <= 0) ? a : b;
-}
-
-//------------------------------------------------------------------------------
-// Predictors
-
-static uint32_t Predictor0(uint32_t left, const uint32_t* const top) {
-  (void)top;
-  (void)left;
-  return ARGB_BLACK;
-}
-static uint32_t Predictor1(uint32_t left, const uint32_t* const top) {
-  (void)top;
-  return left;
-}
-static uint32_t Predictor2(uint32_t left, const uint32_t* const top) {
-  (void)left;
-  return top[0];
-}
-static uint32_t Predictor3(uint32_t left, const uint32_t* const top) {
-  (void)left;
-  return top[1];
-}
-static uint32_t Predictor4(uint32_t left, const uint32_t* const top) {
-  (void)left;
-  return top[-1];
-}
-static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average3(left, top[0], top[1]);
-  return pred;
-}
-static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(left, top[-1]);
-  return pred;
-}
-static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(left, top[0]);
-  return pred;
-}
-static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(top[-1], top[0]);
-  (void)left;
-  return pred;
-}
-static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average2(top[0], top[1]);
-  (void)left;
-  return pred;
-}
-static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
-  return pred;
-}
-static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = Select(top[0], left, top[-1]);
-  return pred;
-}
-static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
-  return pred;
-}
-static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
-  const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
-  return pred;
-}
-
-typedef uint32_t (*PredictorFunc)(uint32_t left, const uint32_t* const top);
-static const PredictorFunc kPredictors[16] = {
-  Predictor0, Predictor1, Predictor2, Predictor3,
-  Predictor4, Predictor5, Predictor6, Predictor7,
-  Predictor8, Predictor9, Predictor10, Predictor11,
-  Predictor12, Predictor13,
-  Predictor0, Predictor0    // <- padding security sentinels
-};
-
-// TODO(vikasa): Replace 256 etc with defines.
-static float PredictionCostSpatial(const int* counts,
-                                   int weight_0, double exp_val) {
-  const int significant_symbols = 16;
-  const double exp_decay_factor = 0.6;
-  double bits = weight_0 * counts[0];
-  int i;
-  for (i = 1; i < significant_symbols; ++i) {
-    bits += exp_val * (counts[i] + counts[256 - i]);
-    exp_val *= exp_decay_factor;
-  }
-  return (float)(-0.1 * bits);
-}
-
-// Compute the Shanon's entropy: Sum(p*log2(p))
-static float ShannonEntropy(const int* const array, int n) {
-  int i;
-  float retval = 0.f;
-  int sum = 0;
-  for (i = 0; i < n; ++i) {
-    if (array[i] != 0) {
-      sum += array[i];
-      retval -= VP8LFastSLog2(array[i]);
-    }
-  }
-  retval += VP8LFastSLog2(sum);
-  return retval;
-}
-
-static float PredictionCostSpatialHistogram(int accumulated[4][256],
-                                            int tile[4][256]) {
-  int i;
-  int k;
-  int combo[256];
-  double retval = 0;
-  for (i = 0; i < 4; ++i) {
-    const double exp_val = 0.94;
-    retval += PredictionCostSpatial(&tile[i][0], 1, exp_val);
-    retval += ShannonEntropy(&tile[i][0], 256);
-    for (k = 0; k < 256; ++k) {
-      combo[k] = accumulated[i][k] + tile[i][k];
-    }
-    retval += ShannonEntropy(&combo[0], 256);
-  }
-  return (float)retval;
-}
-
-static int GetBestPredictorForTile(int width, int height,
-                                   int tile_x, int tile_y, int bits,
-                                   int accumulated[4][256],
-                                   const uint32_t* const argb_scratch) {
-  const int kNumPredModes = 14;
-  const int col_start = tile_x << bits;
-  const int row_start = tile_y << bits;
-  const int tile_size = 1 << bits;
-  const int ymax = (tile_size <= height - row_start) ?
-      tile_size : height - row_start;
-  const int xmax = (tile_size <= width - col_start) ?
-      tile_size : width - col_start;
-  int histo[4][256];
-  float best_diff = MAX_DIFF_COST;
-  int best_mode = 0;
-
-  int mode;
-  for (mode = 0; mode < kNumPredModes; ++mode) {
-    const uint32_t* current_row = argb_scratch;
-    const PredictorFunc pred_func = kPredictors[mode];
-    float cur_diff;
-    int y;
-    memset(&histo[0][0], 0, sizeof(histo));
-    for (y = 0; y < ymax; ++y) {
-      int x;
-      const int row = row_start + y;
-      const uint32_t* const upper_row = current_row;
-      current_row = upper_row + width;
-      for (x = 0; x < xmax; ++x) {
-        const int col = col_start + x;
-        uint32_t predict;
-        uint32_t predict_diff;
-        if (row == 0) {
-          predict = (col == 0) ? ARGB_BLACK : current_row[col - 1];  // Left.
-        } else if (col == 0) {
-          predict = upper_row[col];  // Top.
-        } else {
-          predict = pred_func(current_row[col - 1], upper_row + col);
-        }
-        predict_diff = VP8LSubPixels(current_row[col], predict);
-        ++histo[0][predict_diff >> 24];
-        ++histo[1][((predict_diff >> 16) & 0xff)];
-        ++histo[2][((predict_diff >> 8) & 0xff)];
-        ++histo[3][(predict_diff & 0xff)];
-      }
-    }
-    cur_diff = PredictionCostSpatialHistogram(accumulated, histo);
-    if (cur_diff < best_diff) {
-      best_diff = cur_diff;
-      best_mode = mode;
-    }
-  }
-
-  return best_mode;
-}
-
-static void CopyTileWithPrediction(int width, int height,
-                                   int tile_x, int tile_y, int bits, int mode,
-                                   const uint32_t* const argb_scratch,
-                                   uint32_t* const argb) {
-  const int col_start = tile_x << bits;
-  const int row_start = tile_y << bits;
-  const int tile_size = 1 << bits;
-  const int ymax = (tile_size <= height - row_start) ?
-      tile_size : height - row_start;
-  const int xmax = (tile_size <= width - col_start) ?
-      tile_size : width - col_start;
-  const PredictorFunc pred_func = kPredictors[mode];
-  const uint32_t* current_row = argb_scratch;
-
-  int y;
-  for (y = 0; y < ymax; ++y) {
-    int x;
-    const int row = row_start + y;
-    const uint32_t* const upper_row = current_row;
-    current_row = upper_row + width;
-    for (x = 0; x < xmax; ++x) {
-      const int col = col_start + x;
-      const int pix = row * width + col;
-      uint32_t predict;
-      if (row == 0) {
-        predict = (col == 0) ? ARGB_BLACK : current_row[col - 1];  // Left.
-      } else if (col == 0) {
-        predict = upper_row[col];  // Top.
-      } else {
-        predict = pred_func(current_row[col - 1], upper_row + col);
-      }
-      argb[pix] = VP8LSubPixels(current_row[col], predict);
-    }
-  }
-}
-
-void VP8LResidualImage(int width, int height, int bits,
-                       uint32_t* const argb, uint32_t* const argb_scratch,
-                       uint32_t* const image) {
-  const int max_tile_size = 1 << bits;
-  const int tiles_per_row = VP8LSubSampleSize(width, bits);
-  const int tiles_per_col = VP8LSubSampleSize(height, bits);
-  uint32_t* const upper_row = argb_scratch;
-  uint32_t* const current_tile_rows = argb_scratch + width;
-  int tile_y;
-  int histo[4][256];
-  memset(histo, 0, sizeof(histo));
-  for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) {
-    const int tile_y_offset = tile_y * max_tile_size;
-    const int this_tile_height =
-        (tile_y < tiles_per_col - 1) ? max_tile_size : height - tile_y_offset;
-    int tile_x;
-    if (tile_y > 0) {
-      memcpy(upper_row, current_tile_rows + (max_tile_size - 1) * width,
-             width * sizeof(*upper_row));
-    }
-    memcpy(current_tile_rows, &argb[tile_y_offset * width],
-           this_tile_height * width * sizeof(*current_tile_rows));
-    for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) {
-      int pred;
-      int y;
-      const int tile_x_offset = tile_x * max_tile_size;
-      int all_x_max = tile_x_offset + max_tile_size;
-      if (all_x_max > width) {
-        all_x_max = width;
-      }
-      pred = GetBestPredictorForTile(width, height, tile_x, tile_y, bits, histo,
-                                     argb_scratch);
-      image[tile_y * tiles_per_row + tile_x] = 0xff000000u | (pred << 8);
-      CopyTileWithPrediction(width, height, tile_x, tile_y, bits, pred,
-                             argb_scratch, argb);
-      for (y = 0; y < max_tile_size; ++y) {
-        int ix;
-        int all_x;
-        int all_y = tile_y_offset + y;
-        if (all_y >= height) {
-          break;
-        }
-        ix = all_y * width + tile_x_offset;
-        for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) {
-          const uint32_t a = argb[ix];
-          ++histo[0][a >> 24];
-          ++histo[1][((a >> 16) & 0xff)];
-          ++histo[2][((a >> 8) & 0xff)];
-          ++histo[3][(a & 0xff)];
-        }
-      }
-    }
-  }
-}
-
-// Inverse prediction.
-static void PredictorInverseTransform(const VP8LTransform* const transform,
-                                      int y_start, int y_end, uint32_t* data) {
-  const int width = transform->xsize_;
-  if (y_start == 0) {  // First Row follows the L (mode=1) mode.
-    int x;
-    const uint32_t pred0 = Predictor0(data[-1], NULL);
-    AddPixelsEq(data, pred0);
-    for (x = 1; x < width; ++x) {
-      const uint32_t pred1 = Predictor1(data[x - 1], NULL);
-      AddPixelsEq(data + x, pred1);
-    }
-    data += width;
-    ++y_start;
-  }
-
-  {
-    int y = y_start;
-    const int mask = (1 << transform->bits_) - 1;
-    const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_);
-    const uint32_t* pred_mode_base =
-        transform->data_ + (y >> transform->bits_) * tiles_per_row;
-
-    while (y < y_end) {
-      int x;
-      const uint32_t pred2 = Predictor2(data[-1], data - width);
-      const uint32_t* pred_mode_src = pred_mode_base;
-      PredictorFunc pred_func;
-
-      // First pixel follows the T (mode=2) mode.
-      AddPixelsEq(data, pred2);
-
-      // .. the rest:
-      pred_func = kPredictors[((*pred_mode_src++) >> 8) & 0xf];
-      for (x = 1; x < width; ++x) {
-        uint32_t pred;
-        if ((x & mask) == 0) {    // start of tile. Read predictor function.
-          pred_func = kPredictors[((*pred_mode_src++) >> 8) & 0xf];
-        }
-        pred = pred_func(data[x - 1], data + x - width);
-        AddPixelsEq(data + x, pred);
-      }
-      data += width;
-      ++y;
-      if ((y & mask) == 0) {   // Use the same mask, since tiles are squares.
-        pred_mode_base += tiles_per_row;
-      }
-    }
-  }
-}
-
-void VP8LSubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixs) {
-  int i;
-  for (i = 0; i < num_pixs; ++i) {
-    const uint32_t argb = argb_data[i];
-    const uint32_t green = (argb >> 8) & 0xff;
-    const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
-    const uint32_t new_b = ((argb & 0xff) - green) & 0xff;
-    argb_data[i] = (argb & 0xff00ff00) | (new_r << 16) | new_b;
-  }
-}
-
-// Add green to blue and red channels (i.e. perform the inverse transform of
-// 'subtract green').
-static void AddGreenToBlueAndRed(const VP8LTransform* const transform,
-                                 int y_start, int y_end, uint32_t* data) {
-  const int width = transform->xsize_;
-  const uint32_t* const data_end = data + (y_end - y_start) * width;
-  while (data < data_end) {
-    const uint32_t argb = *data;
-    // "* 0001001u" is equivalent to "(green << 16) + green)"
-    const uint32_t green = ((argb >> 8) & 0xff);
-    uint32_t red_blue = (argb & 0x00ff00ffu);
-    red_blue += (green << 16) | green;
-    red_blue &= 0x00ff00ffu;
-    *data++ = (argb & 0xff00ff00u) | red_blue;
-  }
-}
-
-typedef struct {
-  // Note: the members are uint8_t, so that any negative values are
-  // automatically converted to "mod 256" values.
-  uint8_t green_to_red_;
-  uint8_t green_to_blue_;
-  uint8_t red_to_blue_;
-} Multipliers;
-
-static WEBP_INLINE void MultipliersClear(Multipliers* m) {
-  m->green_to_red_ = 0;
-  m->green_to_blue_ = 0;
-  m->red_to_blue_ = 0;
-}
-
-static WEBP_INLINE uint32_t ColorTransformDelta(int8_t color_pred,
-                                                int8_t color) {
-  return (uint32_t)((int)(color_pred) * color) >> 5;
-}
-
-static WEBP_INLINE void ColorCodeToMultipliers(uint32_t color_code,
-                                               Multipliers* const m) {
-  m->green_to_red_  = (color_code >>  0) & 0xff;
-  m->green_to_blue_ = (color_code >>  8) & 0xff;
-  m->red_to_blue_   = (color_code >> 16) & 0xff;
-}
-
-static WEBP_INLINE uint32_t MultipliersToColorCode(Multipliers* const m) {
-  return 0xff000000u |
-         ((uint32_t)(m->red_to_blue_) << 16) |
-         ((uint32_t)(m->green_to_blue_) << 8) |
-         m->green_to_red_;
-}
-
-static WEBP_INLINE uint32_t TransformColor(const Multipliers* const m,
-                                           uint32_t argb, int inverse) {
-  const uint32_t green = argb >> 8;
-  const uint32_t red = argb >> 16;
-  uint32_t new_red = red;
-  uint32_t new_blue = argb;
-
-  if (inverse) {
-    new_red += ColorTransformDelta(m->green_to_red_, green);
-    new_red &= 0xff;
-    new_blue += ColorTransformDelta(m->green_to_blue_, green);
-    new_blue += ColorTransformDelta(m->red_to_blue_, new_red);
-    new_blue &= 0xff;
-  } else {
-    new_red -= ColorTransformDelta(m->green_to_red_, green);
-    new_red &= 0xff;
-    new_blue -= ColorTransformDelta(m->green_to_blue_, green);
-    new_blue -= ColorTransformDelta(m->red_to_blue_, red);
-    new_blue &= 0xff;
-  }
-  return (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
-}
-
-static WEBP_INLINE int SkipRepeatedPixels(const uint32_t* const argb,
-                                          int ix, int xsize) {
-  const uint32_t v = argb[ix];
-  if (ix >= xsize + 3) {
-    if (v == argb[ix - xsize] &&
-        argb[ix - 1] == argb[ix - xsize - 1] &&
-        argb[ix - 2] == argb[ix - xsize - 2] &&
-        argb[ix - 3] == argb[ix - xsize - 3]) {
-      return 1;
-    }
-    return v == argb[ix - 3] && v == argb[ix - 2] && v == argb[ix - 1];
-  } else if (ix >= 3) {
-    return v == argb[ix - 3] && v == argb[ix - 2] && v == argb[ix - 1];
-  }
-  return 0;
-}
-
-static float PredictionCostCrossColor(const int accumulated[256],
-                                      const int counts[256]) {
-  // Favor low entropy, locally and globally.
-  int i;
-  int combo[256];
-  for (i = 0; i < 256; ++i) {
-    combo[i] = accumulated[i] + counts[i];
-  }
-  return ShannonEntropy(combo, 256) +
-         ShannonEntropy(counts, 256) +
-         PredictionCostSpatial(counts, 3, 2.4);  // Favor small absolute values.
-}
-
-static Multipliers GetBestColorTransformForTile(
-    int tile_x, int tile_y, int bits,
-    Multipliers prevX,
-    Multipliers prevY,
-    int step, int xsize, int ysize,
-    int* accumulated_red_histo,
-    int* accumulated_blue_histo,
-    const uint32_t* const argb) {
-  float best_diff = MAX_DIFF_COST;
-  float cur_diff;
-  const int halfstep = step / 2;
-  const int max_tile_size = 1 << bits;
-  const int tile_y_offset = tile_y * max_tile_size;
-  const int tile_x_offset = tile_x * max_tile_size;
-  int green_to_red;
-  int green_to_blue;
-  int red_to_blue;
-  int all_x_max = tile_x_offset + max_tile_size;
-  int all_y_max = tile_y_offset + max_tile_size;
-  Multipliers best_tx;
-  MultipliersClear(&best_tx);
-  if (all_x_max > xsize) {
-    all_x_max = xsize;
-  }
-  if (all_y_max > ysize) {
-    all_y_max = ysize;
-  }
-  for (green_to_red = -64; green_to_red <= 64; green_to_red += halfstep) {
-    int histo[256] = { 0 };
-    int all_y;
-    Multipliers tx;
-    MultipliersClear(&tx);
-    tx.green_to_red_ = green_to_red & 0xff;
-
-    for (all_y = tile_y_offset; all_y < all_y_max; ++all_y) {
-      uint32_t predict;
-      int ix = all_y * xsize + tile_x_offset;
-      int all_x;
-      for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) {
-        if (SkipRepeatedPixels(argb, ix, xsize)) {
-          continue;
-        }
-        predict = TransformColor(&tx, argb[ix], 0);
-        ++histo[(predict >> 16) & 0xff];  // red.
-      }
-    }
-    cur_diff = PredictionCostCrossColor(&accumulated_red_histo[0], &histo[0]);
-    if (tx.green_to_red_ == prevX.green_to_red_) {
-      cur_diff -= 3;  // favor keeping the areas locally similar
-    }
-    if (tx.green_to_red_ == prevY.green_to_red_) {
-      cur_diff -= 3;  // favor keeping the areas locally similar
-    }
-    if (tx.green_to_red_ == 0) {
-      cur_diff -= 3;
-    }
-    if (cur_diff < best_diff) {
-      best_diff = cur_diff;
-      best_tx = tx;
-    }
-  }
-  best_diff = MAX_DIFF_COST;
-  green_to_red = best_tx.green_to_red_;
-  for (green_to_blue = -32; green_to_blue <= 32; green_to_blue += step) {
-    for (red_to_blue = -32; red_to_blue <= 32; red_to_blue += step) {
-      int all_y;
-      int histo[256] = { 0 };
-      Multipliers tx;
-      tx.green_to_red_ = green_to_red;
-      tx.green_to_blue_ = green_to_blue;
-      tx.red_to_blue_ = red_to_blue;
-      for (all_y = tile_y_offset; all_y < all_y_max; ++all_y) {
-        uint32_t predict;
-        int all_x;
-        int ix = all_y * xsize + tile_x_offset;
-        for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) {
-          if (SkipRepeatedPixels(argb, ix, xsize)) {
-            continue;
-          }
-          predict = TransformColor(&tx, argb[ix], 0);
-          ++histo[predict & 0xff];  // blue.
-        }
-      }
-      cur_diff =
-        PredictionCostCrossColor(&accumulated_blue_histo[0], &histo[0]);
-      if (tx.green_to_blue_ == prevX.green_to_blue_) {
-        cur_diff -= 3;  // favor keeping the areas locally similar
-      }
-      if (tx.green_to_blue_ == prevY.green_to_blue_) {
-        cur_diff -= 3;  // favor keeping the areas locally similar
-      }
-      if (tx.red_to_blue_ == prevX.red_to_blue_) {
-        cur_diff -= 3;  // favor keeping the areas locally similar
-      }
-      if (tx.red_to_blue_ == prevY.red_to_blue_) {
-        cur_diff -= 3;  // favor keeping the areas locally similar
-      }
-      if (tx.green_to_blue_ == 0) {
-        cur_diff -= 3;
-      }
-      if (tx.red_to_blue_ == 0) {
-        cur_diff -= 3;
-      }
-      if (cur_diff < best_diff) {
-        best_diff = cur_diff;
-        best_tx = tx;
-      }
-    }
-  }
-  return best_tx;
-}
-
-static void CopyTileWithColorTransform(int xsize, int ysize,
-                                       int tile_x, int tile_y, int bits,
-                                       Multipliers color_transform,
-                                       uint32_t* const argb) {
-  int y;
-  int xscan = 1 << bits;
-  int yscan = 1 << bits;
-  tile_x <<= bits;
-  tile_y <<= bits;
-  if (xscan > xsize - tile_x) {
-    xscan = xsize - tile_x;
-  }
-  if (yscan > ysize - tile_y) {
-    yscan = ysize - tile_y;
-  }
-  yscan += tile_y;
-  for (y = tile_y; y < yscan; ++y) {
-    int ix = y * xsize + tile_x;
-    const int end_ix = ix + xscan;
-    for (; ix < end_ix; ++ix) {
-      argb[ix] = TransformColor(&color_transform, argb[ix], 0);
-    }
-  }
-}
-
-void VP8LColorSpaceTransform(int width, int height, int bits, int step,
-                             uint32_t* const argb, uint32_t* image) {
-  const int max_tile_size = 1 << bits;
-  int tile_xsize = VP8LSubSampleSize(width, bits);
-  int tile_ysize = VP8LSubSampleSize(height, bits);
-  int accumulated_red_histo[256] = { 0 };
-  int accumulated_blue_histo[256] = { 0 };
-  int tile_y;
-  int tile_x;
-  Multipliers prevX;
-  Multipliers prevY;
-  MultipliersClear(&prevY);
-  MultipliersClear(&prevX);
-  for (tile_y = 0; tile_y < tile_ysize; ++tile_y) {
-    for (tile_x = 0; tile_x < tile_xsize; ++tile_x) {
-      Multipliers color_transform;
-      int all_x_max;
-      int y;
-      const int tile_y_offset = tile_y * max_tile_size;
-      const int tile_x_offset = tile_x * max_tile_size;
-      if (tile_y != 0) {
-        ColorCodeToMultipliers(image[tile_y * tile_xsize + tile_x - 1], &prevX);
-        ColorCodeToMultipliers(image[(tile_y - 1) * tile_xsize + tile_x],
-                               &prevY);
-      } else if (tile_x != 0) {
-        ColorCodeToMultipliers(image[tile_y * tile_xsize + tile_x - 1], &prevX);
-      }
-      color_transform =
-          GetBestColorTransformForTile(tile_x, tile_y, bits,
-                                       prevX, prevY,
-                                       step, width, height,
-                                       &accumulated_red_histo[0],
-                                       &accumulated_blue_histo[0],
-                                       argb);
-      image[tile_y * tile_xsize + tile_x] =
-          MultipliersToColorCode(&color_transform);
-      CopyTileWithColorTransform(width, height, tile_x, tile_y, bits,
-                                 color_transform, argb);
-
-      // Gather accumulated histogram data.
-      all_x_max = tile_x_offset + max_tile_size;
-      if (all_x_max > width) {
-        all_x_max = width;
-      }
-      for (y = 0; y < max_tile_size; ++y) {
-        int ix;
-        int all_x;
-        int all_y = tile_y_offset + y;
-        if (all_y >= height) {
-          break;
-        }
-        ix = all_y * width + tile_x_offset;
-        for (all_x = tile_x_offset; all_x < all_x_max; ++all_x, ++ix) {
-          if (ix >= 2 &&
-              argb[ix] == argb[ix - 2] &&
-              argb[ix] == argb[ix - 1]) {
-            continue;  // repeated pixels are handled by backward references
-          }
-          if (ix >= width + 2 &&
-              argb[ix - 2] == argb[ix - width - 2] &&
-              argb[ix - 1] == argb[ix - width - 1] &&
-              argb[ix] == argb[ix - width]) {
-            continue;  // repeated pixels are handled by backward references
-          }
-          ++accumulated_red_histo[(argb[ix] >> 16) & 0xff];
-          ++accumulated_blue_histo[argb[ix] & 0xff];
-        }
-      }
-    }
-  }
-}
-
-// Color space inverse transform.
-static void ColorSpaceInverseTransform(const VP8LTransform* const transform,
-                                       int y_start, int y_end, uint32_t* data) {
-  const int width = transform->xsize_;
-  const int mask = (1 << transform->bits_) - 1;
-  const int tiles_per_row = VP8LSubSampleSize(width, transform->bits_);
-  int y = y_start;
-  const uint32_t* pred_row =
-      transform->data_ + (y >> transform->bits_) * tiles_per_row;
-
-  while (y < y_end) {
-    const uint32_t* pred = pred_row;
-    Multipliers m = { 0, 0, 0 };
-    int x;
-
-    for (x = 0; x < width; ++x) {
-      if ((x & mask) == 0) ColorCodeToMultipliers(*pred++, &m);
-      data[x] = TransformColor(&m, data[x], 1);
-    }
-    data += width;
-    ++y;
-    if ((y & mask) == 0) pred_row += tiles_per_row;;
-  }
-}
-
-// Separate out pixels packed together using pixel-bundling.
-static void ColorIndexInverseTransform(
-    const VP8LTransform* const transform,
-    int y_start, int y_end, const uint32_t* src, uint32_t* dst) {
-  int y;
-  const int bits_per_pixel = 8 >> transform->bits_;
-  const int width = transform->xsize_;
-  const uint32_t* const color_map = transform->data_;
-  if (bits_per_pixel < 8) {
-    const int pixels_per_byte = 1 << transform->bits_;
-    const int count_mask = pixels_per_byte - 1;
-    const uint32_t bit_mask = (1 << bits_per_pixel) - 1;
-    for (y = y_start; y < y_end; ++y) {
-      uint32_t packed_pixels = 0;
-      int x;
-      for (x = 0; x < width; ++x) {
-        // We need to load fresh 'packed_pixels' once every 'pixels_per_byte'
-        // increments of x. Fortunately, pixels_per_byte is a power of 2, so
-        // can just use a mask for that, instead of decrementing a counter.
-        if ((x & count_mask) == 0) packed_pixels = ((*src++) >> 8) & 0xff;
-        *dst++ = color_map[packed_pixels & bit_mask];
-        packed_pixels >>= bits_per_pixel;
-      }
-    }
-  } else {
-    for (y = y_start; y < y_end; ++y) {
-      int x;
-      for (x = 0; x < width; ++x) {
-        *dst++ = color_map[((*src++) >> 8) & 0xff];
-      }
-    }
-  }
-}
-
-void VP8LInverseTransform(const VP8LTransform* const transform,
-                          int row_start, int row_end,
-                          const uint32_t* const in, uint32_t* const out) {
-  assert(row_start < row_end);
-  assert(row_end <= transform->ysize_);
-  switch (transform->type_) {
-    case SUBTRACT_GREEN:
-      AddGreenToBlueAndRed(transform, row_start, row_end, out);
-      break;
-    case PREDICTOR_TRANSFORM:
-      PredictorInverseTransform(transform, row_start, row_end, out);
-      if (row_end != transform->ysize_) {
-        // The last predicted row in this iteration will be the top-pred row
-        // for the first row in next iteration.
-        const int width = transform->xsize_;
-        memcpy(out - width, out + (row_end - row_start - 1) * width,
-               width * sizeof(*out));
-      }
-      break;
-    case CROSS_COLOR_TRANSFORM:
-      ColorSpaceInverseTransform(transform, row_start, row_end, out);
-      break;
-    case COLOR_INDEXING_TRANSFORM:
-      if (in == out && transform->bits_ > 0) {
-        // Move packed pixels to the end of unpacked region, so that unpacking
-        // can occur seamlessly.
-        // Also, note that this is the only transform that applies on
-        // the effective width of VP8LSubSampleSize(xsize_, bits_). All other
-        // transforms work on effective width of xsize_.
-        const int out_stride = (row_end - row_start) * transform->xsize_;
-        const int in_stride = (row_end - row_start) *
-            VP8LSubSampleSize(transform->xsize_, transform->bits_);
-        uint32_t* const src = out + out_stride - in_stride;
-        memmove(src, out, in_stride * sizeof(*src));
-        ColorIndexInverseTransform(transform, row_start, row_end, src, out);
-      } else {
-        ColorIndexInverseTransform(transform, row_start, row_end, in, out);
-      }
-      break;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Color space conversion.
-
-static int is_big_endian(void) {
-  static const union {
-    uint16_t w;
-    uint8_t b[2];
-  } tmp = { 1 };
-  return (tmp.b[0] != 1);
-}
-
-static void ConvertBGRAToRGB(const uint32_t* src,
-                             int num_pixels, uint8_t* dst) {
-  const uint32_t* const src_end = src + num_pixels;
-  while (src < src_end) {
-    const uint32_t argb = *src++;
-    *dst++ = (argb >> 16) & 0xff;
-    *dst++ = (argb >>  8) & 0xff;
-    *dst++ = (argb >>  0) & 0xff;
-  }
-}
-
-static void ConvertBGRAToRGBA(const uint32_t* src,
-                              int num_pixels, uint8_t* dst) {
-  const uint32_t* const src_end = src + num_pixels;
-  while (src < src_end) {
-    const uint32_t argb = *src++;
-    *dst++ = (argb >> 16) & 0xff;
-    *dst++ = (argb >>  8) & 0xff;
-    *dst++ = (argb >>  0) & 0xff;
-    *dst++ = (argb >> 24) & 0xff;
-  }
-}
-
-static void ConvertBGRAToRGBA4444(const uint32_t* src,
-                                  int num_pixels, uint8_t* dst) {
-  const uint32_t* const src_end = src + num_pixels;
-  while (src < src_end) {
-    const uint32_t argb = *src++;
-    *dst++ = ((argb >> 16) & 0xf0) | ((argb >> 12) & 0xf);
-    *dst++ = ((argb >>  0) & 0xf0) | ((argb >> 28) & 0xf);
-  }
-}
-
-static void ConvertBGRAToRGB565(const uint32_t* src,
-                                int num_pixels, uint8_t* dst) {
-  const uint32_t* const src_end = src + num_pixels;
-  while (src < src_end) {
-    const uint32_t argb = *src++;
-    *dst++ = ((argb >> 16) & 0xf8) | ((argb >> 13) & 0x7);
-    *dst++ = ((argb >>  5) & 0xe0) | ((argb >>  3) & 0x1f);
-  }
-}
-
-static void ConvertBGRAToBGR(const uint32_t* src,
-                             int num_pixels, uint8_t* dst) {
-  const uint32_t* const src_end = src + num_pixels;
-  while (src < src_end) {
-    const uint32_t argb = *src++;
-    *dst++ = (argb >>  0) & 0xff;
-    *dst++ = (argb >>  8) & 0xff;
-    *dst++ = (argb >> 16) & 0xff;
-  }
-}
-
-static void CopyOrSwap(const uint32_t* src, int num_pixels, uint8_t* dst,
-                       int swap_on_big_endian) {
-  if (is_big_endian() == swap_on_big_endian) {
-    const uint32_t* const src_end = src + num_pixels;
-    while (src < src_end) {
-      uint32_t argb = *src++;
-#if !defined(__BIG_ENDIAN__) && (defined(__i386__) || defined(__x86_64__))
-      __asm__ volatile("bswap %0" : "=r"(argb) : "0"(argb));
-      *(uint32_t*)dst = argb;
-      dst += sizeof(argb);
-#elif !defined(__BIG_ENDIAN__) && defined(_MSC_VER)
-      argb = _byteswap_ulong(argb);
-      *(uint32_t*)dst = argb;
-      dst += sizeof(argb);
-#else
-      *dst++ = (argb >> 24) & 0xff;
-      *dst++ = (argb >> 16) & 0xff;
-      *dst++ = (argb >>  8) & 0xff;
-      *dst++ = (argb >>  0) & 0xff;
-#endif
-    }
-  } else {
-    memcpy(dst, src, num_pixels * sizeof(*src));
-  }
-}
-
-void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
-                         WEBP_CSP_MODE out_colorspace, uint8_t* const rgba) {
-  switch (out_colorspace) {
-    case MODE_RGB:
-      ConvertBGRAToRGB(in_data, num_pixels, rgba);
-      break;
-    case MODE_RGBA:
-      ConvertBGRAToRGBA(in_data, num_pixels, rgba);
-      break;
-    case MODE_rgbA:
-      ConvertBGRAToRGBA(in_data, num_pixels, rgba);
-      WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0);
-      break;
-    case MODE_BGR:
-      ConvertBGRAToBGR(in_data, num_pixels, rgba);
-      break;
-    case MODE_BGRA:
-      CopyOrSwap(in_data, num_pixels, rgba, 1);
-      break;
-    case MODE_bgrA:
-      CopyOrSwap(in_data, num_pixels, rgba, 1);
-      WebPApplyAlphaMultiply(rgba, 0, num_pixels, 1, 0);
-      break;
-    case MODE_ARGB:
-      CopyOrSwap(in_data, num_pixels, rgba, 0);
-      break;
-    case MODE_Argb:
-      CopyOrSwap(in_data, num_pixels, rgba, 0);
-      WebPApplyAlphaMultiply(rgba, 1, num_pixels, 1, 0);
-      break;
-    case MODE_RGBA_4444:
-      ConvertBGRAToRGBA4444(in_data, num_pixels, rgba);
-      break;
-    case MODE_rgbA_4444:
-      ConvertBGRAToRGBA4444(in_data, num_pixels, rgba);
-      WebPApplyAlphaMultiply4444(rgba, num_pixels, 1, 0);
-      break;
-    case MODE_RGB_565:
-      ConvertBGRAToRGB565(in_data, num_pixels, rgba);
-      break;
-    default:
-      assert(0);          // Code flow should not reach here.
-  }
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 82
drivers/webpold/dsp/lossless.h

@@ -1,82 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Image transforms and color space conversion methods for lossless decoder.
-//
-// Authors: Vikas Arora ([email protected])
-//          Jyrki Alakuijala ([email protected])
-
-#ifndef WEBP_DSP_LOSSLESS_H_
-#define WEBP_DSP_LOSSLESS_H_
-
-#include "../types.h"
-#include "../decode.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Image transforms.
-
-struct VP8LTransform;  // Defined in dec/vp8li.h.
-
-// Performs inverse transform of data given transform information, start and end
-// rows. Transform will be applied to rows [row_start, row_end[.
-// The *in and *out pointers refer to source and destination data respectively
-// corresponding to the intermediate row (row_start).
-void VP8LInverseTransform(const struct VP8LTransform* const transform,
-                          int row_start, int row_end,
-                          const uint32_t* const in, uint32_t* const out);
-
-// Subtracts green from blue and red channels.
-void VP8LSubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixs);
-
-void VP8LResidualImage(int width, int height, int bits,
-                       uint32_t* const argb, uint32_t* const argb_scratch,
-                       uint32_t* const image);
-
-void VP8LColorSpaceTransform(int width, int height, int bits, int step,
-                             uint32_t* const argb, uint32_t* image);
-
-//------------------------------------------------------------------------------
-// Color space conversion.
-
-// Converts from BGRA to other color spaces.
-void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
-                         WEBP_CSP_MODE out_colorspace, uint8_t* const rgba);
-
-//------------------------------------------------------------------------------
-// Misc methods.
-
-// Computes sampled size of 'size' when sampling using 'sampling bits'.
-static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size,
-                                              uint32_t sampling_bits) {
-  return (size + (1 << sampling_bits) - 1) >> sampling_bits;
-}
-
-// Faster logarithm for integers, with the property of log2(0) == 0.
-float VP8LFastLog2(int v);
-// Fast calculation of v * log2(v) for integer input.
-static WEBP_INLINE float VP8LFastSLog2(int v) { return VP8LFastLog2(v) * v; }
-
-// In-place difference of each component with mod 256.
-static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) {
-  const uint32_t alpha_and_green =
-      0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u);
-  const uint32_t red_and_blue =
-      0xff00ff00u + (a & 0x00ff00ffu) - (b & 0x00ff00ffu);
-  return (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  // WEBP_DSP_LOSSLESS_H_

+ 0 - 357
drivers/webpold/dsp/upsampling.c

@@ -1,357 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// YUV to RGB upsampling functions.
-//
-// Author: [email protected] (Somnath Banerjee)
-
-#include "./dsp.h"
-#include "./yuv.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Fancy upsampler
-
-#ifdef FANCY_UPSAMPLING
-
-// Fancy upsampling functions to convert YUV to RGB
-WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST];
-
-// Given samples laid out in a square as:
-//  [a b]
-//  [c d]
-// we interpolate u/v as:
-//  ([9*a + 3*b + 3*c +   d    3*a + 9*b + 3*c +   d] + [8 8]) / 16
-//  ([3*a +   b + 9*c + 3*d      a + 3*b + 3*c + 9*d]   [8 8]) / 16
-
-// We process u and v together stashed into 32bit (16bit each).
-#define LOAD_UV(u,v) ((u) | ((v) << 16))
-
-#define UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP)                                  \
-static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y,           \
-                      const uint8_t* top_u, const uint8_t* top_v,              \
-                      const uint8_t* cur_u, const uint8_t* cur_v,              \
-                      uint8_t* top_dst, uint8_t* bottom_dst, int len) {        \
-  int x;                                                                       \
-  const int last_pixel_pair = (len - 1) >> 1;                                  \
-  uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]);   /* top-left sample */        \
-  uint32_t l_uv  = LOAD_UV(cur_u[0], cur_v[0]);   /* left-sample */            \
-  if (top_y) {                                                                 \
-    const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2;                \
-    FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst);                          \
-  }                                                                            \
-  if (bottom_y) {                                                              \
-    const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2;                \
-    FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst);                    \
-  }                                                                            \
-  for (x = 1; x <= last_pixel_pair; ++x) {                                     \
-    const uint32_t t_uv = LOAD_UV(top_u[x], top_v[x]);  /* top sample */       \
-    const uint32_t uv   = LOAD_UV(cur_u[x], cur_v[x]);  /* sample */           \
-    /* precompute invariant values associated with first and second diagonals*/\
-    const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u;               \
-    const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3;                   \
-    const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3;                    \
-    if (top_y) {                                                               \
-      const uint32_t uv0 = (diag_12 + tl_uv) >> 1;                             \
-      const uint32_t uv1 = (diag_03 + t_uv) >> 1;                              \
-      FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16),                          \
-           top_dst + (2 * x - 1) * XSTEP);                                     \
-      FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16),                          \
-           top_dst + (2 * x - 0) * XSTEP);                                     \
-    }                                                                          \
-    if (bottom_y) {                                                            \
-      const uint32_t uv0 = (diag_03 + l_uv) >> 1;                              \
-      const uint32_t uv1 = (diag_12 + uv) >> 1;                                \
-      FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16),                       \
-           bottom_dst + (2 * x - 1) * XSTEP);                                  \
-      FUNC(bottom_y[2 * x + 0], uv1 & 0xff, (uv1 >> 16),                       \
-           bottom_dst + (2 * x + 0) * XSTEP);                                  \
-    }                                                                          \
-    tl_uv = t_uv;                                                              \
-    l_uv = uv;                                                                 \
-  }                                                                            \
-  if (!(len & 1)) {                                                            \
-    if (top_y) {                                                               \
-      const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2;              \
-      FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16),                            \
-           top_dst + (len - 1) * XSTEP);                                       \
-    }                                                                          \
-    if (bottom_y) {                                                            \
-      const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2;              \
-      FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16),                         \
-           bottom_dst + (len - 1) * XSTEP);                                    \
-    }                                                                          \
-  }                                                                            \
-}
-
-// All variants implemented.
-UPSAMPLE_FUNC(UpsampleRgbLinePair,  VP8YuvToRgb,  3)
-UPSAMPLE_FUNC(UpsampleBgrLinePair,  VP8YuvToBgr,  3)
-UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
-UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
-UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4)
-UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2)
-UPSAMPLE_FUNC(UpsampleRgb565LinePair,  VP8YuvToRgb565,  2)
-
-#undef LOAD_UV
-#undef UPSAMPLE_FUNC
-
-#endif  // FANCY_UPSAMPLING
-
-//------------------------------------------------------------------------------
-// simple point-sampling
-
-#define SAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP)                                    \
-static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y,           \
-                      const uint8_t* u, const uint8_t* v,                      \
-                      uint8_t* top_dst, uint8_t* bottom_dst, int len) {        \
-  int i;                                                                       \
-  for (i = 0; i < len - 1; i += 2) {                                           \
-    FUNC(top_y[0], u[0], v[0], top_dst);                                       \
-    FUNC(top_y[1], u[0], v[0], top_dst + XSTEP);                               \
-    FUNC(bottom_y[0], u[0], v[0], bottom_dst);                                 \
-    FUNC(bottom_y[1], u[0], v[0], bottom_dst + XSTEP);                         \
-    top_y += 2;                                                                \
-    bottom_y += 2;                                                             \
-    u++;                                                                       \
-    v++;                                                                       \
-    top_dst += 2 * XSTEP;                                                      \
-    bottom_dst += 2 * XSTEP;                                                   \
-  }                                                                            \
-  if (i == len - 1) {    /* last one */                                        \
-    FUNC(top_y[0], u[0], v[0], top_dst);                                       \
-    FUNC(bottom_y[0], u[0], v[0], bottom_dst);                                 \
-  }                                                                            \
-}
-
-// All variants implemented.
-SAMPLE_FUNC(SampleRgbLinePair,      VP8YuvToRgb,  3)
-SAMPLE_FUNC(SampleBgrLinePair,      VP8YuvToBgr,  3)
-SAMPLE_FUNC(SampleRgbaLinePair,     VP8YuvToRgba, 4)
-SAMPLE_FUNC(SampleBgraLinePair,     VP8YuvToBgra, 4)
-SAMPLE_FUNC(SampleArgbLinePair,     VP8YuvToArgb, 4)
-SAMPLE_FUNC(SampleRgba4444LinePair, VP8YuvToRgba4444, 2)
-SAMPLE_FUNC(SampleRgb565LinePair,   VP8YuvToRgb565, 2)
-
-#undef SAMPLE_FUNC
-
-const WebPSampleLinePairFunc WebPSamplers[MODE_LAST] = {
-  SampleRgbLinePair,       // MODE_RGB
-  SampleRgbaLinePair,      // MODE_RGBA
-  SampleBgrLinePair,       // MODE_BGR
-  SampleBgraLinePair,      // MODE_BGRA
-  SampleArgbLinePair,      // MODE_ARGB
-  SampleRgba4444LinePair,  // MODE_RGBA_4444
-  SampleRgb565LinePair,    // MODE_RGB_565
-  SampleRgbaLinePair,      // MODE_rgbA
-  SampleBgraLinePair,      // MODE_bgrA
-  SampleArgbLinePair,      // MODE_Argb
-  SampleRgba4444LinePair   // MODE_rgbA_4444
-};
-
-//------------------------------------------------------------------------------
-
-#if !defined(FANCY_UPSAMPLING)
-#define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC)                                      \
-static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y,              \
-                      const uint8_t* top_u, const uint8_t* top_v,              \
-                      const uint8_t* bot_u, const uint8_t* bot_v,              \
-                      uint8_t* top_dst, uint8_t* bot_dst, int len) {           \
-  const int half_len = len >> 1;                                               \
-  int x;                                                                       \
-  if (top_dst != NULL) {                                                       \
-    for (x = 0; x < half_len; ++x) {                                           \
-      FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0);         \
-      FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4);         \
-    }                                                                          \
-    if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x);  \
-  }                                                                            \
-  if (bot_dst != NULL) {                                                       \
-    for (x = 0; x < half_len; ++x) {                                           \
-      FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0);         \
-      FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4);         \
-    }                                                                          \
-    if (len & 1) FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x);  \
-  }                                                                            \
-}
-
-DUAL_SAMPLE_FUNC(DualLineSamplerBGRA, VP8YuvToBgra)
-DUAL_SAMPLE_FUNC(DualLineSamplerARGB, VP8YuvToArgb)
-#undef DUAL_SAMPLE_FUNC
-
-#endif  // !FANCY_UPSAMPLING
-
-WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last) {
-  WebPInitUpsamplers();
-  VP8YUVInit();
-#ifdef FANCY_UPSAMPLING
-  return WebPUpsamplers[alpha_is_last ? MODE_BGRA : MODE_ARGB];
-#else
-  return (alpha_is_last ? DualLineSamplerBGRA : DualLineSamplerARGB);
-#endif
-}
-
-//------------------------------------------------------------------------------
-// YUV444 converter
-
-#define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP)                                    \
-static void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v,    \
-                      uint8_t* dst, int len) {                                 \
-  int i;                                                                       \
-  for (i = 0; i < len; ++i) FUNC(y[i], u[i], v[i], &dst[i * XSTEP]);           \
-}
-
-YUV444_FUNC(Yuv444ToRgb,      VP8YuvToRgb,  3)
-YUV444_FUNC(Yuv444ToBgr,      VP8YuvToBgr,  3)
-YUV444_FUNC(Yuv444ToRgba,     VP8YuvToRgba, 4)
-YUV444_FUNC(Yuv444ToBgra,     VP8YuvToBgra, 4)
-YUV444_FUNC(Yuv444ToArgb,     VP8YuvToArgb, 4)
-YUV444_FUNC(Yuv444ToRgba4444, VP8YuvToRgba4444, 2)
-YUV444_FUNC(Yuv444ToRgb565,   VP8YuvToRgb565, 2)
-
-#undef YUV444_FUNC
-
-const WebPYUV444Converter WebPYUV444Converters[MODE_LAST] = {
-  Yuv444ToRgb,       // MODE_RGB
-  Yuv444ToRgba,      // MODE_RGBA
-  Yuv444ToBgr,       // MODE_BGR
-  Yuv444ToBgra,      // MODE_BGRA
-  Yuv444ToArgb,      // MODE_ARGB
-  Yuv444ToRgba4444,  // MODE_RGBA_4444
-  Yuv444ToRgb565,    // MODE_RGB_565
-  Yuv444ToRgba,      // MODE_rgbA
-  Yuv444ToBgra,      // MODE_bgrA
-  Yuv444ToArgb,      // MODE_Argb
-  Yuv444ToRgba4444   // MODE_rgbA_4444
-};
-
-//------------------------------------------------------------------------------
-// Premultiplied modes
-
-// non dithered-modes
-
-// (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.)
-// for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5),
-// one can use instead: (x * a * 65793 + (1 << 23)) >> 24
-#if 1     // (int)(x * a / 255.)
-#define MULTIPLIER(a)   ((a) * 32897UL)
-#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
-#else     // (int)(x * a / 255. + .5)
-#define MULTIPLIER(a) ((a) * 65793UL)
-#define PREMULTIPLY(x, m) (((x) * (m) + (1UL << 23)) >> 24)
-#endif
-
-static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
-                               int w, int h, int stride) {
-  while (h-- > 0) {
-    uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
-    const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
-    int i;
-    for (i = 0; i < w; ++i) {
-      const uint32_t a = alpha[4 * i];
-      if (a != 0xff) {
-        const uint32_t mult = MULTIPLIER(a);
-        rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
-        rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
-        rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
-      }
-    }
-    rgba += stride;
-  }
-}
-#undef MULTIPLIER
-#undef PREMULTIPLY
-
-// rgbA4444
-
-#define MULTIPLIER(a)  ((a) * 0x1111)    // 0x1111 ~= (1 << 16) / 15
-
-static WEBP_INLINE uint8_t dither_hi(uint8_t x) {
-  return (x & 0xf0) | (x >> 4);
-}
-
-static WEBP_INLINE uint8_t dither_lo(uint8_t x) {
-  return (x & 0x0f) | (x << 4);
-}
-
-static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
-  return (x * m) >> 16;
-}
-
-static void ApplyAlphaMultiply4444(uint8_t* rgba4444,
-                                   int w, int h, int stride) {
-  while (h-- > 0) {
-    int i;
-    for (i = 0; i < w; ++i) {
-      const uint8_t a = (rgba4444[2 * i + 1] & 0x0f);
-      const uint32_t mult = MULTIPLIER(a);
-      const uint8_t r = multiply(dither_hi(rgba4444[2 * i + 0]), mult);
-      const uint8_t g = multiply(dither_lo(rgba4444[2 * i + 0]), mult);
-      const uint8_t b = multiply(dither_hi(rgba4444[2 * i + 1]), mult);
-      rgba4444[2 * i + 0] = (r & 0xf0) | ((g >> 4) & 0x0f);
-      rgba4444[2 * i + 1] = (b & 0xf0) | a;
-    }
-    rgba4444 += stride;
-  }
-}
-#undef MULTIPLIER
-
-void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int)
-    = ApplyAlphaMultiply;
-void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int)
-    = ApplyAlphaMultiply4444;
-
-//------------------------------------------------------------------------------
-// Main call
-
-void WebPInitUpsamplers(void) {
-#ifdef FANCY_UPSAMPLING
-  WebPUpsamplers[MODE_RGB]       = UpsampleRgbLinePair;
-  WebPUpsamplers[MODE_RGBA]      = UpsampleRgbaLinePair;
-  WebPUpsamplers[MODE_BGR]       = UpsampleBgrLinePair;
-  WebPUpsamplers[MODE_BGRA]      = UpsampleBgraLinePair;
-  WebPUpsamplers[MODE_ARGB]      = UpsampleArgbLinePair;
-  WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
-  WebPUpsamplers[MODE_RGB_565]   = UpsampleRgb565LinePair;
-
-  // If defined, use CPUInfo() to overwrite some pointers with faster versions.
-  if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
-    if (VP8GetCPUInfo(kSSE2)) {
-      WebPInitUpsamplersSSE2();
-    }
-#endif
-  }
-#endif  // FANCY_UPSAMPLING
-}
-
-void WebPInitPremultiply(void) {
-  WebPApplyAlphaMultiply = ApplyAlphaMultiply;
-  WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply4444;
-
-#ifdef FANCY_UPSAMPLING
-  WebPUpsamplers[MODE_rgbA]      = UpsampleRgbaLinePair;
-  WebPUpsamplers[MODE_bgrA]      = UpsampleBgraLinePair;
-  WebPUpsamplers[MODE_Argb]      = UpsampleArgbLinePair;
-  WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
-
-  if (VP8GetCPUInfo != NULL) {
-#if defined(WEBP_USE_SSE2)
-    if (VP8GetCPUInfo(kSSE2)) {
-      WebPInitPremultiplySSE2();
-    }
-#endif
-  }
-#endif  // FANCY_UPSAMPLING
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 209
drivers/webpold/dsp/upsampling_sse2.c

@@ -1,209 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// SSE2 version of YUV to RGB upsampling functions.
-//
-// Author: [email protected] (Somnath Banerjee)
-
-#include "./dsp.h"
-
-#if defined(WEBP_USE_SSE2)
-
-#include <assert.h>
-#include <emmintrin.h>
-#include <string.h>
-#include "./yuv.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#ifdef FANCY_UPSAMPLING
-
-// We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows
-// u = (9*a + 3*b + 3*c + d + 8) / 16
-//   = (a + (a + 3*b + 3*c + d) / 8 + 1) / 2
-//   = (a + m + 1) / 2
-// where m = (a + 3*b + 3*c + d) / 8
-//         = ((a + b + c + d) / 2 + b + c) / 4
-//
-// Let's say  k = (a + b + c + d) / 4.
-// We can compute k as
-// k = (s + t + 1) / 2 - ((a^d) | (b^c) | (s^t)) & 1
-// where s = (a + d + 1) / 2 and t = (b + c + 1) / 2
-//
-// Then m can be written as
-// m = (k + t + 1) / 2 - (((b^c) & (s^t)) | (k^t)) & 1
-
-// Computes out = (k + in + 1) / 2 - ((ij & (s^t)) | (k^in)) & 1
-#define GET_M(ij, in, out) do {                                                \
-  const __m128i tmp0 = _mm_avg_epu8(k, (in));     /* (k + in + 1) / 2 */       \
-  const __m128i tmp1 = _mm_and_si128((ij), st);   /* (ij) & (s^t) */           \
-  const __m128i tmp2 = _mm_xor_si128(k, (in));    /* (k^in) */                 \
-  const __m128i tmp3 = _mm_or_si128(tmp1, tmp2);  /* ((ij) & (s^t)) | (k^in) */\
-  const __m128i tmp4 = _mm_and_si128(tmp3, one);  /* & 1 -> lsb_correction */  \
-  (out) = _mm_sub_epi8(tmp0, tmp4);    /* (k + in + 1) / 2 - lsb_correction */ \
-} while (0)
-
-// pack and store two alterning pixel rows
-#define PACK_AND_STORE(a, b, da, db, out) do {                                 \
-  const __m128i ta = _mm_avg_epu8(a, da);  /* (9a + 3b + 3c +  d + 8) / 16 */  \
-  const __m128i tb = _mm_avg_epu8(b, db);  /* (3a + 9b +  c + 3d + 8) / 16 */  \
-  const __m128i t1 = _mm_unpacklo_epi8(ta, tb);                                \
-  const __m128i t2 = _mm_unpackhi_epi8(ta, tb);                                \
-  _mm_store_si128(((__m128i*)(out)) + 0, t1);                                  \
-  _mm_store_si128(((__m128i*)(out)) + 1, t2);                                  \
-} while (0)
-
-// Loads 17 pixels each from rows r1 and r2 and generates 32 pixels.
-#define UPSAMPLE_32PIXELS(r1, r2, out) {                                       \
-  const __m128i one = _mm_set1_epi8(1);                                        \
-  const __m128i a = _mm_loadu_si128((__m128i*)&(r1)[0]);                       \
-  const __m128i b = _mm_loadu_si128((__m128i*)&(r1)[1]);                       \
-  const __m128i c = _mm_loadu_si128((__m128i*)&(r2)[0]);                       \
-  const __m128i d = _mm_loadu_si128((__m128i*)&(r2)[1]);                       \
-                                                                               \
-  const __m128i s = _mm_avg_epu8(a, d);        /* s = (a + d + 1) / 2 */       \
-  const __m128i t = _mm_avg_epu8(b, c);        /* t = (b + c + 1) / 2 */       \
-  const __m128i st = _mm_xor_si128(s, t);      /* st = s^t */                  \
-                                                                               \
-  const __m128i ad = _mm_xor_si128(a, d);      /* ad = a^d */                  \
-  const __m128i bc = _mm_xor_si128(b, c);      /* bc = b^c */                  \
-                                                                               \
-  const __m128i t1 = _mm_or_si128(ad, bc);     /* (a^d) | (b^c) */             \
-  const __m128i t2 = _mm_or_si128(t1, st);     /* (a^d) | (b^c) | (s^t) */     \
-  const __m128i t3 = _mm_and_si128(t2, one);   /* (a^d) | (b^c) | (s^t) & 1 */ \
-  const __m128i t4 = _mm_avg_epu8(s, t);                                       \
-  const __m128i k = _mm_sub_epi8(t4, t3);      /* k = (a + b + c + d) / 4 */   \
-  __m128i diag1, diag2;                                                        \
-                                                                               \
-  GET_M(bc, t, diag1);                  /* diag1 = (a + 3b + 3c + d) / 8 */    \
-  GET_M(ad, s, diag2);                  /* diag2 = (3a + b + c + 3d) / 8 */    \
-                                                                               \
-  /* pack the alternate pixels */                                              \
-  PACK_AND_STORE(a, b, diag1, diag2, &(out)[0 * 32]);                          \
-  PACK_AND_STORE(c, d, diag2, diag1, &(out)[2 * 32]);                          \
-}
-
-// Turn the macro into a function for reducing code-size when non-critical
-static void Upsample32Pixels(const uint8_t r1[], const uint8_t r2[],
-                             uint8_t* const out) {
-  UPSAMPLE_32PIXELS(r1, r2, out);
-}
-
-#define UPSAMPLE_LAST_BLOCK(tb, bb, num_pixels, out) {                         \
-  uint8_t r1[17], r2[17];                                                      \
-  memcpy(r1, (tb), (num_pixels));                                              \
-  memcpy(r2, (bb), (num_pixels));                                              \
-  /* replicate last byte */                                                    \
-  memset(r1 + (num_pixels), r1[(num_pixels) - 1], 17 - (num_pixels));          \
-  memset(r2 + (num_pixels), r2[(num_pixels) - 1], 17 - (num_pixels));          \
-  /* using the shared function instead of the macro saves ~3k code size */     \
-  Upsample32Pixels(r1, r2, out);                                               \
-}
-
-#define CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, uv,                          \
-                    top_dst, bottom_dst, cur_x, num_pixels) {                  \
-  int n;                                                                       \
-  if (top_y) {                                                                 \
-    for (n = 0; n < (num_pixels); ++n) {                                       \
-      FUNC(top_y[(cur_x) + n], (uv)[n], (uv)[32 + n],                          \
-           top_dst + ((cur_x) + n) * XSTEP);                                   \
-    }                                                                          \
-  }                                                                            \
-  if (bottom_y) {                                                              \
-    for (n = 0; n < (num_pixels); ++n) {                                       \
-      FUNC(bottom_y[(cur_x) + n], (uv)[64 + n], (uv)[64 + 32 + n],             \
-           bottom_dst + ((cur_x) + n) * XSTEP);                                \
-    }                                                                          \
-  }                                                                            \
-}
-
-#define SSE2_UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP)                             \
-static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y,           \
-                      const uint8_t* top_u, const uint8_t* top_v,              \
-                      const uint8_t* cur_u, const uint8_t* cur_v,              \
-                      uint8_t* top_dst, uint8_t* bottom_dst, int len) {        \
-  int b;                                                                       \
-  /* 16 byte aligned array to cache reconstructed u and v */                   \
-  uint8_t uv_buf[4 * 32 + 15];                                                 \
-  uint8_t* const r_uv = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15);            \
-  const int uv_len = (len + 1) >> 1;                                           \
-  /* 17 pixels must be read-able for each block */                             \
-  const int num_blocks = (uv_len - 1) >> 4;                                    \
-  const int leftover = uv_len - num_blocks * 16;                               \
-  const int last_pos = 1 + 32 * num_blocks;                                    \
-                                                                               \
-  const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1;                         \
-  const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1;                         \
-                                                                               \
-  assert(len > 0);                                                             \
-  /* Treat the first pixel in regular way */                                   \
-  if (top_y) {                                                                 \
-    const int u0 = (top_u[0] + u_diag) >> 1;                                   \
-    const int v0 = (top_v[0] + v_diag) >> 1;                                   \
-    FUNC(top_y[0], u0, v0, top_dst);                                           \
-  }                                                                            \
-  if (bottom_y) {                                                              \
-    const int u0 = (cur_u[0] + u_diag) >> 1;                                   \
-    const int v0 = (cur_v[0] + v_diag) >> 1;                                   \
-    FUNC(bottom_y[0], u0, v0, bottom_dst);                                     \
-  }                                                                            \
-                                                                               \
-  for (b = 0; b < num_blocks; ++b) {                                           \
-    UPSAMPLE_32PIXELS(top_u, cur_u, r_uv + 0 * 32);                            \
-    UPSAMPLE_32PIXELS(top_v, cur_v, r_uv + 1 * 32);                            \
-    CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, r_uv, top_dst, bottom_dst,       \
-                32 * b + 1, 32)                                                \
-    top_u += 16;                                                               \
-    cur_u += 16;                                                               \
-    top_v += 16;                                                               \
-    cur_v += 16;                                                               \
-  }                                                                            \
-                                                                               \
-  UPSAMPLE_LAST_BLOCK(top_u, cur_u, leftover, r_uv + 0 * 32);                  \
-  UPSAMPLE_LAST_BLOCK(top_v, cur_v, leftover, r_uv + 1 * 32);                  \
-  CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, r_uv, top_dst, bottom_dst,         \
-              last_pos, len - last_pos);                                       \
-}
-
-// SSE2 variants of the fancy upsampler.
-SSE2_UPSAMPLE_FUNC(UpsampleRgbLinePairSSE2,  VP8YuvToRgb,  3)
-SSE2_UPSAMPLE_FUNC(UpsampleBgrLinePairSSE2,  VP8YuvToBgr,  3)
-SSE2_UPSAMPLE_FUNC(UpsampleRgbaLinePairSSE2, VP8YuvToRgba, 4)
-SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePairSSE2, VP8YuvToBgra, 4)
-
-#undef GET_M
-#undef PACK_AND_STORE
-#undef UPSAMPLE_32PIXELS
-#undef UPSAMPLE_LAST_BLOCK
-#undef CONVERT2RGB
-#undef SSE2_UPSAMPLE_FUNC
-
-//------------------------------------------------------------------------------
-
-extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
-
-void WebPInitUpsamplersSSE2(void) {
-  WebPUpsamplers[MODE_RGB]  = UpsampleRgbLinePairSSE2;
-  WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePairSSE2;
-  WebPUpsamplers[MODE_BGR]  = UpsampleBgrLinePairSSE2;
-  WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePairSSE2;
-}
-
-void WebPInitPremultiplySSE2(void) {
-  WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePairSSE2;
-  WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePairSSE2;
-}
-
-#endif  // FANCY_UPSAMPLING
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif   // WEBP_USE_SSE2

+ 0 - 52
drivers/webpold/dsp/yuv.c

@@ -1,52 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// YUV->RGB conversion function
-//
-// Author: Skal ([email protected])
-
-#include "./yuv.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-enum { YUV_HALF = 1 << (YUV_FIX - 1) };
-
-int16_t VP8kVToR[256], VP8kUToB[256];
-int32_t VP8kVToG[256], VP8kUToG[256];
-uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
-uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
-
-static int done = 0;
-
-static WEBP_INLINE uint8_t clip(int v, int max_value) {
-  return v < 0 ? 0 : v > max_value ? max_value : v;
-}
-
-void VP8YUVInit(void) {
-  int i;
-  if (done) {
-    return;
-  }
-  for (i = 0; i < 256; ++i) {
-    VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX;
-    VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF;
-    VP8kVToG[i] = -45773 * (i - 128);
-    VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX;
-  }
-  for (i = YUV_RANGE_MIN; i < YUV_RANGE_MAX; ++i) {
-    const int k = ((i - 16) * 76283 + YUV_HALF) >> YUV_FIX;
-    VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255);
-    VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15);
-  }
-  done = 1;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 128
drivers/webpold/dsp/yuv.h

@@ -1,128 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// inline YUV<->RGB conversion function
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_DSP_YUV_H_
-#define WEBP_DSP_YUV_H_
-
-#include "../dec/decode_vp8.h"
-
-//------------------------------------------------------------------------------
-// YUV -> RGB conversion
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-enum { YUV_FIX = 16,                // fixed-point precision
-       YUV_RANGE_MIN = -227,        // min value of r/g/b output
-       YUV_RANGE_MAX = 256 + 226    // max value of r/g/b output
-};
-extern int16_t VP8kVToR[256], VP8kUToB[256];
-extern int32_t VP8kVToG[256], VP8kUToG[256];
-extern uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
-extern uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
-
-static WEBP_INLINE void VP8YuvToRgb(uint8_t y, uint8_t u, uint8_t v,
-                                    uint8_t* const rgb) {
-  const int r_off = VP8kVToR[v];
-  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
-  const int b_off = VP8kUToB[u];
-  rgb[0] = VP8kClip[y + r_off - YUV_RANGE_MIN];
-  rgb[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
-  rgb[2] = VP8kClip[y + b_off - YUV_RANGE_MIN];
-}
-
-static WEBP_INLINE void VP8YuvToRgb565(uint8_t y, uint8_t u, uint8_t v,
-                                       uint8_t* const rgb) {
-  const int r_off = VP8kVToR[v];
-  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
-  const int b_off = VP8kUToB[u];
-  rgb[0] = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) |
-            (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5));
-  rgb[1] = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) |
-            (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3));
-}
-
-static WEBP_INLINE void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
-                                     uint8_t* const argb) {
-  argb[0] = 0xff;
-  VP8YuvToRgb(y, u, v, argb + 1);
-}
-
-static WEBP_INLINE void VP8YuvToRgba4444(uint8_t y, uint8_t u, uint8_t v,
-                                         uint8_t* const argb) {
-  const int r_off = VP8kVToR[v];
-  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
-  const int b_off = VP8kUToB[u];
-  // Don't update alpha (last 4 bits of argb[1])
-  argb[0] = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) |
-             VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]);
-  argb[1] = 0x0f | (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4);
-}
-
-static WEBP_INLINE void VP8YuvToBgr(uint8_t y, uint8_t u, uint8_t v,
-                                    uint8_t* const bgr) {
-  const int r_off = VP8kVToR[v];
-  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
-  const int b_off = VP8kUToB[u];
-  bgr[0] = VP8kClip[y + b_off - YUV_RANGE_MIN];
-  bgr[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
-  bgr[2] = VP8kClip[y + r_off - YUV_RANGE_MIN];
-}
-
-static WEBP_INLINE void VP8YuvToBgra(uint8_t y, uint8_t u, uint8_t v,
-                                     uint8_t* const bgra) {
-  VP8YuvToBgr(y, u, v, bgra);
-  bgra[3] = 0xff;
-}
-
-static WEBP_INLINE void VP8YuvToRgba(uint8_t y, uint8_t u, uint8_t v,
-                                     uint8_t* const rgba) {
-  VP8YuvToRgb(y, u, v, rgba);
-  rgba[3] = 0xff;
-}
-
-// Must be called before everything, to initialize the tables.
-void VP8YUVInit(void);
-
-//------------------------------------------------------------------------------
-// RGB -> YUV conversion
-// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
-// More information at: http://en.wikipedia.org/wiki/YCbCr
-// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
-// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
-// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
-// We use 16bit fixed point operations.
-
-static WEBP_INLINE int VP8ClipUV(int v) {
-   v = (v + (257 << (YUV_FIX + 2 - 1))) >> (YUV_FIX + 2);
-   return ((v & ~0xff) == 0) ? v : (v < 0) ? 0 : 255;
-}
-
-static WEBP_INLINE int VP8RGBToY(int r, int g, int b) {
-  const int kRound = (1 << (YUV_FIX - 1)) + (16 << YUV_FIX);
-  const int luma = 16839 * r + 33059 * g + 6420 * b;
-  return (luma + kRound) >> YUV_FIX;  // no need to clip
-}
-
-static WEBP_INLINE int VP8RGBToU(int r, int g, int b) {
-  return VP8ClipUV(-9719 * r - 19081 * g + 28800 * b);
-}
-
-static WEBP_INLINE int VP8RGBToV(int r, int g, int b) {
-  return VP8ClipUV(+28800 * r - 24116 * g - 4684 * b);
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_DSP_YUV_H_ */

+ 0 - 330
drivers/webpold/enc/alpha.c

@@ -1,330 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Alpha-plane compression.
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "./vp8enci.h"
-#include "../utils/filters.h"
-#include "../utils/quant_levels.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// -----------------------------------------------------------------------------
-// Encodes the given alpha data via specified compression method 'method'.
-// The pre-processing (quantization) is performed if 'quality' is less than 100.
-// For such cases, the encoding is lossy. The valid range is [0, 100] for
-// 'quality' and [0, 1] for 'method':
-//   'method = 0' - No compression;
-//   'method = 1' - Use lossless coder on the alpha plane only
-// 'filter' values [0, 4] correspond to prediction modes none, horizontal,
-// vertical & gradient filters. The prediction mode 4 will try all the
-// prediction modes 0 to 3 and pick the best one.
-// 'effort_level': specifies how much effort must be spent to try and reduce
-//  the compressed output size. In range 0 (quick) to 6 (slow).
-//
-// 'output' corresponds to the buffer containing compressed alpha data.
-//          This buffer is allocated by this method and caller should call
-//          free(*output) when done.
-// 'output_size' corresponds to size of this compressed alpha buffer.
-//
-// Returns 1 on successfully encoding the alpha and
-//         0 if either:
-//           invalid quality or method, or
-//           memory allocation for the compressed data fails.
-
-#include "../enc/vp8li.h"
-
-static int EncodeLossless(const uint8_t* const data, int width, int height,
-                          int effort_level,  // in [0..6] range
-                          VP8BitWriter* const bw,
-                          WebPAuxStats* const stats) {
-  int ok = 0;
-  WebPConfig config;
-  WebPPicture picture;
-  VP8LBitWriter tmp_bw;
-
-  WebPPictureInit(&picture);
-  picture.width = width;
-  picture.height = height;
-  picture.use_argb = 1;
-  picture.stats = stats;
-  if (!WebPPictureAlloc(&picture)) return 0;
-
-  // Transfer the alpha values to the green channel.
-  {
-    int i, j;
-    uint32_t* dst = picture.argb;
-    const uint8_t* src = data;
-    for (j = 0; j < picture.height; ++j) {
-      for (i = 0; i < picture.width; ++i) {
-        dst[i] = (src[i] << 8) | 0xff000000u;
-      }
-      src += width;
-      dst += picture.argb_stride;
-    }
-  }
-
-  WebPConfigInit(&config);
-  config.lossless = 1;
-  config.method = effort_level;  // impact is very small
-  // Set moderate default quality setting for alpha. Higher qualities (80 and
-  // above) could be very slow.
-  config.quality = 10.f + 15.f * effort_level;
-  if (config.quality > 100.f) config.quality = 100.f;
-
-  ok = VP8LBitWriterInit(&tmp_bw, (width * height) >> 3);
-  ok = ok && (VP8LEncodeStream(&config, &picture, &tmp_bw) == VP8_ENC_OK);
-  WebPPictureFree(&picture);
-  if (ok) {
-    const uint8_t* const data = VP8LBitWriterFinish(&tmp_bw);
-    const size_t data_size = VP8LBitWriterNumBytes(&tmp_bw);
-    VP8BitWriterAppend(bw, data, data_size);
-  }
-  VP8LBitWriterDestroy(&tmp_bw);
-  return ok && !bw->error_;
-}
-
-// -----------------------------------------------------------------------------
-
-static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
-                               int method, int filter, int reduce_levels,
-                               int effort_level,  // in [0..6] range
-                               uint8_t* const tmp_alpha,
-                               VP8BitWriter* const bw,
-                               WebPAuxStats* const stats) {
-  int ok = 0;
-  const uint8_t* alpha_src;
-  WebPFilterFunc filter_func;
-  uint8_t header;
-  size_t expected_size;
-  const size_t data_size = width * height;
-
-  assert((uint64_t)data_size == (uint64_t)width * height);  // as per spec
-  assert(filter >= 0 && filter < WEBP_FILTER_LAST);
-  assert(method >= ALPHA_NO_COMPRESSION);
-  assert(method <= ALPHA_LOSSLESS_COMPRESSION);
-  assert(sizeof(header) == ALPHA_HEADER_LEN);
-  // TODO(skal): have a common function and #define's to validate alpha params.
-
-  expected_size =
-      (method == ALPHA_NO_COMPRESSION) ? (ALPHA_HEADER_LEN + data_size)
-                                       : (data_size >> 5);
-  header = method | (filter << 2);
-  if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4;
-
-  VP8BitWriterInit(bw, expected_size);
-  VP8BitWriterAppend(bw, &header, ALPHA_HEADER_LEN);
-
-  filter_func = WebPFilters[filter];
-  if (filter_func) {
-    filter_func(data, width, height, 1, width, tmp_alpha);
-    alpha_src = tmp_alpha;
-  }  else {
-    alpha_src = data;
-  }
-
-  if (method == ALPHA_NO_COMPRESSION) {
-    ok = VP8BitWriterAppend(bw, alpha_src, width * height);
-    ok = ok && !bw->error_;
-  } else {
-    ok = EncodeLossless(alpha_src, width, height, effort_level, bw, stats);
-    VP8BitWriterFinish(bw);
-  }
-  return ok;
-}
-
-// -----------------------------------------------------------------------------
-
-// TODO(skal): move to dsp/ ?
-static void CopyPlane(const uint8_t* src, int src_stride,
-                      uint8_t* dst, int dst_stride, int width, int height) {
-  while (height-- > 0) {
-    memcpy(dst, src, width);
-    src += src_stride;
-    dst += dst_stride;
-  }
-}
-
-static int EncodeAlpha(VP8Encoder* const enc,
-                       int quality, int method, int filter,
-                       int effort_level,
-                       uint8_t** const output, size_t* const output_size) {
-  const WebPPicture* const pic = enc->pic_;
-  const int width = pic->width;
-  const int height = pic->height;
-
-  uint8_t* quant_alpha = NULL;
-  const size_t data_size = width * height;
-  uint64_t sse = 0;
-  int ok = 1;
-  const int reduce_levels = (quality < 100);
-
-  // quick sanity checks
-  assert((uint64_t)data_size == (uint64_t)width * height);  // as per spec
-  assert(enc != NULL && pic != NULL && pic->a != NULL);
-  assert(output != NULL && output_size != NULL);
-  assert(width > 0 && height > 0);
-  assert(pic->a_stride >= width);
-  assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST);
-
-  if (quality < 0 || quality > 100) {
-    return 0;
-  }
-
-  if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) {
-    return 0;
-  }
-
-  quant_alpha = (uint8_t*)malloc(data_size);
-  if (quant_alpha == NULL) {
-    return 0;
-  }
-
-  // Extract alpha data (width x height) from raw_data (stride x height).
-  CopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height);
-
-  if (reduce_levels) {  // No Quantization required for 'quality = 100'.
-    // 16 alpha levels gives quite a low MSE w.r.t original alpha plane hence
-    // mapped to moderate quality 70. Hence Quality:[0, 70] -> Levels:[2, 16]
-    // and Quality:]70, 100] -> Levels:]16, 256].
-    const int alpha_levels = (quality <= 70) ? (2 + quality / 5)
-                                             : (16 + (quality - 70) * 8);
-    ok = QuantizeLevels(quant_alpha, width, height, alpha_levels, &sse);
-  }
-
-  if (ok) {
-    VP8BitWriter bw;
-    int test_filter;
-    uint8_t* filtered_alpha = NULL;
-
-    // We always test WEBP_FILTER_NONE first.
-    ok = EncodeAlphaInternal(quant_alpha, width, height,
-                             method, WEBP_FILTER_NONE, reduce_levels,
-                             effort_level, NULL, &bw, pic->stats);
-    if (!ok) {
-      VP8BitWriterWipeOut(&bw);
-      goto End;
-    }
-
-    if (filter == WEBP_FILTER_FAST) {  // Quick estimate of a second candidate?
-      filter = EstimateBestFilter(quant_alpha, width, height, width);
-    }
-    // Stop?
-    if (filter == WEBP_FILTER_NONE) {
-      goto Ok;
-    }
-
-    filtered_alpha = (uint8_t*)malloc(data_size);
-    ok = (filtered_alpha != NULL);
-    if (!ok) {
-      goto End;
-    }
-
-    // Try the other mode(s).
-    {
-      WebPAuxStats best_stats;
-      size_t best_score = VP8BitWriterSize(&bw);
-
-      memset(&best_stats, 0, sizeof(best_stats));  // prevent spurious warning
-      if (pic->stats != NULL) best_stats = *pic->stats;
-      for (test_filter = WEBP_FILTER_HORIZONTAL;
-           ok && (test_filter <= WEBP_FILTER_GRADIENT);
-           ++test_filter) {
-        VP8BitWriter tmp_bw;
-        if (filter != WEBP_FILTER_BEST && test_filter != filter) {
-          continue;
-        }
-        ok = EncodeAlphaInternal(quant_alpha, width, height,
-                                 method, test_filter, reduce_levels,
-                                 effort_level, filtered_alpha, &tmp_bw,
-                                 pic->stats);
-        if (ok) {
-          const size_t score = VP8BitWriterSize(&tmp_bw);
-          if (score < best_score) {
-            // swap bitwriter objects.
-            VP8BitWriter tmp = tmp_bw;
-            tmp_bw = bw;
-            bw = tmp;
-            best_score = score;
-            if (pic->stats != NULL) best_stats = *pic->stats;
-          }
-        } else {
-          VP8BitWriterWipeOut(&bw);
-        }
-        VP8BitWriterWipeOut(&tmp_bw);
-      }
-      if (pic->stats != NULL) *pic->stats = best_stats;
-    }
- Ok:
-    if (ok) {
-      *output_size = VP8BitWriterSize(&bw);
-      *output = VP8BitWriterBuf(&bw);
-      if (pic->stats != NULL) {         // need stats?
-        pic->stats->coded_size += (int)(*output_size);
-        enc->sse_[3] = sse;
-      }
-    }
-    free(filtered_alpha);
-  }
- End:
-  free(quant_alpha);
-  return ok;
-}
-
-
-//------------------------------------------------------------------------------
-// Main calls
-
-void VP8EncInitAlpha(VP8Encoder* const enc) {
-  enc->has_alpha_ = WebPPictureHasTransparency(enc->pic_);
-  enc->alpha_data_ = NULL;
-  enc->alpha_data_size_ = 0;
-}
-
-int VP8EncFinishAlpha(VP8Encoder* const enc) {
-  if (enc->has_alpha_) {
-    const WebPConfig* config = enc->config_;
-    uint8_t* tmp_data = NULL;
-    size_t tmp_size = 0;
-    const int effort_level = config->method;  // maps to [0..6]
-    const WEBP_FILTER_TYPE filter =
-        (config->alpha_filtering == 0) ? WEBP_FILTER_NONE :
-        (config->alpha_filtering == 1) ? WEBP_FILTER_FAST :
-                                         WEBP_FILTER_BEST;
-
-    if (!EncodeAlpha(enc, config->alpha_quality, config->alpha_compression,
-                     filter, effort_level, &tmp_data, &tmp_size)) {
-      return 0;
-    }
-    if (tmp_size != (uint32_t)tmp_size) {  // Sanity check.
-      free(tmp_data);
-      return 0;
-    }
-    enc->alpha_data_size_ = (uint32_t)tmp_size;
-    enc->alpha_data_ = tmp_data;
-  }
-  return WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
-}
-
-void VP8EncDeleteAlpha(VP8Encoder* const enc) {
-  free(enc->alpha_data_);
-  enc->alpha_data_ = NULL;
-  enc->alpha_data_size_ = 0;
-  enc->has_alpha_ = 0;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 364
drivers/webpold/enc/analysis.c

@@ -1,364 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Macroblock analysis
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "./vp8enci.h"
-#include "./cost.h"
-#include "../utils/utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define MAX_ITERS_K_MEANS  6
-
-static int ClipAlpha(int alpha) {
-  return alpha < 0 ? 0 : alpha > 255 ? 255 : alpha;
-}
-
-//------------------------------------------------------------------------------
-// Smooth the segment map by replacing isolated block by the majority of its
-// neighbours.
-
-static void SmoothSegmentMap(VP8Encoder* const enc) {
-  int n, x, y;
-  const int w = enc->mb_w_;
-  const int h = enc->mb_h_;
-  const int majority_cnt_3_x_3_grid = 5;
-  uint8_t* const tmp = (uint8_t*)WebPSafeMalloc((uint64_t)w * h, sizeof(*tmp));
-  assert((uint64_t)(w * h) == (uint64_t)w * h);   // no overflow, as per spec
-
-  if (tmp == NULL) return;
-  for (y = 1; y < h - 1; ++y) {
-    for (x = 1; x < w - 1; ++x) {
-      int cnt[NUM_MB_SEGMENTS] = { 0 };
-      const VP8MBInfo* const mb = &enc->mb_info_[x + w * y];
-      int majority_seg = mb->segment_;
-      // Check the 8 neighbouring segment values.
-      cnt[mb[-w - 1].segment_]++;  // top-left
-      cnt[mb[-w + 0].segment_]++;  // top
-      cnt[mb[-w + 1].segment_]++;  // top-right
-      cnt[mb[   - 1].segment_]++;  // left
-      cnt[mb[   + 1].segment_]++;  // right
-      cnt[mb[ w - 1].segment_]++;  // bottom-left
-      cnt[mb[ w + 0].segment_]++;  // bottom
-      cnt[mb[ w + 1].segment_]++;  // bottom-right
-      for (n = 0; n < NUM_MB_SEGMENTS; ++n) {
-        if (cnt[n] >= majority_cnt_3_x_3_grid) {
-          majority_seg = n;
-        }
-      }
-      tmp[x + y * w] = majority_seg;
-    }
-  }
-  for (y = 1; y < h - 1; ++y) {
-    for (x = 1; x < w - 1; ++x) {
-      VP8MBInfo* const mb = &enc->mb_info_[x + w * y];
-      mb->segment_ = tmp[x + y * w];
-    }
-  }
-  free(tmp);
-}
-
-//------------------------------------------------------------------------------
-// Finalize Segment probability based on the coding tree
-
-static int GetProba(int a, int b) {
-  int proba;
-  const int total = a + b;
-  if (total == 0) return 255;  // that's the default probability.
-  proba = (255 * a + total / 2) / total;
-  return proba;
-}
-
-static void SetSegmentProbas(VP8Encoder* const enc) {
-  int p[NUM_MB_SEGMENTS] = { 0 };
-  int n;
-
-  for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) {
-    const VP8MBInfo* const mb = &enc->mb_info_[n];
-    p[mb->segment_]++;
-  }
-  if (enc->pic_->stats) {
-    for (n = 0; n < NUM_MB_SEGMENTS; ++n) {
-      enc->pic_->stats->segment_size[n] = p[n];
-    }
-  }
-  if (enc->segment_hdr_.num_segments_ > 1) {
-    uint8_t* const probas = enc->proba_.segments_;
-    probas[0] = GetProba(p[0] + p[1], p[2] + p[3]);
-    probas[1] = GetProba(p[0], p[1]);
-    probas[2] = GetProba(p[2], p[3]);
-
-    enc->segment_hdr_.update_map_ =
-        (probas[0] != 255) || (probas[1] != 255) || (probas[2] != 255);
-    enc->segment_hdr_.size_ =
-      p[0] * (VP8BitCost(0, probas[0]) + VP8BitCost(0, probas[1])) +
-      p[1] * (VP8BitCost(0, probas[0]) + VP8BitCost(1, probas[1])) +
-      p[2] * (VP8BitCost(1, probas[0]) + VP8BitCost(0, probas[2])) +
-      p[3] * (VP8BitCost(1, probas[0]) + VP8BitCost(1, probas[2]));
-  } else {
-    enc->segment_hdr_.update_map_ = 0;
-    enc->segment_hdr_.size_ = 0;
-  }
-}
-
-static WEBP_INLINE int clip(int v, int m, int M) {
-  return v < m ? m : v > M ? M : v;
-}
-
-static void SetSegmentAlphas(VP8Encoder* const enc,
-                             const int centers[NUM_MB_SEGMENTS],
-                             int mid) {
-  const int nb = enc->segment_hdr_.num_segments_;
-  int min = centers[0], max = centers[0];
-  int n;
-
-  if (nb > 1) {
-    for (n = 0; n < nb; ++n) {
-      if (min > centers[n]) min = centers[n];
-      if (max < centers[n]) max = centers[n];
-    }
-  }
-  if (max == min) max = min + 1;
-  assert(mid <= max && mid >= min);
-  for (n = 0; n < nb; ++n) {
-    const int alpha = 255 * (centers[n] - mid) / (max - min);
-    const int beta = 255 * (centers[n] - min) / (max - min);
-    enc->dqm_[n].alpha_ = clip(alpha, -127, 127);
-    enc->dqm_[n].beta_ = clip(beta, 0, 255);
-  }
-}
-
-//------------------------------------------------------------------------------
-// Simplified k-Means, to assign Nb segments based on alpha-histogram
-
-static void AssignSegments(VP8Encoder* const enc, const int alphas[256]) {
-  const int nb = enc->segment_hdr_.num_segments_;
-  int centers[NUM_MB_SEGMENTS];
-  int weighted_average = 0;
-  int map[256];
-  int a, n, k;
-  int min_a = 0, max_a = 255, range_a;
-  // 'int' type is ok for histo, and won't overflow
-  int accum[NUM_MB_SEGMENTS], dist_accum[NUM_MB_SEGMENTS];
-
-  // bracket the input
-  for (n = 0; n < 256 && alphas[n] == 0; ++n) {}
-  min_a = n;
-  for (n = 255; n > min_a && alphas[n] == 0; --n) {}
-  max_a = n;
-  range_a = max_a - min_a;
-
-  // Spread initial centers evenly
-  for (n = 1, k = 0; n < 2 * nb; n += 2) {
-    centers[k++] = min_a + (n * range_a) / (2 * nb);
-  }
-
-  for (k = 0; k < MAX_ITERS_K_MEANS; ++k) {     // few iters are enough
-    int total_weight;
-    int displaced;
-    // Reset stats
-    for (n = 0; n < nb; ++n) {
-      accum[n] = 0;
-      dist_accum[n] = 0;
-    }
-    // Assign nearest center for each 'a'
-    n = 0;    // track the nearest center for current 'a'
-    for (a = min_a; a <= max_a; ++a) {
-      if (alphas[a]) {
-        while (n < nb - 1 && abs(a - centers[n + 1]) < abs(a - centers[n])) {
-          n++;
-        }
-        map[a] = n;
-        // accumulate contribution into best centroid
-        dist_accum[n] += a * alphas[a];
-        accum[n] += alphas[a];
-      }
-    }
-    // All point are classified. Move the centroids to the
-    // center of their respective cloud.
-    displaced = 0;
-    weighted_average = 0;
-    total_weight = 0;
-    for (n = 0; n < nb; ++n) {
-      if (accum[n]) {
-        const int new_center = (dist_accum[n] + accum[n] / 2) / accum[n];
-        displaced += abs(centers[n] - new_center);
-        centers[n] = new_center;
-        weighted_average += new_center * accum[n];
-        total_weight += accum[n];
-      }
-    }
-    weighted_average = (weighted_average + total_weight / 2) / total_weight;
-    if (displaced < 5) break;   // no need to keep on looping...
-  }
-
-  // Map each original value to the closest centroid
-  for (n = 0; n < enc->mb_w_ * enc->mb_h_; ++n) {
-    VP8MBInfo* const mb = &enc->mb_info_[n];
-    const int alpha = mb->alpha_;
-    mb->segment_ = map[alpha];
-    mb->alpha_ = centers[map[alpha]];     // just for the record.
-  }
-
-  if (nb > 1) {
-    const int smooth = (enc->config_->preprocessing & 1);
-    if (smooth) SmoothSegmentMap(enc);
-  }
-
-  SetSegmentProbas(enc);                             // Assign final proba
-  SetSegmentAlphas(enc, centers, weighted_average);  // pick some alphas.
-}
-
-//------------------------------------------------------------------------------
-// Macroblock analysis: collect histogram for each mode, deduce the maximal
-// susceptibility and set best modes for this macroblock.
-// Segment assignment is done later.
-
-// Number of modes to inspect for alpha_ evaluation. For high-quality settings,
-// we don't need to test all the possible modes during the analysis phase.
-#define MAX_INTRA16_MODE 2
-#define MAX_INTRA4_MODE  2
-#define MAX_UV_MODE      2
-
-static int MBAnalyzeBestIntra16Mode(VP8EncIterator* const it) {
-  const int max_mode = (it->enc_->method_ >= 3) ? MAX_INTRA16_MODE : 4;
-  int mode;
-  int best_alpha = -1;
-  int best_mode = 0;
-
-  VP8MakeLuma16Preds(it);
-  for (mode = 0; mode < max_mode; ++mode) {
-    const int alpha = VP8CollectHistogram(it->yuv_in_ + Y_OFF,
-                                          it->yuv_p_ + VP8I16ModeOffsets[mode],
-                                          0, 16);
-    if (alpha > best_alpha) {
-      best_alpha = alpha;
-      best_mode = mode;
-    }
-  }
-  VP8SetIntra16Mode(it, best_mode);
-  return best_alpha;
-}
-
-static int MBAnalyzeBestIntra4Mode(VP8EncIterator* const it,
-                                   int best_alpha) {
-  uint8_t modes[16];
-  const int max_mode = (it->enc_->method_ >= 3) ? MAX_INTRA4_MODE : NUM_BMODES;
-  int i4_alpha = 0;
-  VP8IteratorStartI4(it);
-  do {
-    int mode;
-    int best_mode_alpha = -1;
-    const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_];
-
-    VP8MakeIntra4Preds(it);
-    for (mode = 0; mode < max_mode; ++mode) {
-      const int alpha = VP8CollectHistogram(src,
-                                            it->yuv_p_ + VP8I4ModeOffsets[mode],
-                                            0, 1);
-      if (alpha > best_mode_alpha) {
-        best_mode_alpha = alpha;
-        modes[it->i4_] = mode;
-      }
-    }
-    i4_alpha += best_mode_alpha;
-    // Note: we reuse the original samples for predictors
-  } while (VP8IteratorRotateI4(it, it->yuv_in_ + Y_OFF));
-
-  if (i4_alpha > best_alpha) {
-    VP8SetIntra4Mode(it, modes);
-    best_alpha = ClipAlpha(i4_alpha);
-  }
-  return best_alpha;
-}
-
-static int MBAnalyzeBestUVMode(VP8EncIterator* const it) {
-  int best_alpha = -1;
-  int best_mode = 0;
-  const int max_mode = (it->enc_->method_ >= 3) ? MAX_UV_MODE : 4;
-  int mode;
-  VP8MakeChroma8Preds(it);
-  for (mode = 0; mode < max_mode; ++mode) {
-    const int alpha = VP8CollectHistogram(it->yuv_in_ + U_OFF,
-                                          it->yuv_p_ + VP8UVModeOffsets[mode],
-                                          16, 16 + 4 + 4);
-    if (alpha > best_alpha) {
-      best_alpha = alpha;
-      best_mode = mode;
-    }
-  }
-  VP8SetIntraUVMode(it, best_mode);
-  return best_alpha;
-}
-
-static void MBAnalyze(VP8EncIterator* const it,
-                      int alphas[256], int* const uv_alpha) {
-  const VP8Encoder* const enc = it->enc_;
-  int best_alpha, best_uv_alpha;
-
-  VP8SetIntra16Mode(it, 0);  // default: Intra16, DC_PRED
-  VP8SetSkip(it, 0);         // not skipped
-  VP8SetSegment(it, 0);      // default segment, spec-wise.
-
-  best_alpha = MBAnalyzeBestIntra16Mode(it);
-  if (enc->method_ != 3) {
-    // We go and make a fast decision for intra4/intra16.
-    // It's usually not a good and definitive pick, but helps seeding the stats
-    // about level bit-cost.
-    // TODO(skal): improve criterion.
-    best_alpha = MBAnalyzeBestIntra4Mode(it, best_alpha);
-  }
-  best_uv_alpha = MBAnalyzeBestUVMode(it);
-
-  // Final susceptibility mix
-  best_alpha = (best_alpha + best_uv_alpha + 1) / 2;
-  alphas[best_alpha]++;
-  *uv_alpha += best_uv_alpha;
-  it->mb_->alpha_ = best_alpha;   // Informative only.
-}
-
-//------------------------------------------------------------------------------
-// Main analysis loop:
-// Collect all susceptibilities for each macroblock and record their
-// distribution in alphas[]. Segments is assigned a-posteriori, based on
-// this histogram.
-// We also pick an intra16 prediction mode, which shouldn't be considered
-// final except for fast-encode settings. We can also pick some intra4 modes
-// and decide intra4/intra16, but that's usually almost always a bad choice at
-// this stage.
-
-int VP8EncAnalyze(VP8Encoder* const enc) {
-  int ok = 1;
-  int alphas[256] = { 0 };
-  VP8EncIterator it;
-
-  VP8IteratorInit(enc, &it);
-  enc->uv_alpha_ = 0;
-  do {
-    VP8IteratorImport(&it);
-    MBAnalyze(&it, alphas, &enc->uv_alpha_);
-    ok = VP8IteratorProgress(&it, 20);
-    // Let's pretend we have perfect lossless reconstruction.
-  } while (ok && VP8IteratorNext(&it, it.yuv_in_));
-  enc->uv_alpha_ /= enc->mb_w_ * enc->mb_h_;
-  if (ok) AssignSegments(enc, alphas);
-
-  return ok;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 874
drivers/webpold/enc/backward_references.c

@@ -1,874 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Author: Jyrki Alakuijala ([email protected])
-//
-
-#include <assert.h>
-#include <math.h>
-#include <stdio.h>
-
-#include "./backward_references.h"
-#include "./histogram.h"
-#include "../dsp/lossless.h"
-#include "../utils/color_cache.h"
-#include "../utils/utils.h"
-
-#define VALUES_IN_BYTE 256
-
-#define HASH_BITS 18
-#define HASH_SIZE (1 << HASH_BITS)
-#define HASH_MULTIPLIER (0xc6a4a7935bd1e995ULL)
-
-// 1M window (4M bytes) minus 120 special codes for short distances.
-#define WINDOW_SIZE ((1 << 20) - 120)
-
-// Bounds for the match length.
-#define MIN_LENGTH 2
-#define MAX_LENGTH 4096
-
-typedef struct {
-  // Stores the most recently added position with the given hash value.
-  int32_t hash_to_first_index_[HASH_SIZE];
-  // chain_[pos] stores the previous position with the same hash value
-  // for every pixel in the image.
-  int32_t* chain_;
-} HashChain;
-
-// -----------------------------------------------------------------------------
-
-static const uint8_t plane_to_code_lut[128] = {
- 96,   73,  55,  39,  23,  13,   5,  1,  255, 255, 255, 255, 255, 255, 255, 255,
- 101,  78,  58,  42,  26,  16,   8,  2,    0,   3,  9,   17,  27,  43,  59,  79,
- 102,  86,  62,  46,  32,  20,  10,  6,    4,   7,  11,  21,  33,  47,  63,  87,
- 105,  90,  70,  52,  37,  28,  18,  14,  12,  15,  19,  29,  38,  53,  71,  91,
- 110,  99,  82,  66,  48,  35,  30,  24,  22,  25,  31,  36,  49,  67,  83, 100,
- 115, 108,  94,  76,  64,  50,  44,  40,  34,  41,  45,  51,  65,  77,  95, 109,
- 118, 113, 103,  92,  80,  68,  60,  56,  54,  57,  61,  69,  81,  93, 104, 114,
- 119, 116, 111, 106,  97,  88,  84,  74,  72,  75,  85,  89,  98, 107, 112, 117
-};
-
-static int DistanceToPlaneCode(int xsize, int dist) {
-  const int yoffset = dist / xsize;
-  const int xoffset = dist - yoffset * xsize;
-  if (xoffset <= 8 && yoffset < 8) {
-    return plane_to_code_lut[yoffset * 16 + 8 - xoffset] + 1;
-  } else if (xoffset > xsize - 8 && yoffset < 7) {
-    return plane_to_code_lut[(yoffset + 1) * 16 + 8 + (xsize - xoffset)] + 1;
-  }
-  return dist + 120;
-}
-
-static WEBP_INLINE int FindMatchLength(const uint32_t* const array1,
-                                       const uint32_t* const array2,
-                                       const int max_limit) {
-  int match_len = 0;
-  while (match_len < max_limit && array1[match_len] == array2[match_len]) {
-    ++match_len;
-  }
-  return match_len;
-}
-
-// -----------------------------------------------------------------------------
-//  VP8LBackwardRefs
-
-void VP8LInitBackwardRefs(VP8LBackwardRefs* const refs) {
-  if (refs != NULL) {
-    refs->refs = NULL;
-    refs->size = 0;
-    refs->max_size = 0;
-  }
-}
-
-void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs) {
-  if (refs != NULL) {
-    free(refs->refs);
-    VP8LInitBackwardRefs(refs);
-  }
-}
-
-int VP8LBackwardRefsAlloc(VP8LBackwardRefs* const refs, int max_size) {
-  assert(refs != NULL);
-  refs->size = 0;
-  refs->max_size = 0;
-  refs->refs = (PixOrCopy*)WebPSafeMalloc((uint64_t)max_size,
-                                          sizeof(*refs->refs));
-  if (refs->refs == NULL) return 0;
-  refs->max_size = max_size;
-  return 1;
-}
-
-// -----------------------------------------------------------------------------
-// Hash chains
-
-static WEBP_INLINE uint64_t GetPixPairHash64(const uint32_t* const argb) {
-  uint64_t key = ((uint64_t)(argb[1]) << 32) | argb[0];
-  key = (key * HASH_MULTIPLIER) >> (64 - HASH_BITS);
-  return key;
-}
-
-static int HashChainInit(HashChain* const p, int size) {
-  int i;
-  p->chain_ = (int*)WebPSafeMalloc((uint64_t)size, sizeof(*p->chain_));
-  if (p->chain_ == NULL) {
-    return 0;
-  }
-  for (i = 0; i < size; ++i) {
-    p->chain_[i] = -1;
-  }
-  for (i = 0; i < HASH_SIZE; ++i) {
-    p->hash_to_first_index_[i] = -1;
-  }
-  return 1;
-}
-
-static void HashChainDelete(HashChain* const p) {
-  if (p != NULL) {
-    free(p->chain_);
-    free(p);
-  }
-}
-
-// Insertion of two pixels at a time.
-static void HashChainInsert(HashChain* const p,
-                            const uint32_t* const argb, int pos) {
-  const uint64_t hash_code = GetPixPairHash64(argb);
-  p->chain_[pos] = p->hash_to_first_index_[hash_code];
-  p->hash_to_first_index_[hash_code] = pos;
-}
-
-static int HashChainFindCopy(const HashChain* const p,
-                             int quality, int index, int xsize,
-                             const uint32_t* const argb, int maxlen,
-                             int* const distance_ptr,
-                             int* const length_ptr) {
-  const uint64_t hash_code = GetPixPairHash64(&argb[index]);
-  int prev_length = 0;
-  int64_t best_val = 0;
-  int best_length = 0;
-  int best_distance = 0;
-  const uint32_t* const argb_start = argb + index;
-  const int iter_min_mult = (quality < 50) ? 2 : (quality < 75) ? 4 : 8;
-  const int iter_min = -quality * iter_min_mult;
-  int iter_cnt = 10 + (quality >> 1);
-  const int min_pos = (index > WINDOW_SIZE) ? index - WINDOW_SIZE : 0;
-  int pos;
-
-  assert(xsize > 0);
-  for (pos = p->hash_to_first_index_[hash_code];
-       pos >= min_pos;
-       pos = p->chain_[pos]) {
-    int64_t val;
-    int curr_length;
-    if (iter_cnt < 0) {
-      if (iter_cnt < iter_min || best_val >= 0xff0000) {
-        break;
-      }
-    }
-    --iter_cnt;
-    if (best_length != 0 &&
-        argb[pos + best_length - 1] != argb_start[best_length - 1]) {
-      continue;
-    }
-    curr_length = FindMatchLength(argb + pos, argb_start, maxlen);
-    if (curr_length < prev_length) {
-      continue;
-    }
-    val = 65536 * curr_length;
-    // Favoring 2d locality here gives savings for certain images.
-    if (index - pos < 9 * xsize) {
-      const int y = (index - pos) / xsize;
-      int x = (index - pos) % xsize;
-      if (x > xsize / 2) {
-        x = xsize - x;
-      }
-      if (x <= 7 && x >= -8) {
-        val -= y * y + x * x;
-      } else {
-        val -= 9 * 9 + 9 * 9;
-      }
-    } else {
-      val -= 9 * 9 + 9 * 9;
-    }
-    if (best_val < val) {
-      prev_length = curr_length;
-      best_val = val;
-      best_length = curr_length;
-      best_distance = index - pos;
-      if (curr_length >= MAX_LENGTH) {
-        break;
-      }
-      if ((best_distance == 1 || best_distance == xsize) &&
-          best_length >= 128) {
-        break;
-      }
-    }
-  }
-  *distance_ptr = best_distance;
-  *length_ptr = best_length;
-  return (best_length >= MIN_LENGTH);
-}
-
-static WEBP_INLINE void PushBackCopy(VP8LBackwardRefs* const refs, int length) {
-  int size = refs->size;
-  while (length >= MAX_LENGTH) {
-    refs->refs[size++] = PixOrCopyCreateCopy(1, MAX_LENGTH);
-    length -= MAX_LENGTH;
-  }
-  if (length > 0) {
-    refs->refs[size++] = PixOrCopyCreateCopy(1, length);
-  }
-  refs->size = size;
-}
-
-static void BackwardReferencesRle(int xsize, int ysize,
-                                  const uint32_t* const argb,
-                                  VP8LBackwardRefs* const refs) {
-  const int pix_count = xsize * ysize;
-  int match_len = 0;
-  int i;
-  refs->size = 0;
-  PushBackCopy(refs, match_len);    // i=0 case
-  refs->refs[refs->size++] = PixOrCopyCreateLiteral(argb[0]);
-  for (i = 1; i < pix_count; ++i) {
-    if (argb[i] == argb[i - 1]) {
-      ++match_len;
-    } else {
-      PushBackCopy(refs, match_len);
-      match_len = 0;
-      refs->refs[refs->size++] = PixOrCopyCreateLiteral(argb[i]);
-    }
-  }
-  PushBackCopy(refs, match_len);
-}
-
-static int BackwardReferencesHashChain(int xsize, int ysize,
-                                       const uint32_t* const argb,
-                                       int cache_bits, int quality,
-                                       VP8LBackwardRefs* const refs) {
-  int i;
-  int ok = 0;
-  int cc_init = 0;
-  const int use_color_cache = (cache_bits > 0);
-  const int pix_count = xsize * ysize;
-  HashChain* const hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
-  VP8LColorCache hashers;
-
-  if (hash_chain == NULL) return 0;
-  if (use_color_cache) {
-    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
-    if (!cc_init) goto Error;
-  }
-
-  if (!HashChainInit(hash_chain, pix_count)) goto Error;
-
-  refs->size = 0;
-  for (i = 0; i < pix_count; ) {
-    // Alternative#1: Code the pixels starting at 'i' using backward reference.
-    int offset = 0;
-    int len = 0;
-    if (i < pix_count - 1) {  // FindCopy(i,..) reads pixels at [i] and [i + 1].
-      int maxlen = pix_count - i;
-      if (maxlen > MAX_LENGTH) {
-        maxlen = MAX_LENGTH;
-      }
-      HashChainFindCopy(hash_chain, quality, i, xsize, argb, maxlen,
-                        &offset, &len);
-    }
-    if (len >= MIN_LENGTH) {
-      // Alternative#2: Insert the pixel at 'i' as literal, and code the
-      // pixels starting at 'i + 1' using backward reference.
-      int offset2 = 0;
-      int len2 = 0;
-      int k;
-      HashChainInsert(hash_chain, &argb[i], i);
-      if (i < pix_count - 2) {  // FindCopy(i+1,..) reads [i + 1] and [i + 2].
-        int maxlen = pix_count - (i + 1);
-        if (maxlen > MAX_LENGTH) {
-          maxlen = MAX_LENGTH;
-        }
-        HashChainFindCopy(hash_chain, quality,
-                          i + 1, xsize, argb, maxlen, &offset2, &len2);
-        if (len2 > len + 1) {
-          const uint32_t pixel = argb[i];
-          // Alternative#2 is a better match. So push pixel at 'i' as literal.
-          if (use_color_cache && VP8LColorCacheContains(&hashers, pixel)) {
-            const int ix = VP8LColorCacheGetIndex(&hashers, pixel);
-            refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
-          } else {
-            refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel);
-          }
-          ++refs->size;
-          if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
-          i++;  // Backward reference to be done for next pixel.
-          len = len2;
-          offset = offset2;
-        }
-      }
-      if (len >= MAX_LENGTH) {
-        len = MAX_LENGTH - 1;
-      }
-      refs->refs[refs->size++] = PixOrCopyCreateCopy(offset, len);
-      if (use_color_cache) {
-        for (k = 0; k < len; ++k) {
-          VP8LColorCacheInsert(&hashers, argb[i + k]);
-        }
-      }
-      // Add to the hash_chain (but cannot add the last pixel).
-      {
-        const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i;
-        for (k = 1; k < last; ++k) {
-          HashChainInsert(hash_chain, &argb[i + k], i + k);
-        }
-      }
-      i += len;
-    } else {
-      const uint32_t pixel = argb[i];
-      if (use_color_cache && VP8LColorCacheContains(&hashers, pixel)) {
-        // push pixel as a PixOrCopyCreateCacheIdx pixel
-        const int ix = VP8LColorCacheGetIndex(&hashers, pixel);
-        refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
-      } else {
-        refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel);
-      }
-      ++refs->size;
-      if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
-      if (i + 1 < pix_count) {
-        HashChainInsert(hash_chain, &argb[i], i);
-      }
-      ++i;
-    }
-  }
-  ok = 1;
-Error:
-  if (cc_init) VP8LColorCacheClear(&hashers);
-  HashChainDelete(hash_chain);
-  return ok;
-}
-
-// -----------------------------------------------------------------------------
-
-typedef struct {
-  double alpha_[VALUES_IN_BYTE];
-  double red_[VALUES_IN_BYTE];
-  double literal_[PIX_OR_COPY_CODES_MAX];
-  double blue_[VALUES_IN_BYTE];
-  double distance_[NUM_DISTANCE_CODES];
-} CostModel;
-
-static int BackwardReferencesTraceBackwards(
-    int xsize, int ysize, int recursive_cost_model,
-    const uint32_t* const argb, int cache_bits, VP8LBackwardRefs* const refs);
-
-static void ConvertPopulationCountTableToBitEstimates(
-    int num_symbols, const int population_counts[], double output[]) {
-  int sum = 0;
-  int nonzeros = 0;
-  int i;
-  for (i = 0; i < num_symbols; ++i) {
-    sum += population_counts[i];
-    if (population_counts[i] > 0) {
-      ++nonzeros;
-    }
-  }
-  if (nonzeros <= 1) {
-    memset(output, 0, num_symbols * sizeof(*output));
-  } else {
-    const double logsum = VP8LFastLog2(sum);
-    for (i = 0; i < num_symbols; ++i) {
-      output[i] = logsum - VP8LFastLog2(population_counts[i]);
-    }
-  }
-}
-
-static int CostModelBuild(CostModel* const m, int xsize, int ysize,
-                          int recursion_level, const uint32_t* const argb,
-                          int cache_bits) {
-  int ok = 0;
-  VP8LHistogram histo;
-  VP8LBackwardRefs refs;
-  const int quality = 100;
-
-  if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize)) goto Error;
-
-  if (recursion_level > 0) {
-    if (!BackwardReferencesTraceBackwards(xsize, ysize, recursion_level - 1,
-                                          argb, cache_bits, &refs)) {
-      goto Error;
-    }
-  } else {
-    if (!BackwardReferencesHashChain(xsize, ysize, argb, cache_bits, quality,
-                                     &refs)) {
-      goto Error;
-    }
-  }
-  VP8LHistogramCreate(&histo, &refs, cache_bits);
-  ConvertPopulationCountTableToBitEstimates(
-      VP8LHistogramNumCodes(&histo), histo.literal_, m->literal_);
-  ConvertPopulationCountTableToBitEstimates(
-      VALUES_IN_BYTE, histo.red_, m->red_);
-  ConvertPopulationCountTableToBitEstimates(
-      VALUES_IN_BYTE, histo.blue_, m->blue_);
-  ConvertPopulationCountTableToBitEstimates(
-      VALUES_IN_BYTE, histo.alpha_, m->alpha_);
-  ConvertPopulationCountTableToBitEstimates(
-      NUM_DISTANCE_CODES, histo.distance_, m->distance_);
-  ok = 1;
-
- Error:
-  VP8LClearBackwardRefs(&refs);
-  return ok;
-}
-
-static WEBP_INLINE double GetLiteralCost(const CostModel* const m, uint32_t v) {
-  return m->alpha_[v >> 24] +
-         m->red_[(v >> 16) & 0xff] +
-         m->literal_[(v >> 8) & 0xff] +
-         m->blue_[v & 0xff];
-}
-
-static WEBP_INLINE double GetCacheCost(const CostModel* const m, uint32_t idx) {
-  const int literal_idx = VALUES_IN_BYTE + NUM_LENGTH_CODES + idx;
-  return m->literal_[literal_idx];
-}
-
-static WEBP_INLINE double GetLengthCost(const CostModel* const m,
-                                        uint32_t length) {
-  int code, extra_bits_count, extra_bits_value;
-  PrefixEncode(length, &code, &extra_bits_count, &extra_bits_value);
-  return m->literal_[VALUES_IN_BYTE + code] + extra_bits_count;
-}
-
-static WEBP_INLINE double GetDistanceCost(const CostModel* const m,
-                                          uint32_t distance) {
-  int code, extra_bits_count, extra_bits_value;
-  PrefixEncode(distance, &code, &extra_bits_count, &extra_bits_value);
-  return m->distance_[code] + extra_bits_count;
-}
-
-static int BackwardReferencesHashChainDistanceOnly(
-    int xsize, int ysize, int recursive_cost_model, const uint32_t* const argb,
-    int cache_bits, uint32_t* const dist_array) {
-  int i;
-  int ok = 0;
-  int cc_init = 0;
-  const int quality = 100;
-  const int pix_count = xsize * ysize;
-  const int use_color_cache = (cache_bits > 0);
-  double* const cost =
-      (double*)WebPSafeMalloc((uint64_t)pix_count, sizeof(*cost));
-  CostModel* cost_model = (CostModel*)malloc(sizeof(*cost_model));
-  HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
-  VP8LColorCache hashers;
-  const double mul0 = (recursive_cost_model != 0) ? 1.0 : 0.68;
-  const double mul1 = (recursive_cost_model != 0) ? 1.0 : 0.82;
-
-  if (cost == NULL || cost_model == NULL || hash_chain == NULL) goto Error;
-
-  if (!HashChainInit(hash_chain, pix_count)) goto Error;
-
-  if (use_color_cache) {
-    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
-    if (!cc_init) goto Error;
-  }
-
-  if (!CostModelBuild(cost_model, xsize, ysize, recursive_cost_model, argb,
-                      cache_bits)) {
-    goto Error;
-  }
-
-  for (i = 0; i < pix_count; ++i) cost[i] = 1e100;
-
-  // We loop one pixel at a time, but store all currently best points to
-  // non-processed locations from this point.
-  dist_array[0] = 0;
-  for (i = 0; i < pix_count; ++i) {
-    double prev_cost = 0.0;
-    int shortmax;
-    if (i > 0) {
-      prev_cost = cost[i - 1];
-    }
-    for (shortmax = 0; shortmax < 2; ++shortmax) {
-      int offset = 0;
-      int len = 0;
-      if (i < pix_count - 1) {  // FindCopy reads pixels at [i] and [i + 1].
-        int maxlen = shortmax ? 2 : MAX_LENGTH;
-        if (maxlen > pix_count - i) {
-          maxlen = pix_count - i;
-        }
-        HashChainFindCopy(hash_chain, quality, i, xsize, argb, maxlen,
-                          &offset, &len);
-      }
-      if (len >= MIN_LENGTH) {
-        const int code = DistanceToPlaneCode(xsize, offset);
-        const double distance_cost =
-            prev_cost + GetDistanceCost(cost_model, code);
-        int k;
-        for (k = 1; k < len; ++k) {
-          const double cost_val =
-              distance_cost + GetLengthCost(cost_model, k);
-          if (cost[i + k] > cost_val) {
-            cost[i + k] = cost_val;
-            dist_array[i + k] = k + 1;
-          }
-        }
-        // This if is for speedup only. It roughly doubles the speed, and
-        // makes compression worse by .1 %.
-        if (len >= 128 && code < 2) {
-          // Long copy for short distances, let's skip the middle
-          // lookups for better copies.
-          // 1) insert the hashes.
-          if (use_color_cache) {
-            for (k = 0; k < len; ++k) {
-              VP8LColorCacheInsert(&hashers, argb[i + k]);
-            }
-          }
-          // 2) Add to the hash_chain (but cannot add the last pixel)
-          {
-            const int last = (len < pix_count - 1 - i) ? len
-                                                       : pix_count - 1 - i;
-            for (k = 0; k < last; ++k) {
-              HashChainInsert(hash_chain, &argb[i + k], i + k);
-            }
-          }
-          // 3) jump.
-          i += len - 1;  // for loop does ++i, thus -1 here.
-          goto next_symbol;
-        }
-      }
-    }
-    if (i < pix_count - 1) {
-      HashChainInsert(hash_chain, &argb[i], i);
-    }
-    {
-      // inserting a literal pixel
-      double cost_val = prev_cost;
-      if (use_color_cache && VP8LColorCacheContains(&hashers, argb[i])) {
-        const int ix = VP8LColorCacheGetIndex(&hashers, argb[i]);
-        cost_val += GetCacheCost(cost_model, ix) * mul0;
-      } else {
-        cost_val += GetLiteralCost(cost_model, argb[i]) * mul1;
-      }
-      if (cost[i] > cost_val) {
-        cost[i] = cost_val;
-        dist_array[i] = 1;  // only one is inserted.
-      }
-      if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
-    }
- next_symbol: ;
-  }
-  // Last pixel still to do, it can only be a single step if not reached
-  // through cheaper means already.
-  ok = 1;
-Error:
-  if (cc_init) VP8LColorCacheClear(&hashers);
-  HashChainDelete(hash_chain);
-  free(cost_model);
-  free(cost);
-  return ok;
-}
-
-static int TraceBackwards(const uint32_t* const dist_array,
-                          int dist_array_size,
-                          uint32_t** const chosen_path,
-                          int* const chosen_path_size) {
-  int i;
-  // Count how many.
-  int count = 0;
-  for (i = dist_array_size - 1; i >= 0; ) {
-    int k = dist_array[i];
-    assert(k >= 1);
-    ++count;
-    i -= k;
-  }
-  // Allocate.
-  *chosen_path_size = count;
-  *chosen_path =
-      (uint32_t*)WebPSafeMalloc((uint64_t)count, sizeof(**chosen_path));
-  if (*chosen_path == NULL) return 0;
-
-  // Write in reverse order.
-  for (i = dist_array_size - 1; i >= 0; ) {
-    int k = dist_array[i];
-    assert(k >= 1);
-    (*chosen_path)[--count] = k;
-    i -= k;
-  }
-  return 1;
-}
-
-static int BackwardReferencesHashChainFollowChosenPath(
-    int xsize, int ysize, const uint32_t* const argb, int cache_bits,
-    const uint32_t* const chosen_path, int chosen_path_size,
-    VP8LBackwardRefs* const refs) {
-  const int quality = 100;
-  const int pix_count = xsize * ysize;
-  const int use_color_cache = (cache_bits > 0);
-  int size = 0;
-  int i = 0;
-  int k;
-  int ix;
-  int ok = 0;
-  int cc_init = 0;
-  HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
-  VP8LColorCache hashers;
-
-  if (hash_chain == NULL || !HashChainInit(hash_chain, pix_count)) {
-    goto Error;
-  }
-  if (use_color_cache) {
-    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
-    if (!cc_init) goto Error;
-  }
-
-  refs->size = 0;
-  for (ix = 0; ix < chosen_path_size; ++ix, ++size) {
-    int offset = 0;
-    int len = 0;
-    int maxlen = chosen_path[ix];
-    if (maxlen != 1) {
-      HashChainFindCopy(hash_chain, quality,
-                        i, xsize, argb, maxlen, &offset, &len);
-      assert(len == maxlen);
-      refs->refs[size] = PixOrCopyCreateCopy(offset, len);
-      if (use_color_cache) {
-        for (k = 0; k < len; ++k) {
-          VP8LColorCacheInsert(&hashers, argb[i + k]);
-        }
-      }
-      {
-        const int last = (len < pix_count - 1 - i) ? len : pix_count - 1 - i;
-        for (k = 0; k < last; ++k) {
-          HashChainInsert(hash_chain, &argb[i + k], i + k);
-        }
-      }
-      i += len;
-    } else {
-      if (use_color_cache && VP8LColorCacheContains(&hashers, argb[i])) {
-        // push pixel as a color cache index
-        const int idx = VP8LColorCacheGetIndex(&hashers, argb[i]);
-        refs->refs[size] = PixOrCopyCreateCacheIdx(idx);
-      } else {
-        refs->refs[size] = PixOrCopyCreateLiteral(argb[i]);
-      }
-      if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
-      if (i + 1 < pix_count) {
-        HashChainInsert(hash_chain, &argb[i], i);
-      }
-      ++i;
-    }
-  }
-  assert(size <= refs->max_size);
-  refs->size = size;
-  ok = 1;
-Error:
-  if (cc_init) VP8LColorCacheClear(&hashers);
-  HashChainDelete(hash_chain);
-  return ok;
-}
-
-// Returns 1 on success.
-static int BackwardReferencesTraceBackwards(int xsize, int ysize,
-                                            int recursive_cost_model,
-                                            const uint32_t* const argb,
-                                            int cache_bits,
-                                            VP8LBackwardRefs* const refs) {
-  int ok = 0;
-  const int dist_array_size = xsize * ysize;
-  uint32_t* chosen_path = NULL;
-  int chosen_path_size = 0;
-  uint32_t* dist_array =
-      (uint32_t*)WebPSafeMalloc((uint64_t)dist_array_size, sizeof(*dist_array));
-
-  if (dist_array == NULL) goto Error;
-
-  if (!BackwardReferencesHashChainDistanceOnly(
-      xsize, ysize, recursive_cost_model, argb, cache_bits, dist_array)) {
-    goto Error;
-  }
-  if (!TraceBackwards(dist_array, dist_array_size,
-                      &chosen_path, &chosen_path_size)) {
-    goto Error;
-  }
-  free(dist_array);   // no need to retain this memory any longer
-  dist_array = NULL;
-  if (!BackwardReferencesHashChainFollowChosenPath(
-      xsize, ysize, argb, cache_bits, chosen_path, chosen_path_size, refs)) {
-    goto Error;
-  }
-  ok = 1;
- Error:
-  free(chosen_path);
-  free(dist_array);
-  return ok;
-}
-
-static void BackwardReferences2DLocality(int xsize,
-                                         VP8LBackwardRefs* const refs) {
-  int i;
-  for (i = 0; i < refs->size; ++i) {
-    if (PixOrCopyIsCopy(&refs->refs[i])) {
-      const int dist = refs->refs[i].argb_or_distance;
-      const int transformed_dist = DistanceToPlaneCode(xsize, dist);
-      refs->refs[i].argb_or_distance = transformed_dist;
-    }
-  }
-}
-
-int VP8LGetBackwardReferences(int width, int height,
-                              const uint32_t* const argb,
-                              int quality, int cache_bits, int use_2d_locality,
-                              VP8LBackwardRefs* const best) {
-  int ok = 0;
-  int lz77_is_useful;
-  VP8LBackwardRefs refs_rle, refs_lz77;
-  const int num_pix = width * height;
-
-  VP8LBackwardRefsAlloc(&refs_rle, num_pix);
-  VP8LBackwardRefsAlloc(&refs_lz77, num_pix);
-  VP8LInitBackwardRefs(best);
-  if (refs_rle.refs == NULL || refs_lz77.refs == NULL) {
- Error1:
-    VP8LClearBackwardRefs(&refs_rle);
-    VP8LClearBackwardRefs(&refs_lz77);
-    goto End;
-  }
-
-  if (!BackwardReferencesHashChain(width, height, argb, cache_bits, quality,
-                                   &refs_lz77)) {
-    goto End;
-  }
-  // Backward Reference using RLE only.
-  BackwardReferencesRle(width, height, argb, &refs_rle);
-
-  {
-    double bit_cost_lz77, bit_cost_rle;
-    VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo));
-    if (histo == NULL) goto Error1;
-    // Evaluate lz77 coding
-    VP8LHistogramCreate(histo, &refs_lz77, cache_bits);
-    bit_cost_lz77 = VP8LHistogramEstimateBits(histo);
-    // Evaluate RLE coding
-    VP8LHistogramCreate(histo, &refs_rle, cache_bits);
-    bit_cost_rle = VP8LHistogramEstimateBits(histo);
-    // Decide if LZ77 is useful.
-    lz77_is_useful = (bit_cost_lz77 < bit_cost_rle);
-    free(histo);
-  }
-
-  // Choose appropriate backward reference.
-  if (lz77_is_useful) {
-    // TraceBackwards is costly. Run it for higher qualities.
-    const int try_lz77_trace_backwards = (quality >= 75);
-    *best = refs_lz77;   // default guess: lz77 is better
-    VP8LClearBackwardRefs(&refs_rle);
-    if (try_lz77_trace_backwards) {
-      const int recursion_level = (num_pix < 320 * 200) ? 1 : 0;
-      VP8LBackwardRefs refs_trace;
-      if (!VP8LBackwardRefsAlloc(&refs_trace, num_pix)) {
-        goto End;
-      }
-      if (BackwardReferencesTraceBackwards(
-          width, height, recursion_level, argb, cache_bits, &refs_trace)) {
-        VP8LClearBackwardRefs(&refs_lz77);
-        *best = refs_trace;
-      }
-    }
-  } else {
-    VP8LClearBackwardRefs(&refs_lz77);
-    *best = refs_rle;
-  }
-
-  if (use_2d_locality) BackwardReferences2DLocality(width, best);
-
-  ok = 1;
-
- End:
-  if (!ok) {
-    VP8LClearBackwardRefs(best);
-  }
-  return ok;
-}
-
-// Returns 1 on success.
-static int ComputeCacheHistogram(const uint32_t* const argb,
-                                 int xsize, int ysize,
-                                 const VP8LBackwardRefs* const refs,
-                                 int cache_bits,
-                                 VP8LHistogram* const histo) {
-  int pixel_index = 0;
-  int i;
-  uint32_t k;
-  VP8LColorCache hashers;
-  const int use_color_cache = (cache_bits > 0);
-  int cc_init = 0;
-
-  if (use_color_cache) {
-    cc_init = VP8LColorCacheInit(&hashers, cache_bits);
-    if (!cc_init) return 0;
-  }
-
-  for (i = 0; i < refs->size; ++i) {
-    const PixOrCopy* const v = &refs->refs[i];
-    if (PixOrCopyIsLiteral(v)) {
-      if (use_color_cache &&
-          VP8LColorCacheContains(&hashers, argb[pixel_index])) {
-        // push pixel as a cache index
-        const int ix = VP8LColorCacheGetIndex(&hashers, argb[pixel_index]);
-        const PixOrCopy token = PixOrCopyCreateCacheIdx(ix);
-        VP8LHistogramAddSinglePixOrCopy(histo, &token);
-      } else {
-        VP8LHistogramAddSinglePixOrCopy(histo, v);
-      }
-    } else {
-      VP8LHistogramAddSinglePixOrCopy(histo, v);
-    }
-    if (use_color_cache) {
-      for (k = 0; k < PixOrCopyLength(v); ++k) {
-        VP8LColorCacheInsert(&hashers, argb[pixel_index + k]);
-      }
-    }
-    pixel_index += PixOrCopyLength(v);
-  }
-  assert(pixel_index == xsize * ysize);
-  (void)xsize;  // xsize is not used in non-debug compilations otherwise.
-  (void)ysize;  // ysize is not used in non-debug compilations otherwise.
-  if (cc_init) VP8LColorCacheClear(&hashers);
-  return 1;
-}
-
-// Returns how many bits are to be used for a color cache.
-int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb,
-                                      int xsize, int ysize,
-                                      int* const best_cache_bits) {
-  int ok = 0;
-  int cache_bits;
-  double lowest_entropy = 1e99;
-  VP8LBackwardRefs refs;
-  static const double kSmallPenaltyForLargeCache = 4.0;
-  static const int quality = 30;
-  if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize) ||
-      !BackwardReferencesHashChain(xsize, ysize, argb, 0, quality, &refs)) {
-    goto Error;
-  }
-  for (cache_bits = 0; cache_bits <= MAX_COLOR_CACHE_BITS; ++cache_bits) {
-    double cur_entropy;
-    VP8LHistogram histo;
-    VP8LHistogramInit(&histo, cache_bits);
-    ComputeCacheHistogram(argb, xsize, ysize, &refs, cache_bits, &histo);
-    cur_entropy = VP8LHistogramEstimateBits(&histo) +
-        kSmallPenaltyForLargeCache * cache_bits;
-    if (cache_bits == 0 || cur_entropy < lowest_entropy) {
-      *best_cache_bits = cache_bits;
-      lowest_entropy = cur_entropy;
-    }
-  }
-  ok = 1;
- Error:
-  VP8LClearBackwardRefs(&refs);
-  return ok;
-}

+ 0 - 212
drivers/webpold/enc/backward_references.h

@@ -1,212 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Author: Jyrki Alakuijala ([email protected])
-//
-
-#ifndef WEBP_ENC_BACKWARD_REFERENCES_H_
-#define WEBP_ENC_BACKWARD_REFERENCES_H_
-
-#include <assert.h>
-#include <stdlib.h>
-#include "../types.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// The spec allows 11, we use 9 bits to reduce memory consumption in encoding.
-// Having 9 instead of 11 only removes about 0.25 % of compression density.
-#define MAX_COLOR_CACHE_BITS 9
-
-// Max ever number of codes we'll use:
-#define PIX_OR_COPY_CODES_MAX \
-    (NUM_LITERAL_CODES + NUM_LENGTH_CODES + (1 << MAX_COLOR_CACHE_BITS))
-
-// -----------------------------------------------------------------------------
-// PrefixEncode()
-
-// use GNU builtins where available.
-#if defined(__GNUC__) && \
-    ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
-static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
-  return n == 0 ? -1 : 31 ^ __builtin_clz(n);
-}
-#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
-#include <intrin.h>
-#pragma intrinsic(_BitScanReverse)
-
-static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
-  unsigned long first_set_bit;
-  return _BitScanReverse(&first_set_bit, n) ? first_set_bit : -1;
-}
-#else
-static WEBP_INLINE int BitsLog2Floor(uint32_t n) {
-  int log = 0;
-  uint32_t value = n;
-  int i;
-
-  if (value == 0) return -1;
-  for (i = 4; i >= 0; --i) {
-    const int shift = (1 << i);
-    const uint32_t x = value >> shift;
-    if (x != 0) {
-      value = x;
-      log += shift;
-    }
-  }
-  return log;
-}
-#endif
-
-static WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) {
-  const int floor = BitsLog2Floor(n);
-  if (n == (n & ~(n - 1)))  // zero or a power of two.
-    return floor;
-  else
-    return floor + 1;
-}
-
-// Splitting of distance and length codes into prefixes and
-// extra bits. The prefixes are encoded with an entropy code
-// while the extra bits are stored just as normal bits.
-static WEBP_INLINE void PrefixEncode(int distance, int* const code,
-                                     int* const extra_bits_count,
-                                     int* const extra_bits_value) {
-  // Collect the two most significant bits where the highest bit is 1.
-  const int highest_bit = BitsLog2Floor(--distance);
-  // & 0x3f is to make behavior well defined when highest_bit
-  // does not exist or is the least significant bit.
-  const int second_highest_bit =
-      (distance >> ((highest_bit - 1) & 0x3f)) & 1;
-  *extra_bits_count = (highest_bit > 0) ? (highest_bit - 1) : 0;
-  *extra_bits_value = distance & ((1 << *extra_bits_count) - 1);
-  *code = (highest_bit > 0) ? (2 * highest_bit + second_highest_bit)
-                            : (highest_bit == 0) ? 1 : 0;
-}
-
-// -----------------------------------------------------------------------------
-// PixOrCopy
-
-enum Mode {
-  kLiteral,
-  kCacheIdx,
-  kCopy,
-  kNone
-};
-
-typedef struct {
-  // mode as uint8_t to make the memory layout to be exactly 8 bytes.
-  uint8_t mode;
-  uint16_t len;
-  uint32_t argb_or_distance;
-} PixOrCopy;
-
-static WEBP_INLINE PixOrCopy PixOrCopyCreateCopy(uint32_t distance,
-                                                 uint16_t len) {
-  PixOrCopy retval;
-  retval.mode = kCopy;
-  retval.argb_or_distance = distance;
-  retval.len = len;
-  return retval;
-}
-
-static WEBP_INLINE PixOrCopy PixOrCopyCreateCacheIdx(int idx) {
-  PixOrCopy retval;
-  assert(idx >= 0);
-  assert(idx < (1 << MAX_COLOR_CACHE_BITS));
-  retval.mode = kCacheIdx;
-  retval.argb_or_distance = idx;
-  retval.len = 1;
-  return retval;
-}
-
-static WEBP_INLINE PixOrCopy PixOrCopyCreateLiteral(uint32_t argb) {
-  PixOrCopy retval;
-  retval.mode = kLiteral;
-  retval.argb_or_distance = argb;
-  retval.len = 1;
-  return retval;
-}
-
-static WEBP_INLINE int PixOrCopyIsLiteral(const PixOrCopy* const p) {
-  return (p->mode == kLiteral);
-}
-
-static WEBP_INLINE int PixOrCopyIsCacheIdx(const PixOrCopy* const p) {
-  return (p->mode == kCacheIdx);
-}
-
-static WEBP_INLINE int PixOrCopyIsCopy(const PixOrCopy* const p) {
-  return (p->mode == kCopy);
-}
-
-static WEBP_INLINE uint32_t PixOrCopyLiteral(const PixOrCopy* const p,
-                                             int component) {
-  assert(p->mode == kLiteral);
-  return (p->argb_or_distance >> (component * 8)) & 0xff;
-}
-
-static WEBP_INLINE uint32_t PixOrCopyLength(const PixOrCopy* const p) {
-  return p->len;
-}
-
-static WEBP_INLINE uint32_t PixOrCopyArgb(const PixOrCopy* const p) {
-  assert(p->mode == kLiteral);
-  return p->argb_or_distance;
-}
-
-static WEBP_INLINE uint32_t PixOrCopyCacheIdx(const PixOrCopy* const p) {
-  assert(p->mode == kCacheIdx);
-  assert(p->argb_or_distance < (1U << MAX_COLOR_CACHE_BITS));
-  return p->argb_or_distance;
-}
-
-static WEBP_INLINE uint32_t PixOrCopyDistance(const PixOrCopy* const p) {
-  assert(p->mode == kCopy);
-  return p->argb_or_distance;
-}
-
-// -----------------------------------------------------------------------------
-// VP8LBackwardRefs
-
-typedef struct {
-  PixOrCopy* refs;
-  int size;      // currently used
-  int max_size;  // maximum capacity
-} VP8LBackwardRefs;
-
-// Initialize the object. Must be called first. 'refs' can be NULL.
-void VP8LInitBackwardRefs(VP8LBackwardRefs* const refs);
-
-// Release memory and re-initialize the object. 'refs' can be NULL.
-void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs);
-
-// Allocate 'max_size' references. Returns false in case of memory error.
-int VP8LBackwardRefsAlloc(VP8LBackwardRefs* const refs, int max_size);
-
-// -----------------------------------------------------------------------------
-// Main entry points
-
-// Evaluates best possible backward references for specified quality.
-// Further optimize for 2D locality if use_2d_locality flag is set.
-int VP8LGetBackwardReferences(int width, int height,
-                              const uint32_t* const argb,
-                              int quality, int cache_bits, int use_2d_locality,
-                              VP8LBackwardRefs* const best);
-
-// Produce an estimate for a good color cache size for the image.
-int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb,
-                                      int xsize, int ysize,
-                                      int* const best_cache_bits);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif  // WEBP_ENC_BACKWARD_REFERENCES_H_

+ 0 - 132
drivers/webpold/enc/config.c

@@ -1,132 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Coding tools configuration
-//
-// Author: Skal ([email protected])
-
-#include "../encode.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// WebPConfig
-//------------------------------------------------------------------------------
-
-int WebPConfigInitInternal(WebPConfig* config,
-                           WebPPreset preset, float quality, int version) {
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) {
-    return 0;   // caller/system version mismatch!
-  }
-  if (config == NULL) return 0;
-
-  config->quality = quality;
-  config->target_size = 0;
-  config->target_PSNR = 0.;
-  config->method = 4;
-  config->sns_strength = 50;
-  config->filter_strength = 20;   // default: light filtering
-  config->filter_sharpness = 0;
-  config->filter_type = 0;        // default: simple
-  config->partitions = 0;
-  config->segments = 4;
-  config->pass = 1;
-  config->show_compressed = 0;
-  config->preprocessing = 0;
-  config->autofilter = 0;
-  config->partition_limit = 0;
-  config->alpha_compression = 1;
-  config->alpha_filtering = 1;
-  config->alpha_quality = 100;
-  config->lossless = 0;
-  config->image_hint = WEBP_HINT_DEFAULT;
-
-  // TODO(skal): tune.
-  switch (preset) {
-    case WEBP_PRESET_PICTURE:
-      config->sns_strength = 80;
-      config->filter_sharpness = 4;
-      config->filter_strength = 35;
-      break;
-    case WEBP_PRESET_PHOTO:
-      config->sns_strength = 80;
-      config->filter_sharpness = 3;
-      config->filter_strength = 30;
-      break;
-    case WEBP_PRESET_DRAWING:
-      config->sns_strength = 25;
-      config->filter_sharpness = 6;
-      config->filter_strength = 10;
-      break;
-    case WEBP_PRESET_ICON:
-      config->sns_strength = 0;
-      config->filter_strength = 0;   // disable filtering to retain sharpness
-      break;
-    case WEBP_PRESET_TEXT:
-      config->sns_strength = 0;
-      config->filter_strength = 0;   // disable filtering to retain sharpness
-      config->segments = 2;
-      break;
-    case WEBP_PRESET_DEFAULT:
-    default:
-      break;
-  }
-  return WebPValidateConfig(config);
-}
-
-int WebPValidateConfig(const WebPConfig* config) {
-  if (config == NULL) return 0;
-  if (config->quality < 0 || config->quality > 100)
-    return 0;
-  if (config->target_size < 0)
-    return 0;
-  if (config->target_PSNR < 0)
-    return 0;
-  if (config->method < 0 || config->method > 6)
-    return 0;
-  if (config->segments < 1 || config->segments > 4)
-    return 0;
-  if (config->sns_strength < 0 || config->sns_strength > 100)
-    return 0;
-  if (config->filter_strength < 0 || config->filter_strength > 100)
-    return 0;
-  if (config->filter_sharpness < 0 || config->filter_sharpness > 7)
-    return 0;
-  if (config->filter_type < 0 || config->filter_type > 1)
-    return 0;
-  if (config->autofilter < 0 || config->autofilter > 1)
-    return 0;
-  if (config->pass < 1 || config->pass > 10)
-    return 0;
-  if (config->show_compressed < 0 || config->show_compressed > 1)
-    return 0;
-  if (config->preprocessing < 0 || config->preprocessing > 1)
-    return 0;
-  if (config->partitions < 0 || config->partitions > 3)
-    return 0;
-  if (config->partition_limit < 0 || config->partition_limit > 100)
-    return 0;
-  if (config->alpha_compression < 0)
-    return 0;
-  if (config->alpha_filtering < 0)
-    return 0;
-  if (config->alpha_quality < 0 || config->alpha_quality > 100)
-    return 0;
-  if (config->lossless < 0 || config->lossless > 1)
-    return 0;
-  if (config->image_hint >= WEBP_HINT_LAST)
-    return 0;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 494
drivers/webpold/enc/cost.c

@@ -1,494 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Cost tables for level and modes
-//
-// Author: Skal ([email protected])
-
-#include "./cost.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Boolean-cost cost table
-
-const uint16_t VP8EntropyCost[256] = {
-  1792, 1792, 1792, 1536, 1536, 1408, 1366, 1280, 1280, 1216,
-  1178, 1152, 1110, 1076, 1061, 1024, 1024,  992,  968,  951,
-   939,  911,  896,  878,  871,  854,  838,  820,  811,  794,
-   786,  768,  768,  752,  740,  732,  720,  709,  704,  690,
-   683,  672,  666,  655,  647,  640,  631,  622,  615,  607,
-   598,  592,  586,  576,  572,  564,  559,  555,  547,  541,
-   534,  528,  522,  512,  512,  504,  500,  494,  488,  483,
-   477,  473,  467,  461,  458,  452,  448,  443,  438,  434,
-   427,  424,  419,  415,  410,  406,  403,  399,  394,  390,
-   384,  384,  377,  374,  370,  366,  362,  359,  355,  351,
-   347,  342,  342,  336,  333,  330,  326,  323,  320,  316,
-   312,  308,  305,  302,  299,  296,  293,  288,  287,  283,
-   280,  277,  274,  272,  268,  266,  262,  256,  256,  256,
-   251,  248,  245,  242,  240,  237,  234,  232,  228,  226,
-   223,  221,  218,  216,  214,  211,  208,  205,  203,  201,
-   198,  196,  192,  191,  188,  187,  183,  181,  179,  176,
-   175,  171,  171,  168,  165,  163,  160,  159,  156,  154,
-   152,  150,  148,  146,  144,  142,  139,  138,  135,  133,
-   131,  128,  128,  125,  123,  121,  119,  117,  115,  113,
-   111,  110,  107,  105,  103,  102,  100,   98,   96,   94,
-    92,   91,   89,   86,   86,   83,   82,   80,   77,   76,
-    74,   73,   71,   69,   67,   66,   64,   63,   61,   59,
-    57,   55,   54,   52,   51,   49,   47,   46,   44,   43,
-    41,   40,   38,   36,   35,   33,   32,   30,   29,   27,
-    25,   24,   22,   21,   19,   18,   16,   15,   13,   12,
-    10,    9,    7,    6,    4,    3
-};
-
-//------------------------------------------------------------------------------
-// Level cost tables
-
-// For each given level, the following table gives the pattern of contexts to
-// use for coding it (in [][0]) as well as the bit value to use for each
-// context (in [][1]).
-const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2] = {
-                  {0x001, 0x000}, {0x007, 0x001}, {0x00f, 0x005},
-  {0x00f, 0x00d}, {0x033, 0x003}, {0x033, 0x003}, {0x033, 0x023},
-  {0x033, 0x023}, {0x033, 0x023}, {0x033, 0x023}, {0x0d3, 0x013},
-  {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013},
-  {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x013}, {0x0d3, 0x093},
-  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093},
-  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093},
-  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093},
-  {0x0d3, 0x093}, {0x0d3, 0x093}, {0x0d3, 0x093}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053},
-  {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x053}, {0x153, 0x153}
-};
-
-// fixed costs for coding levels, deduce from the coding tree.
-// This is only the part that doesn't depend on the probability state.
-const uint16_t VP8LevelFixedCosts[2048] = {
-     0,  256,  256,  256,  256,  432,  618,  630,
-   731,  640,  640,  828,  901,  948, 1021, 1101,
-  1174, 1221, 1294, 1042, 1085, 1115, 1158, 1202,
-  1245, 1275, 1318, 1337, 1380, 1410, 1453, 1497,
-  1540, 1570, 1613, 1280, 1295, 1317, 1332, 1358,
-  1373, 1395, 1410, 1454, 1469, 1491, 1506, 1532,
-  1547, 1569, 1584, 1601, 1616, 1638, 1653, 1679,
-  1694, 1716, 1731, 1775, 1790, 1812, 1827, 1853,
-  1868, 1890, 1905, 1727, 1733, 1742, 1748, 1759,
-  1765, 1774, 1780, 1800, 1806, 1815, 1821, 1832,
-  1838, 1847, 1853, 1878, 1884, 1893, 1899, 1910,
-  1916, 1925, 1931, 1951, 1957, 1966, 1972, 1983,
-  1989, 1998, 2004, 2027, 2033, 2042, 2048, 2059,
-  2065, 2074, 2080, 2100, 2106, 2115, 2121, 2132,
-  2138, 2147, 2153, 2178, 2184, 2193, 2199, 2210,
-  2216, 2225, 2231, 2251, 2257, 2266, 2272, 2283,
-  2289, 2298, 2304, 2168, 2174, 2183, 2189, 2200,
-  2206, 2215, 2221, 2241, 2247, 2256, 2262, 2273,
-  2279, 2288, 2294, 2319, 2325, 2334, 2340, 2351,
-  2357, 2366, 2372, 2392, 2398, 2407, 2413, 2424,
-  2430, 2439, 2445, 2468, 2474, 2483, 2489, 2500,
-  2506, 2515, 2521, 2541, 2547, 2556, 2562, 2573,
-  2579, 2588, 2594, 2619, 2625, 2634, 2640, 2651,
-  2657, 2666, 2672, 2692, 2698, 2707, 2713, 2724,
-  2730, 2739, 2745, 2540, 2546, 2555, 2561, 2572,
-  2578, 2587, 2593, 2613, 2619, 2628, 2634, 2645,
-  2651, 2660, 2666, 2691, 2697, 2706, 2712, 2723,
-  2729, 2738, 2744, 2764, 2770, 2779, 2785, 2796,
-  2802, 2811, 2817, 2840, 2846, 2855, 2861, 2872,
-  2878, 2887, 2893, 2913, 2919, 2928, 2934, 2945,
-  2951, 2960, 2966, 2991, 2997, 3006, 3012, 3023,
-  3029, 3038, 3044, 3064, 3070, 3079, 3085, 3096,
-  3102, 3111, 3117, 2981, 2987, 2996, 3002, 3013,
-  3019, 3028, 3034, 3054, 3060, 3069, 3075, 3086,
-  3092, 3101, 3107, 3132, 3138, 3147, 3153, 3164,
-  3170, 3179, 3185, 3205, 3211, 3220, 3226, 3237,
-  3243, 3252, 3258, 3281, 3287, 3296, 3302, 3313,
-  3319, 3328, 3334, 3354, 3360, 3369, 3375, 3386,
-  3392, 3401, 3407, 3432, 3438, 3447, 3453, 3464,
-  3470, 3479, 3485, 3505, 3511, 3520, 3526, 3537,
-  3543, 3552, 3558, 2816, 2822, 2831, 2837, 2848,
-  2854, 2863, 2869, 2889, 2895, 2904, 2910, 2921,
-  2927, 2936, 2942, 2967, 2973, 2982, 2988, 2999,
-  3005, 3014, 3020, 3040, 3046, 3055, 3061, 3072,
-  3078, 3087, 3093, 3116, 3122, 3131, 3137, 3148,
-  3154, 3163, 3169, 3189, 3195, 3204, 3210, 3221,
-  3227, 3236, 3242, 3267, 3273, 3282, 3288, 3299,
-  3305, 3314, 3320, 3340, 3346, 3355, 3361, 3372,
-  3378, 3387, 3393, 3257, 3263, 3272, 3278, 3289,
-  3295, 3304, 3310, 3330, 3336, 3345, 3351, 3362,
-  3368, 3377, 3383, 3408, 3414, 3423, 3429, 3440,
-  3446, 3455, 3461, 3481, 3487, 3496, 3502, 3513,
-  3519, 3528, 3534, 3557, 3563, 3572, 3578, 3589,
-  3595, 3604, 3610, 3630, 3636, 3645, 3651, 3662,
-  3668, 3677, 3683, 3708, 3714, 3723, 3729, 3740,
-  3746, 3755, 3761, 3781, 3787, 3796, 3802, 3813,
-  3819, 3828, 3834, 3629, 3635, 3644, 3650, 3661,
-  3667, 3676, 3682, 3702, 3708, 3717, 3723, 3734,
-  3740, 3749, 3755, 3780, 3786, 3795, 3801, 3812,
-  3818, 3827, 3833, 3853, 3859, 3868, 3874, 3885,
-  3891, 3900, 3906, 3929, 3935, 3944, 3950, 3961,
-  3967, 3976, 3982, 4002, 4008, 4017, 4023, 4034,
-  4040, 4049, 4055, 4080, 4086, 4095, 4101, 4112,
-  4118, 4127, 4133, 4153, 4159, 4168, 4174, 4185,
-  4191, 4200, 4206, 4070, 4076, 4085, 4091, 4102,
-  4108, 4117, 4123, 4143, 4149, 4158, 4164, 4175,
-  4181, 4190, 4196, 4221, 4227, 4236, 4242, 4253,
-  4259, 4268, 4274, 4294, 4300, 4309, 4315, 4326,
-  4332, 4341, 4347, 4370, 4376, 4385, 4391, 4402,
-  4408, 4417, 4423, 4443, 4449, 4458, 4464, 4475,
-  4481, 4490, 4496, 4521, 4527, 4536, 4542, 4553,
-  4559, 4568, 4574, 4594, 4600, 4609, 4615, 4626,
-  4632, 4641, 4647, 3515, 3521, 3530, 3536, 3547,
-  3553, 3562, 3568, 3588, 3594, 3603, 3609, 3620,
-  3626, 3635, 3641, 3666, 3672, 3681, 3687, 3698,
-  3704, 3713, 3719, 3739, 3745, 3754, 3760, 3771,
-  3777, 3786, 3792, 3815, 3821, 3830, 3836, 3847,
-  3853, 3862, 3868, 3888, 3894, 3903, 3909, 3920,
-  3926, 3935, 3941, 3966, 3972, 3981, 3987, 3998,
-  4004, 4013, 4019, 4039, 4045, 4054, 4060, 4071,
-  4077, 4086, 4092, 3956, 3962, 3971, 3977, 3988,
-  3994, 4003, 4009, 4029, 4035, 4044, 4050, 4061,
-  4067, 4076, 4082, 4107, 4113, 4122, 4128, 4139,
-  4145, 4154, 4160, 4180, 4186, 4195, 4201, 4212,
-  4218, 4227, 4233, 4256, 4262, 4271, 4277, 4288,
-  4294, 4303, 4309, 4329, 4335, 4344, 4350, 4361,
-  4367, 4376, 4382, 4407, 4413, 4422, 4428, 4439,
-  4445, 4454, 4460, 4480, 4486, 4495, 4501, 4512,
-  4518, 4527, 4533, 4328, 4334, 4343, 4349, 4360,
-  4366, 4375, 4381, 4401, 4407, 4416, 4422, 4433,
-  4439, 4448, 4454, 4479, 4485, 4494, 4500, 4511,
-  4517, 4526, 4532, 4552, 4558, 4567, 4573, 4584,
-  4590, 4599, 4605, 4628, 4634, 4643, 4649, 4660,
-  4666, 4675, 4681, 4701, 4707, 4716, 4722, 4733,
-  4739, 4748, 4754, 4779, 4785, 4794, 4800, 4811,
-  4817, 4826, 4832, 4852, 4858, 4867, 4873, 4884,
-  4890, 4899, 4905, 4769, 4775, 4784, 4790, 4801,
-  4807, 4816, 4822, 4842, 4848, 4857, 4863, 4874,
-  4880, 4889, 4895, 4920, 4926, 4935, 4941, 4952,
-  4958, 4967, 4973, 4993, 4999, 5008, 5014, 5025,
-  5031, 5040, 5046, 5069, 5075, 5084, 5090, 5101,
-  5107, 5116, 5122, 5142, 5148, 5157, 5163, 5174,
-  5180, 5189, 5195, 5220, 5226, 5235, 5241, 5252,
-  5258, 5267, 5273, 5293, 5299, 5308, 5314, 5325,
-  5331, 5340, 5346, 4604, 4610, 4619, 4625, 4636,
-  4642, 4651, 4657, 4677, 4683, 4692, 4698, 4709,
-  4715, 4724, 4730, 4755, 4761, 4770, 4776, 4787,
-  4793, 4802, 4808, 4828, 4834, 4843, 4849, 4860,
-  4866, 4875, 4881, 4904, 4910, 4919, 4925, 4936,
-  4942, 4951, 4957, 4977, 4983, 4992, 4998, 5009,
-  5015, 5024, 5030, 5055, 5061, 5070, 5076, 5087,
-  5093, 5102, 5108, 5128, 5134, 5143, 5149, 5160,
-  5166, 5175, 5181, 5045, 5051, 5060, 5066, 5077,
-  5083, 5092, 5098, 5118, 5124, 5133, 5139, 5150,
-  5156, 5165, 5171, 5196, 5202, 5211, 5217, 5228,
-  5234, 5243, 5249, 5269, 5275, 5284, 5290, 5301,
-  5307, 5316, 5322, 5345, 5351, 5360, 5366, 5377,
-  5383, 5392, 5398, 5418, 5424, 5433, 5439, 5450,
-  5456, 5465, 5471, 5496, 5502, 5511, 5517, 5528,
-  5534, 5543, 5549, 5569, 5575, 5584, 5590, 5601,
-  5607, 5616, 5622, 5417, 5423, 5432, 5438, 5449,
-  5455, 5464, 5470, 5490, 5496, 5505, 5511, 5522,
-  5528, 5537, 5543, 5568, 5574, 5583, 5589, 5600,
-  5606, 5615, 5621, 5641, 5647, 5656, 5662, 5673,
-  5679, 5688, 5694, 5717, 5723, 5732, 5738, 5749,
-  5755, 5764, 5770, 5790, 5796, 5805, 5811, 5822,
-  5828, 5837, 5843, 5868, 5874, 5883, 5889, 5900,
-  5906, 5915, 5921, 5941, 5947, 5956, 5962, 5973,
-  5979, 5988, 5994, 5858, 5864, 5873, 5879, 5890,
-  5896, 5905, 5911, 5931, 5937, 5946, 5952, 5963,
-  5969, 5978, 5984, 6009, 6015, 6024, 6030, 6041,
-  6047, 6056, 6062, 6082, 6088, 6097, 6103, 6114,
-  6120, 6129, 6135, 6158, 6164, 6173, 6179, 6190,
-  6196, 6205, 6211, 6231, 6237, 6246, 6252, 6263,
-  6269, 6278, 6284, 6309, 6315, 6324, 6330, 6341,
-  6347, 6356, 6362, 6382, 6388, 6397, 6403, 6414,
-  6420, 6429, 6435, 3515, 3521, 3530, 3536, 3547,
-  3553, 3562, 3568, 3588, 3594, 3603, 3609, 3620,
-  3626, 3635, 3641, 3666, 3672, 3681, 3687, 3698,
-  3704, 3713, 3719, 3739, 3745, 3754, 3760, 3771,
-  3777, 3786, 3792, 3815, 3821, 3830, 3836, 3847,
-  3853, 3862, 3868, 3888, 3894, 3903, 3909, 3920,
-  3926, 3935, 3941, 3966, 3972, 3981, 3987, 3998,
-  4004, 4013, 4019, 4039, 4045, 4054, 4060, 4071,
-  4077, 4086, 4092, 3956, 3962, 3971, 3977, 3988,
-  3994, 4003, 4009, 4029, 4035, 4044, 4050, 4061,
-  4067, 4076, 4082, 4107, 4113, 4122, 4128, 4139,
-  4145, 4154, 4160, 4180, 4186, 4195, 4201, 4212,
-  4218, 4227, 4233, 4256, 4262, 4271, 4277, 4288,
-  4294, 4303, 4309, 4329, 4335, 4344, 4350, 4361,
-  4367, 4376, 4382, 4407, 4413, 4422, 4428, 4439,
-  4445, 4454, 4460, 4480, 4486, 4495, 4501, 4512,
-  4518, 4527, 4533, 4328, 4334, 4343, 4349, 4360,
-  4366, 4375, 4381, 4401, 4407, 4416, 4422, 4433,
-  4439, 4448, 4454, 4479, 4485, 4494, 4500, 4511,
-  4517, 4526, 4532, 4552, 4558, 4567, 4573, 4584,
-  4590, 4599, 4605, 4628, 4634, 4643, 4649, 4660,
-  4666, 4675, 4681, 4701, 4707, 4716, 4722, 4733,
-  4739, 4748, 4754, 4779, 4785, 4794, 4800, 4811,
-  4817, 4826, 4832, 4852, 4858, 4867, 4873, 4884,
-  4890, 4899, 4905, 4769, 4775, 4784, 4790, 4801,
-  4807, 4816, 4822, 4842, 4848, 4857, 4863, 4874,
-  4880, 4889, 4895, 4920, 4926, 4935, 4941, 4952,
-  4958, 4967, 4973, 4993, 4999, 5008, 5014, 5025,
-  5031, 5040, 5046, 5069, 5075, 5084, 5090, 5101,
-  5107, 5116, 5122, 5142, 5148, 5157, 5163, 5174,
-  5180, 5189, 5195, 5220, 5226, 5235, 5241, 5252,
-  5258, 5267, 5273, 5293, 5299, 5308, 5314, 5325,
-  5331, 5340, 5346, 4604, 4610, 4619, 4625, 4636,
-  4642, 4651, 4657, 4677, 4683, 4692, 4698, 4709,
-  4715, 4724, 4730, 4755, 4761, 4770, 4776, 4787,
-  4793, 4802, 4808, 4828, 4834, 4843, 4849, 4860,
-  4866, 4875, 4881, 4904, 4910, 4919, 4925, 4936,
-  4942, 4951, 4957, 4977, 4983, 4992, 4998, 5009,
-  5015, 5024, 5030, 5055, 5061, 5070, 5076, 5087,
-  5093, 5102, 5108, 5128, 5134, 5143, 5149, 5160,
-  5166, 5175, 5181, 5045, 5051, 5060, 5066, 5077,
-  5083, 5092, 5098, 5118, 5124, 5133, 5139, 5150,
-  5156, 5165, 5171, 5196, 5202, 5211, 5217, 5228,
-  5234, 5243, 5249, 5269, 5275, 5284, 5290, 5301,
-  5307, 5316, 5322, 5345, 5351, 5360, 5366, 5377,
-  5383, 5392, 5398, 5418, 5424, 5433, 5439, 5450,
-  5456, 5465, 5471, 5496, 5502, 5511, 5517, 5528,
-  5534, 5543, 5549, 5569, 5575, 5584, 5590, 5601,
-  5607, 5616, 5622, 5417, 5423, 5432, 5438, 5449,
-  5455, 5464, 5470, 5490, 5496, 5505, 5511, 5522,
-  5528, 5537, 5543, 5568, 5574, 5583, 5589, 5600,
-  5606, 5615, 5621, 5641, 5647, 5656, 5662, 5673,
-  5679, 5688, 5694, 5717, 5723, 5732, 5738, 5749,
-  5755, 5764, 5770, 5790, 5796, 5805, 5811, 5822,
-  5828, 5837, 5843, 5868, 5874, 5883, 5889, 5900,
-  5906, 5915, 5921, 5941, 5947, 5956, 5962, 5973,
-  5979, 5988, 5994, 5858, 5864, 5873, 5879, 5890,
-  5896, 5905, 5911, 5931, 5937, 5946, 5952, 5963,
-  5969, 5978, 5984, 6009, 6015, 6024, 6030, 6041,
-  6047, 6056, 6062, 6082, 6088, 6097, 6103, 6114,
-  6120, 6129, 6135, 6158, 6164, 6173, 6179, 6190,
-  6196, 6205, 6211, 6231, 6237, 6246, 6252, 6263,
-  6269, 6278, 6284, 6309, 6315, 6324, 6330, 6341,
-  6347, 6356, 6362, 6382, 6388, 6397, 6403, 6414,
-  6420, 6429, 6435, 5303, 5309, 5318, 5324, 5335,
-  5341, 5350, 5356, 5376, 5382, 5391, 5397, 5408,
-  5414, 5423, 5429, 5454, 5460, 5469, 5475, 5486,
-  5492, 5501, 5507, 5527, 5533, 5542, 5548, 5559,
-  5565, 5574, 5580, 5603, 5609, 5618, 5624, 5635,
-  5641, 5650, 5656, 5676, 5682, 5691, 5697, 5708,
-  5714, 5723, 5729, 5754, 5760, 5769, 5775, 5786,
-  5792, 5801, 5807, 5827, 5833, 5842, 5848, 5859,
-  5865, 5874, 5880, 5744, 5750, 5759, 5765, 5776,
-  5782, 5791, 5797, 5817, 5823, 5832, 5838, 5849,
-  5855, 5864, 5870, 5895, 5901, 5910, 5916, 5927,
-  5933, 5942, 5948, 5968, 5974, 5983, 5989, 6000,
-  6006, 6015, 6021, 6044, 6050, 6059, 6065, 6076,
-  6082, 6091, 6097, 6117, 6123, 6132, 6138, 6149,
-  6155, 6164, 6170, 6195, 6201, 6210, 6216, 6227,
-  6233, 6242, 6248, 6268, 6274, 6283, 6289, 6300,
-  6306, 6315, 6321, 6116, 6122, 6131, 6137, 6148,
-  6154, 6163, 6169, 6189, 6195, 6204, 6210, 6221,
-  6227, 6236, 6242, 6267, 6273, 6282, 6288, 6299,
-  6305, 6314, 6320, 6340, 6346, 6355, 6361, 6372,
-  6378, 6387, 6393, 6416, 6422, 6431, 6437, 6448,
-  6454, 6463, 6469, 6489, 6495, 6504, 6510, 6521,
-  6527, 6536, 6542, 6567, 6573, 6582, 6588, 6599,
-  6605, 6614, 6620, 6640, 6646, 6655, 6661, 6672,
-  6678, 6687, 6693, 6557, 6563, 6572, 6578, 6589,
-  6595, 6604, 6610, 6630, 6636, 6645, 6651, 6662,
-  6668, 6677, 6683, 6708, 6714, 6723, 6729, 6740,
-  6746, 6755, 6761, 6781, 6787, 6796, 6802, 6813,
-  6819, 6828, 6834, 6857, 6863, 6872, 6878, 6889,
-  6895, 6904, 6910, 6930, 6936, 6945, 6951, 6962,
-  6968, 6977, 6983, 7008, 7014, 7023, 7029, 7040,
-  7046, 7055, 7061, 7081, 7087, 7096, 7102, 7113,
-  7119, 7128, 7134, 6392, 6398, 6407, 6413, 6424,
-  6430, 6439, 6445, 6465, 6471, 6480, 6486, 6497,
-  6503, 6512, 6518, 6543, 6549, 6558, 6564, 6575,
-  6581, 6590, 6596, 6616, 6622, 6631, 6637, 6648,
-  6654, 6663, 6669, 6692, 6698, 6707, 6713, 6724,
-  6730, 6739, 6745, 6765, 6771, 6780, 6786, 6797,
-  6803, 6812, 6818, 6843, 6849, 6858, 6864, 6875,
-  6881, 6890, 6896, 6916, 6922, 6931, 6937, 6948,
-  6954, 6963, 6969, 6833, 6839, 6848, 6854, 6865,
-  6871, 6880, 6886, 6906, 6912, 6921, 6927, 6938,
-  6944, 6953, 6959, 6984, 6990, 6999, 7005, 7016,
-  7022, 7031, 7037, 7057, 7063, 7072, 7078, 7089,
-  7095, 7104, 7110, 7133, 7139, 7148, 7154, 7165,
-  7171, 7180, 7186, 7206, 7212, 7221, 7227, 7238,
-  7244, 7253, 7259, 7284, 7290, 7299, 7305, 7316,
-  7322, 7331, 7337, 7357, 7363, 7372, 7378, 7389,
-  7395, 7404, 7410, 7205, 7211, 7220, 7226, 7237,
-  7243, 7252, 7258, 7278, 7284, 7293, 7299, 7310,
-  7316, 7325, 7331, 7356, 7362, 7371, 7377, 7388,
-  7394, 7403, 7409, 7429, 7435, 7444, 7450, 7461,
-  7467, 7476, 7482, 7505, 7511, 7520, 7526, 7537,
-  7543, 7552, 7558, 7578, 7584, 7593, 7599, 7610,
-  7616, 7625, 7631, 7656, 7662, 7671, 7677, 7688,
-  7694, 7703, 7709, 7729, 7735, 7744, 7750, 7761
-};
-
-static int VariableLevelCost(int level, const uint8_t probas[NUM_PROBAS]) {
-  int pattern = VP8LevelCodes[level - 1][0];
-  int bits = VP8LevelCodes[level - 1][1];
-  int cost = 0;
-  int i;
-  for (i = 2; pattern; ++i) {
-    if (pattern & 1) {
-      cost += VP8BitCost(bits & 1, probas[i]);
-    }
-    bits >>= 1;
-    pattern >>= 1;
-  }
-  return cost;
-}
-
-//------------------------------------------------------------------------------
-// Pre-calc level costs once for all
-
-void VP8CalculateLevelCosts(VP8Proba* const proba) {
-  int ctype, band, ctx;
-
-  if (!proba->dirty_) return;  // nothing to do.
-
-  for (ctype = 0; ctype < NUM_TYPES; ++ctype) {
-    for (band = 0; band < NUM_BANDS; ++band) {
-      for(ctx = 0; ctx < NUM_CTX; ++ctx) {
-        const uint8_t* const p = proba->coeffs_[ctype][band][ctx];
-        uint16_t* const table = proba->level_cost_[ctype][band][ctx];
-        const int cost_base = VP8BitCost(1, p[1]);
-        int v;
-        table[0] = VP8BitCost(0, p[1]);
-        for (v = 1; v <= MAX_VARIABLE_LEVEL; ++v) {
-          table[v] = cost_base + VariableLevelCost(v, p);
-        }
-        // Starting at level 67 and up, the variable part of the cost is
-        // actually constant.
-      }
-    }
-  }
-  proba->dirty_ = 0;
-}
-
-//------------------------------------------------------------------------------
-// Mode cost tables.
-
-// These are the fixed probabilities (in the coding trees) turned into bit-cost
-// by calling VP8BitCost().
-const uint16_t VP8FixedCostsUV[4] = { 302, 984, 439, 642 };
-// note: these values include the fixed VP8BitCost(1, 145) mode selection cost.
-const uint16_t VP8FixedCostsI16[4] = { 663, 919, 872, 919 };
-const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES] = {
-  { {  251, 1362, 1934, 2085, 2314, 2230, 1839, 1988, 2437, 2348 },
-    {  403,  680, 1507, 1519, 2060, 2005, 1992, 1914, 1924, 1733 },
-    {  353, 1121,  973, 1895, 2060, 1787, 1671, 1516, 2012, 1868 },
-    {  770,  852, 1581,  632, 1393, 1780, 1823, 1936, 1074, 1218 },
-    {  510, 1270, 1467, 1319,  847, 1279, 1792, 2094, 1080, 1353 },
-    {  488, 1322,  918, 1573, 1300,  883, 1814, 1752, 1756, 1502 },
-    {  425,  992, 1820, 1514, 1843, 2440,  937, 1771, 1924, 1129 },
-    {  363, 1248, 1257, 1970, 2194, 2385, 1569,  953, 1951, 1601 },
-    {  723, 1257, 1631,  964,  963, 1508, 1697, 1824,  671, 1418 },
-    {  635, 1038, 1573,  930, 1673, 1413, 1410, 1687, 1410,  749 } },
-  { {  451,  613, 1345, 1702, 1870, 1716, 1728, 1766, 2190, 2310 },
-    {  678,  453, 1171, 1443, 1925, 1831, 2045, 1781, 1887, 1602 },
-    {  711,  666,  674, 1718, 1910, 1493, 1775, 1193, 2325, 2325 },
-    {  883,  854, 1583,  542, 1800, 1878, 1664, 2149, 1207, 1087 },
-    {  669,  994, 1248, 1122,  949, 1179, 1376, 1729, 1070, 1244 },
-    {  715, 1026,  715, 1350, 1430,  930, 1717, 1296, 1479, 1479 },
-    {  544,  841, 1656, 1450, 2094, 3883, 1010, 1759, 2076,  809 },
-    {  610,  855,  957, 1553, 2067, 1561, 1704,  824, 2066, 1226 },
-    {  833,  960, 1416,  819, 1277, 1619, 1501, 1617,  757, 1182 },
-    {  711,  964, 1252,  879, 1441, 1828, 1508, 1636, 1594,  734 } },
-  { {  605,  764,  734, 1713, 1747, 1192, 1819, 1353, 1877, 2392 },
-    {  866,  641,  586, 1622, 2072, 1431, 1888, 1346, 2189, 1764 },
-    {  901,  851,  456, 2165, 2281, 1405, 1739, 1193, 2183, 2443 },
-    {  770, 1045,  952, 1078, 1342, 1191, 1436, 1063, 1303,  995 },
-    {  901, 1086,  727, 1170,  884, 1105, 1267, 1401, 1739, 1337 },
-    {  951, 1162,  595, 1488, 1388,  703, 1790, 1366, 2057, 1724 },
-    {  534,  986, 1273, 1987, 3273, 1485, 1024, 1399, 1583,  866 },
-    {  699, 1182,  695, 1978, 1726, 1986, 1326,  714, 1750, 1672 },
-    {  951, 1217, 1209,  920, 1062, 1441, 1548,  999,  952,  932 },
-    {  733, 1284,  784, 1256, 1557, 1098, 1257, 1357, 1414,  908 } },
-  { {  316, 1075, 1653, 1220, 2145, 2051, 1730, 2131, 1884, 1790 },
-    {  745,  516, 1404,  894, 1599, 2375, 2013, 2105, 1475, 1381 },
-    {  516,  729, 1088, 1319, 1637, 3426, 1636, 1275, 1531, 1453 },
-    {  894,  943, 2138,  468, 1704, 2259, 2069, 1763, 1266, 1158 },
-    {  605, 1025, 1235,  871, 1170, 1767, 1493, 1500, 1104, 1258 },
-    {  739,  826, 1207, 1151, 1412,  846, 1305, 2726, 1014, 1569 },
-    {  558,  825, 1820, 1398, 3344, 1556, 1218, 1550, 1228,  878 },
-    {  429,  951, 1089, 1816, 3861, 3861, 1556,  969, 1568, 1828 },
-    {  883,  961, 1752,  769, 1468, 1810, 2081, 2346,  613, 1298 },
-    {  803,  895, 1372,  641, 1303, 1708, 1686, 1700, 1306, 1033 } },
-  { {  439, 1267, 1270, 1579,  963, 1193, 1723, 1729, 1198, 1993 },
-    {  705,  725, 1029, 1153, 1176, 1103, 1821, 1567, 1259, 1574 },
-    {  723,  859,  802, 1253,  972, 1202, 1407, 1665, 1520, 1674 },
-    {  894,  960, 1254,  887, 1052, 1607, 1344, 1349,  865, 1150 },
-    {  833, 1312, 1337, 1205,  572, 1288, 1414, 1529, 1088, 1430 },
-    {  842, 1279, 1068, 1861,  862,  688, 1861, 1630, 1039, 1381 },
-    {  766,  938, 1279, 1546, 3338, 1550, 1031, 1542, 1288,  640 },
-    {  715, 1090,  835, 1609, 1100, 1100, 1603, 1019, 1102, 1617 },
-    {  894, 1813, 1500, 1188,  789, 1194, 1491, 1919,  617, 1333 },
-    {  610, 1076, 1644, 1281, 1283,  975, 1179, 1688, 1434,  889 } },
-  { {  544,  971, 1146, 1849, 1221,  740, 1857, 1621, 1683, 2430 },
-    {  723,  705,  961, 1371, 1426,  821, 2081, 2079, 1839, 1380 },
-    {  783,  857,  703, 2145, 1419,  814, 1791, 1310, 1609, 2206 },
-    {  997, 1000, 1153,  792, 1229, 1162, 1810, 1418,  942,  979 },
-    {  901, 1226,  883, 1289,  793,  715, 1904, 1649, 1319, 3108 },
-    {  979, 1478,  782, 2216, 1454,  455, 3092, 1591, 1997, 1664 },
-    {  663, 1110, 1504, 1114, 1522, 3311,  676, 1522, 1530, 1024 },
-    {  605, 1138, 1153, 1314, 1569, 1315, 1157,  804, 1574, 1320 },
-    {  770, 1216, 1218, 1227,  869, 1384, 1232, 1375,  834, 1239 },
-    {  775, 1007,  843, 1216, 1225, 1074, 2527, 1479, 1149,  975 } },
-  { {  477,  817, 1309, 1439, 1708, 1454, 1159, 1241, 1945, 1672 },
-    {  577,  796, 1112, 1271, 1618, 1458, 1087, 1345, 1831, 1265 },
-    {  663,  776,  753, 1940, 1690, 1690, 1227, 1097, 3149, 1361 },
-    {  766, 1299, 1744, 1161, 1565, 1106, 1045, 1230, 1232,  707 },
-    {  915, 1026, 1404, 1182, 1184,  851, 1428, 2425, 1043,  789 },
-    {  883, 1456,  790, 1082, 1086,  985, 1083, 1484, 1238, 1160 },
-    {  507, 1345, 2261, 1995, 1847, 3636,  653, 1761, 2287,  933 },
-    {  553, 1193, 1470, 2057, 2059, 2059,  833,  779, 2058, 1263 },
-    {  766, 1275, 1515, 1039,  957, 1554, 1286, 1540, 1289,  705 },
-    {  499, 1378, 1496, 1385, 1850, 1850, 1044, 2465, 1515,  720 } },
-  { {  553,  930,  978, 2077, 1968, 1481, 1457,  761, 1957, 2362 },
-    {  694,  864,  905, 1720, 1670, 1621, 1429,  718, 2125, 1477 },
-    {  699,  968,  658, 3190, 2024, 1479, 1865,  750, 2060, 2320 },
-    {  733, 1308, 1296, 1062, 1576, 1322, 1062, 1112, 1172,  816 },
-    {  920,  927, 1052,  939,  947, 1156, 1152, 1073, 3056, 1268 },
-    {  723, 1534,  711, 1547, 1294,  892, 1553,  928, 1815, 1561 },
-    {  663, 1366, 1583, 2111, 1712, 3501,  522, 1155, 2130, 1133 },
-    {  614, 1731, 1188, 2343, 1944, 3733, 1287,  487, 3546, 1758 },
-    {  770, 1585, 1312,  826,  884, 2673, 1185, 1006, 1195, 1195 },
-    {  758, 1333, 1273, 1023, 1621, 1162, 1351,  833, 1479,  862 } },
-  { {  376, 1193, 1446, 1149, 1545, 1577, 1870, 1789, 1175, 1823 },
-    {  803,  633, 1136, 1058, 1350, 1323, 1598, 2247, 1072, 1252 },
-    {  614, 1048,  943,  981, 1152, 1869, 1461, 1020, 1618, 1618 },
-    { 1107, 1085, 1282,  592, 1779, 1933, 1648, 2403,  691, 1246 },
-    {  851, 1309, 1223, 1243,  895, 1593, 1792, 2317,  627, 1076 },
-    {  770, 1216, 1030, 1125,  921,  981, 1629, 1131, 1049, 1646 },
-    {  626, 1469, 1456, 1081, 1489, 3278,  981, 1232, 1498,  733 },
-    {  617, 1201,  812, 1220, 1476, 1476, 1478,  970, 1228, 1488 },
-    { 1179, 1393, 1540,  999, 1243, 1503, 1916, 1925,  414, 1614 },
-    {  943, 1088, 1490,  682, 1112, 1372, 1756, 1505,  966,  966 } },
-  { {  322, 1142, 1589, 1396, 2144, 1859, 1359, 1925, 2084, 1518 },
-    {  617,  625, 1241, 1234, 2121, 1615, 1524, 1858, 1720, 1004 },
-    {  553,  851,  786, 1299, 1452, 1560, 1372, 1561, 1967, 1713 },
-    {  770,  977, 1396,  568, 1893, 1639, 1540, 2108, 1430, 1013 },
-    {  684, 1120, 1375,  982,  930, 2719, 1638, 1643,  933,  993 },
-    {  553, 1103,  996, 1356, 1361, 1005, 1507, 1761, 1184, 1268 },
-    {  419, 1247, 1537, 1554, 1817, 3606, 1026, 1666, 1829,  923 },
-    {  439, 1139, 1101, 1257, 3710, 1922, 1205, 1040, 1931, 1529 },
-    {  979,  935, 1269,  847, 1202, 1286, 1530, 1535,  827, 1036 },
-    {  516, 1378, 1569, 1110, 1798, 1798, 1198, 2199, 1543,  712 } },
-};
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 48
drivers/webpold/enc/cost.h

@@ -1,48 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Cost tables for level and modes.
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_ENC_COST_H_
-#define WEBP_ENC_COST_H_
-
-#include "./vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-extern const uint16_t VP8LevelFixedCosts[2048];   // approximate cost per level
-extern const uint16_t VP8EntropyCost[256];        // 8bit fixed-point log(p)
-
-// Cost of coding one event with probability 'proba'.
-static WEBP_INLINE int VP8BitCost(int bit, uint8_t proba) {
-  return !bit ? VP8EntropyCost[proba] : VP8EntropyCost[255 - proba];
-}
-
-// Level cost calculations
-extern const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2];
-void VP8CalculateLevelCosts(VP8Proba* const proba);
-static WEBP_INLINE int VP8LevelCost(const uint16_t* const table, int level) {
-  return VP8LevelFixedCosts[level]
-       + table[(level > MAX_VARIABLE_LEVEL) ? MAX_VARIABLE_LEVEL : level];
-}
-
-// Mode costs
-extern const uint16_t VP8FixedCostsUV[4];
-extern const uint16_t VP8FixedCostsI16[4];
-extern const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES];
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_ENC_COST_H_ */

+ 0 - 409
drivers/webpold/enc/filter.c

@@ -1,409 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Selecting filter level
-//
-// Author: [email protected] (Somnath Banerjee)
-
-#include "./vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// NOTE: clip1, tables and InitTables are repeated entries of dsp.c
-static uint8_t abs0[255 + 255 + 1];     // abs(i)
-static uint8_t abs1[255 + 255 + 1];     // abs(i)>>1
-static int8_t sclip1[1020 + 1020 + 1];  // clips [-1020, 1020] to [-128, 127]
-static int8_t sclip2[112 + 112 + 1];    // clips [-112, 112] to [-16, 15]
-static uint8_t clip1[255 + 510 + 1];    // clips [-255,510] to [0,255]
-
-static int tables_ok = 0;
-
-static void InitTables(void) {
-  if (!tables_ok) {
-    int i;
-    for (i = -255; i <= 255; ++i) {
-      abs0[255 + i] = (i < 0) ? -i : i;
-      abs1[255 + i] = abs0[255 + i] >> 1;
-    }
-    for (i = -1020; i <= 1020; ++i) {
-      sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i;
-    }
-    for (i = -112; i <= 112; ++i) {
-      sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i;
-    }
-    for (i = -255; i <= 255 + 255; ++i) {
-      clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
-    }
-    tables_ok = 1;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Edge filtering functions
-
-// 4 pixels in, 2 pixels out
-static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  const int a = 3 * (q0 - p0) + sclip1[1020 + p1 - q1];
-  const int a1 = sclip2[112 + ((a + 4) >> 3)];
-  const int a2 = sclip2[112 + ((a + 3) >> 3)];
-  p[-step] = clip1[255 + p0 + a2];
-  p[    0] = clip1[255 + q0 - a1];
-}
-
-// 4 pixels in, 4 pixels out
-static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  const int a = 3 * (q0 - p0);
-  const int a1 = sclip2[112 + ((a + 4) >> 3)];
-  const int a2 = sclip2[112 + ((a + 3) >> 3)];
-  const int a3 = (a1 + 1) >> 1;
-  p[-2*step] = clip1[255 + p1 + a3];
-  p[-  step] = clip1[255 + p0 + a2];
-  p[      0] = clip1[255 + q0 - a1];
-  p[   step] = clip1[255 + q1 - a3];
-}
-
-// high edge-variance
-static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  return (abs0[255 + p1 - p0] > thresh) || (abs0[255 + q1 - q0] > thresh);
-}
-
-static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int thresh) {
-  const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
-  return (2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) <= thresh;
-}
-
-static WEBP_INLINE int needs_filter2(const uint8_t* p,
-                                     int step, int t, int it) {
-  const int p3 = p[-4*step], p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
-  const int q0 = p[0], q1 = p[step], q2 = p[2*step], q3 = p[3*step];
-  if ((2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) > t)
-    return 0;
-  return abs0[255 + p3 - p2] <= it && abs0[255 + p2 - p1] <= it &&
-         abs0[255 + p1 - p0] <= it && abs0[255 + q3 - q2] <= it &&
-         abs0[255 + q2 - q1] <= it && abs0[255 + q1 - q0] <= it;
-}
-
-//------------------------------------------------------------------------------
-// Simple In-loop filtering (Paragraph 15.2)
-
-static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
-  int i;
-  for (i = 0; i < 16; ++i) {
-    if (needs_filter(p + i, stride, thresh)) {
-      do_filter2(p + i, stride);
-    }
-  }
-}
-
-static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
-  int i;
-  for (i = 0; i < 16; ++i) {
-    if (needs_filter(p + i * stride, 1, thresh)) {
-      do_filter2(p + i * stride, 1);
-    }
-  }
-}
-
-static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4 * stride;
-    SimpleVFilter16(p, stride, thresh);
-  }
-}
-
-static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4;
-    SimpleHFilter16(p, stride, thresh);
-  }
-}
-
-//------------------------------------------------------------------------------
-// Complex In-loop filtering (Paragraph 15.3)
-
-static WEBP_INLINE void FilterLoop24(uint8_t* p,
-                                     int hstride, int vstride, int size,
-                                     int thresh, int ithresh, int hev_thresh) {
-  while (size-- > 0) {
-    if (needs_filter2(p, hstride, thresh, ithresh)) {
-      if (hev(p, hstride, hev_thresh)) {
-        do_filter2(p, hstride);
-      } else {
-        do_filter4(p, hstride);
-      }
-    }
-    p += vstride;
-  }
-}
-
-// on three inner edges
-static void VFilter16i(uint8_t* p, int stride,
-                       int thresh, int ithresh, int hev_thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4 * stride;
-    FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
-  }
-}
-
-static void HFilter16i(uint8_t* p, int stride,
-                       int thresh, int ithresh, int hev_thresh) {
-  int k;
-  for (k = 3; k > 0; --k) {
-    p += 4;
-    FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
-  }
-}
-
-static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
-                      int thresh, int ithresh, int hev_thresh) {
-  FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
-  FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
-}
-
-static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
-                      int thresh, int ithresh, int hev_thresh) {
-  FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
-  FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
-}
-
-//------------------------------------------------------------------------------
-
-void (*VP8EncVFilter16i)(uint8_t*, int, int, int, int) = VFilter16i;
-void (*VP8EncHFilter16i)(uint8_t*, int, int, int, int) = HFilter16i;
-void (*VP8EncVFilter8i)(uint8_t*, uint8_t*, int, int, int, int) = VFilter8i;
-void (*VP8EncHFilter8i)(uint8_t*, uint8_t*, int, int, int, int) = HFilter8i;
-
-void (*VP8EncSimpleVFilter16i)(uint8_t*, int, int) = SimpleVFilter16i;
-void (*VP8EncSimpleHFilter16i)(uint8_t*, int, int) = SimpleHFilter16i;
-
-//------------------------------------------------------------------------------
-// Paragraph 15.4: compute the inner-edge filtering strength
-
-static int GetILevel(int sharpness, int level) {
-  if (sharpness > 0) {
-    if (sharpness > 4) {
-      level >>= 2;
-    } else {
-      level >>= 1;
-    }
-    if (level > 9 - sharpness) {
-      level = 9 - sharpness;
-    }
-  }
-  if (level < 1) level = 1;
-  return level;
-}
-
-static void DoFilter(const VP8EncIterator* const it, int level) {
-  const VP8Encoder* const enc = it->enc_;
-  const int ilevel = GetILevel(enc->config_->filter_sharpness, level);
-  const int limit = 2 * level + ilevel;
-
-  uint8_t* const y_dst = it->yuv_out2_ + Y_OFF;
-  uint8_t* const u_dst = it->yuv_out2_ + U_OFF;
-  uint8_t* const v_dst = it->yuv_out2_ + V_OFF;
-
-  // copy current block to yuv_out2_
-  memcpy(y_dst, it->yuv_out_, YUV_SIZE * sizeof(uint8_t));
-
-  if (enc->filter_hdr_.simple_ == 1) {   // simple
-    VP8EncSimpleHFilter16i(y_dst, BPS, limit);
-    VP8EncSimpleVFilter16i(y_dst, BPS, limit);
-  } else {    // complex
-    const int hev_thresh = (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
-    VP8EncHFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
-    VP8EncHFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
-    VP8EncVFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
-    VP8EncVFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
-  }
-}
-
-//------------------------------------------------------------------------------
-// SSIM metric
-
-enum { KERNEL = 3 };
-static const double kMinValue = 1.e-10;  // minimal threshold
-
-void VP8SSIMAddStats(const DistoStats* const src, DistoStats* const dst) {
-  dst->w   += src->w;
-  dst->xm  += src->xm;
-  dst->ym  += src->ym;
-  dst->xxm += src->xxm;
-  dst->xym += src->xym;
-  dst->yym += src->yym;
-}
-
-static void VP8SSIMAccumulate(const uint8_t* src1, int stride1,
-                              const uint8_t* src2, int stride2,
-                              int xo, int yo, int W, int H,
-                              DistoStats* const stats) {
-  const int ymin = (yo - KERNEL < 0) ? 0 : yo - KERNEL;
-  const int ymax = (yo + KERNEL > H - 1) ? H - 1 : yo + KERNEL;
-  const int xmin = (xo - KERNEL < 0) ? 0 : xo - KERNEL;
-  const int xmax = (xo + KERNEL > W - 1) ? W - 1 : xo + KERNEL;
-  int x, y;
-  src1 += ymin * stride1;
-  src2 += ymin * stride2;
-  for (y = ymin; y <= ymax; ++y, src1 += stride1, src2 += stride2) {
-    for (x = xmin; x <= xmax; ++x) {
-      const int s1 = src1[x];
-      const int s2 = src2[x];
-      stats->w   += 1;
-      stats->xm  += s1;
-      stats->ym  += s2;
-      stats->xxm += s1 * s1;
-      stats->xym += s1 * s2;
-      stats->yym += s2 * s2;
-    }
-  }
-}
-
-double VP8SSIMGet(const DistoStats* const stats) {
-  const double xmxm = stats->xm * stats->xm;
-  const double ymym = stats->ym * stats->ym;
-  const double xmym = stats->xm * stats->ym;
-  const double w2 = stats->w * stats->w;
-  double sxx = stats->xxm * stats->w - xmxm;
-  double syy = stats->yym * stats->w - ymym;
-  double sxy = stats->xym * stats->w - xmym;
-  double C1, C2;
-  double fnum;
-  double fden;
-  // small errors are possible, due to rounding. Clamp to zero.
-  if (sxx < 0.) sxx = 0.;
-  if (syy < 0.) syy = 0.;
-  C1 = 6.5025 * w2;
-  C2 = 58.5225 * w2;
-  fnum = (2 * xmym + C1) * (2 * sxy + C2);
-  fden = (xmxm + ymym + C1) * (sxx + syy + C2);
-  return (fden != 0.) ? fnum / fden : kMinValue;
-}
-
-double VP8SSIMGetSquaredError(const DistoStats* const s) {
-  if (s->w > 0.) {
-    const double iw2 = 1. / (s->w * s->w);
-    const double sxx = s->xxm * s->w - s->xm * s->xm;
-    const double syy = s->yym * s->w - s->ym * s->ym;
-    const double sxy = s->xym * s->w - s->xm * s->ym;
-    const double SSE = iw2 * (sxx + syy - 2. * sxy);
-    if (SSE > kMinValue) return SSE;
-  }
-  return kMinValue;
-}
-
-void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1,
-                            const uint8_t* src2, int stride2,
-                            int W, int H, DistoStats* const stats) {
-  int x, y;
-  for (y = 0; y < H; ++y) {
-    for (x = 0; x < W; ++x) {
-      VP8SSIMAccumulate(src1, stride1, src2, stride2, x, y, W, H, stats);
-    }
-  }
-}
-
-static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) {
-  int x, y;
-  DistoStats s = { .0, .0, .0, .0, .0, .0 };
-
-  // compute SSIM in a 10 x 10 window
-  for (x = 3; x < 13; x++) {
-    for (y = 3; y < 13; y++) {
-      VP8SSIMAccumulate(yuv1 + Y_OFF, BPS, yuv2 + Y_OFF, BPS, x, y, 16, 16, &s);
-    }
-  }
-  for (x = 1; x < 7; x++) {
-    for (y = 1; y < 7; y++) {
-      VP8SSIMAccumulate(yuv1 + U_OFF, BPS, yuv2 + U_OFF, BPS, x, y, 8, 8, &s);
-      VP8SSIMAccumulate(yuv1 + V_OFF, BPS, yuv2 + V_OFF, BPS, x, y, 8, 8, &s);
-    }
-  }
-  return VP8SSIMGet(&s);
-}
-
-//------------------------------------------------------------------------------
-// Exposed APIs: Encoder should call the following 3 functions to adjust
-// loop filter strength
-
-void VP8InitFilter(VP8EncIterator* const it) {
-  int s, i;
-  if (!it->lf_stats_) return;
-
-  InitTables();
-  for (s = 0; s < NUM_MB_SEGMENTS; s++) {
-    for (i = 0; i < MAX_LF_LEVELS; i++) {
-      (*it->lf_stats_)[s][i] = 0;
-    }
-  }
-}
-
-void VP8StoreFilterStats(VP8EncIterator* const it) {
-  int d;
-  const int s = it->mb_->segment_;
-  const int level0 = it->enc_->dqm_[s].fstrength_;  // TODO: ref_lf_delta[]
-
-  // explore +/-quant range of values around level0
-  const int delta_min = -it->enc_->dqm_[s].quant_;
-  const int delta_max = it->enc_->dqm_[s].quant_;
-  const int step_size = (delta_max - delta_min >= 4) ? 4 : 1;
-
-  if (!it->lf_stats_) return;
-
-  // NOTE: Currently we are applying filter only across the sublock edges
-  // There are two reasons for that.
-  // 1. Applying filter on macro block edges will change the pixels in
-  // the left and top macro blocks. That will be hard to restore
-  // 2. Macro Blocks on the bottom and right are not yet compressed. So we
-  // cannot apply filter on the right and bottom macro block edges.
-  if (it->mb_->type_ == 1 && it->mb_->skip_) return;
-
-  // Always try filter level  zero
-  (*it->lf_stats_)[s][0] += GetMBSSIM(it->yuv_in_, it->yuv_out_);
-
-  for (d = delta_min; d <= delta_max; d += step_size) {
-    const int level = level0 + d;
-    if (level <= 0 || level >= MAX_LF_LEVELS) {
-      continue;
-    }
-    DoFilter(it, level);
-    (*it->lf_stats_)[s][level] += GetMBSSIM(it->yuv_in_, it->yuv_out2_);
-  }
-}
-
-void VP8AdjustFilterStrength(VP8EncIterator* const it) {
-  int s;
-  VP8Encoder* const enc = it->enc_;
-
-  if (!it->lf_stats_) {
-    return;
-  }
-  for (s = 0; s < NUM_MB_SEGMENTS; s++) {
-    int i, best_level = 0;
-    // Improvement over filter level 0 should be at least 1e-5 (relatively)
-    double best_v = 1.00001 * (*it->lf_stats_)[s][0];
-    for (i = 1; i < MAX_LF_LEVELS; i++) {
-      const double v = (*it->lf_stats_)[s][i];
-      if (v > best_v) {
-        best_v = v;
-        best_level = i;
-      }
-    }
-    enc->dqm_[s].fstrength_ = best_level;
-  }
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 939
drivers/webpold/enc/frame.c

@@ -1,939 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//   frame coding and analysis
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "./vp8enci.h"
-#include "./cost.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define SEGMENT_VISU 0
-#define DEBUG_SEARCH 0    // useful to track search convergence
-
-// On-the-fly info about the current set of residuals. Handy to avoid
-// passing zillions of params.
-typedef struct {
-  int first;
-  int last;
-  const int16_t* coeffs;
-
-  int coeff_type;
-  ProbaArray* prob;
-  StatsArray* stats;
-  CostArray*  cost;
-} VP8Residual;
-
-//------------------------------------------------------------------------------
-// Tables for level coding
-
-const uint8_t VP8EncBands[16 + 1] = {
-  0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
-  0  // sentinel
-};
-
-static const uint8_t kCat3[] = { 173, 148, 140 };
-static const uint8_t kCat4[] = { 176, 155, 140, 135 };
-static const uint8_t kCat5[] = { 180, 157, 141, 134, 130 };
-static const uint8_t kCat6[] =
-    { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129 };
-
-//------------------------------------------------------------------------------
-// Reset the statistics about: number of skips, token proba, level cost,...
-
-static void ResetStats(VP8Encoder* const enc) {
-  VP8Proba* const proba = &enc->proba_;
-  VP8CalculateLevelCosts(proba);
-  proba->nb_skip_ = 0;
-}
-
-//------------------------------------------------------------------------------
-// Skip decision probability
-
-#define SKIP_PROBA_THRESHOLD 250  // value below which using skip_proba is OK.
-
-static int CalcSkipProba(uint64_t nb, uint64_t total) {
-  return (int)(total ? (total - nb) * 255 / total : 255);
-}
-
-// Returns the bit-cost for coding the skip probability.
-static int FinalizeSkipProba(VP8Encoder* const enc) {
-  VP8Proba* const proba = &enc->proba_;
-  const int nb_mbs = enc->mb_w_ * enc->mb_h_;
-  const int nb_events = proba->nb_skip_;
-  int size;
-  proba->skip_proba_ = CalcSkipProba(nb_events, nb_mbs);
-  proba->use_skip_proba_ = (proba->skip_proba_ < SKIP_PROBA_THRESHOLD);
-  size = 256;   // 'use_skip_proba' bit
-  if (proba->use_skip_proba_) {
-    size +=  nb_events * VP8BitCost(1, proba->skip_proba_)
-         + (nb_mbs - nb_events) * VP8BitCost(0, proba->skip_proba_);
-    size += 8 * 256;   // cost of signaling the skip_proba_ itself.
-  }
-  return size;
-}
-
-//------------------------------------------------------------------------------
-// Recording of token probabilities.
-
-static void ResetTokenStats(VP8Encoder* const enc) {
-  VP8Proba* const proba = &enc->proba_;
-  memset(proba->stats_, 0, sizeof(proba->stats_));
-}
-
-// Record proba context used
-static int 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;
-  return bit;
-}
-
-// We keep the table free variant around for reference, in case.
-#define USE_LEVEL_CODE_TABLE
-
-// Simulate block coding, but only record statistics.
-// Note: no need to record the fixed probas.
-static int RecordCoeffs(int ctx, const VP8Residual* const res) {
-  int n = res->first;
-  proba_t* s = res->stats[VP8EncBands[n]][ctx];
-  if (res->last  < 0) {
-    Record(0, s + 0);
-    return 0;
-  }
-  while (n <= res->last) {
-    int v;
-    Record(1, s + 0);
-    while ((v = res->coeffs[n++]) == 0) {
-      Record(0, s + 1);
-      s = res->stats[VP8EncBands[n]][0];
-    }
-    Record(1, s + 1);
-    if (!Record(2u < (unsigned int)(v + 1), s + 2)) {  // v = -1 or 1
-      s = res->stats[VP8EncBands[n]][1];
-    } else {
-      v = abs(v);
-#if !defined(USE_LEVEL_CODE_TABLE)
-      if (!Record(v > 4, s + 3)) {
-        if (Record(v != 2, s + 4))
-          Record(v == 4, s + 5);
-      } else if (!Record(v > 10, s + 6)) {
-        Record(v > 6, s + 7);
-      } else if (!Record((v >= 3 + (8 << 2)), s + 8)) {
-        Record((v >= 3 + (8 << 1)), s + 9);
-      } else {
-        Record((v >= 3 + (8 << 3)), s + 10);
-      }
-#else
-      if (v > MAX_VARIABLE_LEVEL)
-        v = MAX_VARIABLE_LEVEL;
-
-      {
-        const int bits = VP8LevelCodes[v - 1][1];
-        int pattern = VP8LevelCodes[v - 1][0];
-        int i;
-        for (i = 0; (pattern >>= 1) != 0; ++i) {
-          const int mask = 2 << i;
-          if (pattern & 1) Record(!!(bits & mask), s + 3 + i);
-        }
-      }
-#endif
-      s = res->stats[VP8EncBands[n]][2];
-    }
-  }
-  if (n < 16) Record(0, s + 0);
-  return 1;
-}
-
-// Collect statistics and deduce probabilities for next coding pass.
-// Return the total bit-cost for coding the probability updates.
-static int CalcTokenProba(int nb, int total) {
-  assert(nb <= total);
-  return nb ? (255 - nb * 255 / total) : 255;
-}
-
-// Cost of coding 'nb' 1's and 'total-nb' 0's using 'proba' probability.
-static int BranchCost(int nb, int total, int proba) {
-  return nb * VP8BitCost(1, proba) + (total - nb) * VP8BitCost(0, proba);
-}
-
-static int FinalizeTokenProbas(VP8Encoder* const enc) {
-  VP8Proba* const proba = &enc->proba_;
-  int has_changed = 0;
-  int size = 0;
-  int t, b, c, p;
-  for (t = 0; t < NUM_TYPES; ++t) {
-    for (b = 0; b < NUM_BANDS; ++b) {
-      for (c = 0; c < NUM_CTX; ++c) {
-        for (p = 0; p < NUM_PROBAS; ++p) {
-          const proba_t stats = proba->stats_[t][b][c][p];
-          const int nb = (stats >> 0) & 0xffff;
-          const int total = (stats >> 16) & 0xffff;
-          const int update_proba = VP8CoeffsUpdateProba[t][b][c][p];
-          const int old_p = VP8CoeffsProba0[t][b][c][p];
-          const int new_p = CalcTokenProba(nb, total);
-          const int old_cost = BranchCost(nb, total, old_p)
-                             + VP8BitCost(0, update_proba);
-          const int new_cost = BranchCost(nb, total, new_p)
-                             + VP8BitCost(1, update_proba)
-                             + 8 * 256;
-          const int use_new_p = (old_cost > new_cost);
-          size += VP8BitCost(use_new_p, update_proba);
-          if (use_new_p) {  // only use proba that seem meaningful enough.
-            proba->coeffs_[t][b][c][p] = new_p;
-            has_changed |= (new_p != old_p);
-            size += 8 * 256;
-          } else {
-            proba->coeffs_[t][b][c][p] = old_p;
-          }
-        }
-      }
-    }
-  }
-  proba->dirty_ = has_changed;
-  return size;
-}
-
-//------------------------------------------------------------------------------
-// helper functions for residuals struct VP8Residual.
-
-static void InitResidual(int first, int coeff_type,
-                         VP8Encoder* const enc, VP8Residual* const res) {
-  res->coeff_type = coeff_type;
-  res->prob  = enc->proba_.coeffs_[coeff_type];
-  res->stats = enc->proba_.stats_[coeff_type];
-  res->cost  = enc->proba_.level_cost_[coeff_type];
-  res->first = first;
-}
-
-static void SetResidualCoeffs(const int16_t* const coeffs,
-                              VP8Residual* const res) {
-  int n;
-  res->last = -1;
-  for (n = 15; n >= res->first; --n) {
-    if (coeffs[n]) {
-      res->last = n;
-      break;
-    }
-  }
-  res->coeffs = coeffs;
-}
-
-//------------------------------------------------------------------------------
-// Mode costs
-
-static int GetResidualCost(int ctx, const VP8Residual* const res) {
-  int n = res->first;
-  int p0 = res->prob[VP8EncBands[n]][ctx][0];
-  const uint16_t* t = res->cost[VP8EncBands[n]][ctx];
-  int cost;
-
-  if (res->last < 0) {
-    return VP8BitCost(0, p0);
-  }
-  cost = 0;
-  while (n <= res->last) {
-    const int v = res->coeffs[n];
-    const int b = VP8EncBands[n + 1];
-    ++n;
-    if (v == 0) {
-      // short-case for VP8LevelCost(t, 0) (note: VP8LevelFixedCosts[0] == 0):
-      cost += t[0];
-      t = res->cost[b][0];
-      continue;
-    }
-    cost += VP8BitCost(1, p0);
-    if (2u >= (unsigned int)(v + 1)) {   // v = -1 or 1
-      // short-case for "VP8LevelCost(t, 1)" (256 is VP8LevelFixedCosts[1]):
-      cost += 256 + t[1];
-      p0 = res->prob[b][1][0];
-      t = res->cost[b][1];
-    } else {
-      cost += VP8LevelCost(t, abs(v));
-      p0 = res->prob[b][2][0];
-      t = res->cost[b][2];
-    }
-  }
-  if (n < 16) cost += VP8BitCost(0, p0);
-  return cost;
-}
-
-int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]) {
-  const int x = (it->i4_ & 3), y = (it->i4_ >> 2);
-  VP8Residual res;
-  VP8Encoder* const enc = it->enc_;
-  int R = 0;
-  int ctx;
-
-  InitResidual(0, 3, enc, &res);
-  ctx = it->top_nz_[x] + it->left_nz_[y];
-  SetResidualCoeffs(levels, &res);
-  R += GetResidualCost(ctx, &res);
-  return R;
-}
-
-int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd) {
-  VP8Residual res;
-  VP8Encoder* const enc = it->enc_;
-  int x, y;
-  int R = 0;
-
-  VP8IteratorNzToBytes(it);   // re-import the non-zero context
-
-  // DC
-  InitResidual(0, 1, enc, &res);
-  SetResidualCoeffs(rd->y_dc_levels, &res);
-  R += GetResidualCost(it->top_nz_[8] + it->left_nz_[8], &res);
-
-  // AC
-  InitResidual(1, 0, enc, &res);
-  for (y = 0; y < 4; ++y) {
-    for (x = 0; x < 4; ++x) {
-      const int ctx = it->top_nz_[x] + it->left_nz_[y];
-      SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
-      R += GetResidualCost(ctx, &res);
-      it->top_nz_[x] = it->left_nz_[y] = (res.last >= 0);
-    }
-  }
-  return R;
-}
-
-int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd) {
-  VP8Residual res;
-  VP8Encoder* const enc = it->enc_;
-  int ch, x, y;
-  int R = 0;
-
-  VP8IteratorNzToBytes(it);  // re-import the non-zero context
-
-  InitResidual(0, 2, enc, &res);
-  for (ch = 0; ch <= 2; ch += 2) {
-    for (y = 0; y < 2; ++y) {
-      for (x = 0; x < 2; ++x) {
-        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
-        SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
-        R += GetResidualCost(ctx, &res);
-        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = (res.last >= 0);
-      }
-    }
-  }
-  return R;
-}
-
-//------------------------------------------------------------------------------
-// Coefficient coding
-
-static int PutCoeffs(VP8BitWriter* const bw, int ctx, const VP8Residual* res) {
-  int n = res->first;
-  const uint8_t* p = res->prob[VP8EncBands[n]][ctx];
-  if (!VP8PutBit(bw, res->last >= 0, p[0])) {
-    return 0;
-  }
-
-  while (n < 16) {
-    const int c = res->coeffs[n++];
-    const int sign = c < 0;
-    int v = sign ? -c : c;
-    if (!VP8PutBit(bw, v != 0, p[1])) {
-      p = res->prob[VP8EncBands[n]][0];
-      continue;
-    }
-    if (!VP8PutBit(bw, v > 1, p[2])) {
-      p = res->prob[VP8EncBands[n]][1];
-    } else {
-      if (!VP8PutBit(bw, v > 4, p[3])) {
-        if (VP8PutBit(bw, v != 2, p[4]))
-          VP8PutBit(bw, v == 4, p[5]);
-      } else if (!VP8PutBit(bw, v > 10, p[6])) {
-        if (!VP8PutBit(bw, v > 6, p[7])) {
-          VP8PutBit(bw, v == 6, 159);
-        } else {
-          VP8PutBit(bw, v >= 9, 165);
-          VP8PutBit(bw, !(v & 1), 145);
-        }
-      } else {
-        int mask;
-        const uint8_t* tab;
-        if (v < 3 + (8 << 1)) {          // kCat3  (3b)
-          VP8PutBit(bw, 0, p[8]);
-          VP8PutBit(bw, 0, p[9]);
-          v -= 3 + (8 << 0);
-          mask = 1 << 2;
-          tab = kCat3;
-        } else if (v < 3 + (8 << 2)) {   // kCat4  (4b)
-          VP8PutBit(bw, 0, p[8]);
-          VP8PutBit(bw, 1, p[9]);
-          v -= 3 + (8 << 1);
-          mask = 1 << 3;
-          tab = kCat4;
-        } else if (v < 3 + (8 << 3)) {   // kCat5  (5b)
-          VP8PutBit(bw, 1, p[8]);
-          VP8PutBit(bw, 0, p[10]);
-          v -= 3 + (8 << 2);
-          mask = 1 << 4;
-          tab = kCat5;
-        } else {                         // kCat6 (11b)
-          VP8PutBit(bw, 1, p[8]);
-          VP8PutBit(bw, 1, p[10]);
-          v -= 3 + (8 << 3);
-          mask = 1 << 10;
-          tab = kCat6;
-        }
-        while (mask) {
-          VP8PutBit(bw, !!(v & mask), *tab++);
-          mask >>= 1;
-        }
-      }
-      p = res->prob[VP8EncBands[n]][2];
-    }
-    VP8PutBitUniform(bw, sign);
-    if (n == 16 || !VP8PutBit(bw, n <= res->last, p[0])) {
-      return 1;   // EOB
-    }
-  }
-  return 1;
-}
-
-static void CodeResiduals(VP8BitWriter* const bw,
-                          VP8EncIterator* const it,
-                          const VP8ModeScore* const rd) {
-  int x, y, ch;
-  VP8Residual res;
-  uint64_t pos1, pos2, pos3;
-  const int i16 = (it->mb_->type_ == 1);
-  const int segment = it->mb_->segment_;
-  VP8Encoder* const enc = it->enc_;
-
-  VP8IteratorNzToBytes(it);
-
-  pos1 = VP8BitWriterPos(bw);
-  if (i16) {
-    InitResidual(0, 1, enc, &res);
-    SetResidualCoeffs(rd->y_dc_levels, &res);
-    it->top_nz_[8] = it->left_nz_[8] =
-      PutCoeffs(bw, it->top_nz_[8] + it->left_nz_[8], &res);
-    InitResidual(1, 0, enc, &res);
-  } else {
-    InitResidual(0, 3, enc, &res);
-  }
-
-  // luma-AC
-  for (y = 0; y < 4; ++y) {
-    for (x = 0; x < 4; ++x) {
-      const int ctx = it->top_nz_[x] + it->left_nz_[y];
-      SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
-      it->top_nz_[x] = it->left_nz_[y] = PutCoeffs(bw, ctx, &res);
-    }
-  }
-  pos2 = VP8BitWriterPos(bw);
-
-  // U/V
-  InitResidual(0, 2, enc, &res);
-  for (ch = 0; ch <= 2; ch += 2) {
-    for (y = 0; y < 2; ++y) {
-      for (x = 0; x < 2; ++x) {
-        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
-        SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
-        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] =
-            PutCoeffs(bw, ctx, &res);
-      }
-    }
-  }
-  pos3 = VP8BitWriterPos(bw);
-  it->luma_bits_ = pos2 - pos1;
-  it->uv_bits_ = pos3 - pos2;
-  it->bit_count_[segment][i16] += it->luma_bits_;
-  it->bit_count_[segment][2] += it->uv_bits_;
-  VP8IteratorBytesToNz(it);
-}
-
-// Same as CodeResiduals, but doesn't actually write anything.
-// Instead, it just records the event distribution.
-static void RecordResiduals(VP8EncIterator* const it,
-                            const VP8ModeScore* const rd) {
-  int x, y, ch;
-  VP8Residual res;
-  VP8Encoder* const enc = it->enc_;
-
-  VP8IteratorNzToBytes(it);
-
-  if (it->mb_->type_ == 1) {   // i16x16
-    InitResidual(0, 1, enc, &res);
-    SetResidualCoeffs(rd->y_dc_levels, &res);
-    it->top_nz_[8] = it->left_nz_[8] =
-      RecordCoeffs(it->top_nz_[8] + it->left_nz_[8], &res);
-    InitResidual(1, 0, enc, &res);
-  } else {
-    InitResidual(0, 3, enc, &res);
-  }
-
-  // luma-AC
-  for (y = 0; y < 4; ++y) {
-    for (x = 0; x < 4; ++x) {
-      const int ctx = it->top_nz_[x] + it->left_nz_[y];
-      SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
-      it->top_nz_[x] = it->left_nz_[y] = RecordCoeffs(ctx, &res);
-    }
-  }
-
-  // U/V
-  InitResidual(0, 2, enc, &res);
-  for (ch = 0; ch <= 2; ch += 2) {
-    for (y = 0; y < 2; ++y) {
-      for (x = 0; x < 2; ++x) {
-        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
-        SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
-        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] =
-            RecordCoeffs(ctx, &res);
-      }
-    }
-  }
-
-  VP8IteratorBytesToNz(it);
-}
-
-//------------------------------------------------------------------------------
-// Token buffer
-
-#ifdef USE_TOKEN_BUFFER
-
-void VP8TBufferInit(VP8TBuffer* const b) {
-  b->rows_ = NULL;
-  b->tokens_ = NULL;
-  b->last_ = &b->rows_;
-  b->left_ = 0;
-  b->error_ = 0;
-}
-
-int VP8TBufferNewPage(VP8TBuffer* const b) {
-  VP8Tokens* const page = b->error_ ? NULL : (VP8Tokens*)malloc(sizeof(*page));
-  if (page == NULL) {
-    b->error_ = 1;
-    return 0;
-  }
-  *b->last_ = page;
-  b->last_ = &page->next_;
-  b->left_ = MAX_NUM_TOKEN;
-  b->tokens_ = page->tokens_;
-  return 1;
-}
-
-void VP8TBufferClear(VP8TBuffer* const b) {
-  if (b != NULL) {
-    const VP8Tokens* p = b->rows_;
-    while (p != NULL) {
-      const VP8Tokens* const next = p->next_;
-      free((void*)p);
-      p = next;
-    }
-    VP8TBufferInit(b);
-  }
-}
-
-int VP8EmitTokens(const VP8TBuffer* const b, VP8BitWriter* const bw,
-                  const uint8_t* const probas) {
-  VP8Tokens* p = b->rows_;
-  if (b->error_) return 0;
-  while (p != NULL) {
-    const int N = (p->next_ == NULL) ? b->left_ : 0;
-    int n = MAX_NUM_TOKEN;
-    while (n-- > N) {
-      VP8PutBit(bw, (p->tokens_[n] >> 15) & 1, probas[p->tokens_[n] & 0x7fff]);
-    }
-    p = p->next_;
-  }
-  return 1;
-}
-
-#define TOKEN_ID(b, ctx, p) ((p) + NUM_PROBAS * ((ctx) + (b) * NUM_CTX))
-
-static int RecordCoeffTokens(int ctx, const VP8Residual* const res,
-                             VP8TBuffer* tokens) {
-  int n = res->first;
-  int b = VP8EncBands[n];
-  if (!VP8AddToken(tokens, res->last >= 0, TOKEN_ID(b, ctx, 0))) {
-    return 0;
-  }
-
-  while (n < 16) {
-    const int c = res->coeffs[n++];
-    const int sign = c < 0;
-    int v = sign ? -c : c;
-    const int base_id = TOKEN_ID(b, ctx, 0);
-    if (!VP8AddToken(tokens, v != 0, base_id + 1)) {
-      b = VP8EncBands[n];
-      ctx = 0;
-      continue;
-    }
-    if (!VP8AddToken(tokens, v > 1, base_id + 2)) {
-      b = VP8EncBands[n];
-      ctx = 1;
-    } else {
-      if (!VP8AddToken(tokens, v > 4, base_id + 3)) {
-        if (VP8AddToken(tokens, v != 2, base_id + 4))
-          VP8AddToken(tokens, v == 4, base_id + 5);
-      } else if (!VP8AddToken(tokens, v > 10, base_id + 6)) {
-        if (!VP8AddToken(tokens, v > 6, base_id + 7)) {
-//          VP8AddToken(tokens, v == 6, 159);
-        } else {
-//          VP8AddToken(tokens, v >= 9, 165);
-//          VP8AddToken(tokens, !(v & 1), 145);
-        }
-      } else {
-        int mask;
-        const uint8_t* tab;
-        if (v < 3 + (8 << 1)) {          // kCat3  (3b)
-          VP8AddToken(tokens, 0, base_id + 8);
-          VP8AddToken(tokens, 0, base_id + 9);
-          v -= 3 + (8 << 0);
-          mask = 1 << 2;
-          tab = kCat3;
-        } else if (v < 3 + (8 << 2)) {   // kCat4  (4b)
-          VP8AddToken(tokens, 0, base_id + 8);
-          VP8AddToken(tokens, 1, base_id + 9);
-          v -= 3 + (8 << 1);
-          mask = 1 << 3;
-          tab = kCat4;
-        } else if (v < 3 + (8 << 3)) {   // kCat5  (5b)
-          VP8AddToken(tokens, 1, base_id + 8);
-          VP8AddToken(tokens, 0, base_id + 10);
-          v -= 3 + (8 << 2);
-          mask = 1 << 4;
-          tab = kCat5;
-        } else {                         // kCat6 (11b)
-          VP8AddToken(tokens, 1, base_id + 8);
-          VP8AddToken(tokens, 1, base_id + 10);
-          v -= 3 + (8 << 3);
-          mask = 1 << 10;
-          tab = kCat6;
-        }
-        while (mask) {
-          // VP8AddToken(tokens, !!(v & mask), *tab++);
-          mask >>= 1;
-        }
-      }
-      ctx = 2;
-    }
-    b = VP8EncBands[n];
-    // VP8PutBitUniform(bw, sign);
-    if (n == 16 || !VP8AddToken(tokens, n <= res->last, TOKEN_ID(b, ctx, 0))) {
-      return 1;   // EOB
-    }
-  }
-  return 1;
-}
-
-static void RecordTokens(VP8EncIterator* const it,
-                         const VP8ModeScore* const rd, VP8TBuffer tokens[2]) {
-  int x, y, ch;
-  VP8Residual res;
-  VP8Encoder* const enc = it->enc_;
-
-  VP8IteratorNzToBytes(it);
-  if (it->mb_->type_ == 1) {   // i16x16
-    InitResidual(0, 1, enc, &res);
-    SetResidualCoeffs(rd->y_dc_levels, &res);
-// TODO(skal): FIX ->    it->top_nz_[8] = it->left_nz_[8] =
-      RecordCoeffTokens(it->top_nz_[8] + it->left_nz_[8], &res, &tokens[0]);
-    InitResidual(1, 0, enc, &res);
-  } else {
-    InitResidual(0, 3, enc, &res);
-  }
-
-  // luma-AC
-  for (y = 0; y < 4; ++y) {
-    for (x = 0; x < 4; ++x) {
-      const int ctx = it->top_nz_[x] + it->left_nz_[y];
-      SetResidualCoeffs(rd->y_ac_levels[x + y * 4], &res);
-      it->top_nz_[x] = it->left_nz_[y] =
-          RecordCoeffTokens(ctx, &res, &tokens[0]);
-    }
-  }
-
-  // U/V
-  InitResidual(0, 2, enc, &res);
-  for (ch = 0; ch <= 2; ch += 2) {
-    for (y = 0; y < 2; ++y) {
-      for (x = 0; x < 2; ++x) {
-        const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
-        SetResidualCoeffs(rd->uv_levels[ch * 2 + x + y * 2], &res);
-        it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] =
-            RecordCoeffTokens(ctx, &res, &tokens[1]);
-      }
-    }
-  }
-}
-
-#endif    // USE_TOKEN_BUFFER
-
-//------------------------------------------------------------------------------
-// ExtraInfo map / Debug function
-
-#if SEGMENT_VISU
-static void SetBlock(uint8_t* p, int value, int size) {
-  int y;
-  for (y = 0; y < size; ++y) {
-    memset(p, value, size);
-    p += BPS;
-  }
-}
-#endif
-
-static void ResetSSE(VP8Encoder* const enc) {
-  memset(enc->sse_, 0, sizeof(enc->sse_));
-  enc->sse_count_ = 0;
-}
-
-static void StoreSSE(const VP8EncIterator* const it) {
-  VP8Encoder* const enc = it->enc_;
-  const uint8_t* const in = it->yuv_in_;
-  const uint8_t* const out = it->yuv_out_;
-  // Note: not totally accurate at boundary. And doesn't include in-loop filter.
-  enc->sse_[0] += VP8SSE16x16(in + Y_OFF, out + Y_OFF);
-  enc->sse_[1] += VP8SSE8x8(in + U_OFF, out + U_OFF);
-  enc->sse_[2] += VP8SSE8x8(in + V_OFF, out + V_OFF);
-  enc->sse_count_ += 16 * 16;
-}
-
-static void StoreSideInfo(const VP8EncIterator* const it) {
-  VP8Encoder* const enc = it->enc_;
-  const VP8MBInfo* const mb = it->mb_;
-  WebPPicture* const pic = enc->pic_;
-
-  if (pic->stats != NULL) {
-    StoreSSE(it);
-    enc->block_count_[0] += (mb->type_ == 0);
-    enc->block_count_[1] += (mb->type_ == 1);
-    enc->block_count_[2] += (mb->skip_ != 0);
-  }
-
-  if (pic->extra_info != NULL) {
-    uint8_t* const info = &pic->extra_info[it->x_ + it->y_ * enc->mb_w_];
-    switch (pic->extra_info_type) {
-      case 1: *info = mb->type_; break;
-      case 2: *info = mb->segment_; break;
-      case 3: *info = enc->dqm_[mb->segment_].quant_; break;
-      case 4: *info = (mb->type_ == 1) ? it->preds_[0] : 0xff; break;
-      case 5: *info = mb->uv_mode_; break;
-      case 6: {
-        const int b = (int)((it->luma_bits_ + it->uv_bits_ + 7) >> 3);
-        *info = (b > 255) ? 255 : b; break;
-      }
-      default: *info = 0; break;
-    };
-  }
-#if SEGMENT_VISU  // visualize segments and prediction modes
-  SetBlock(it->yuv_out_ + Y_OFF, mb->segment_ * 64, 16);
-  SetBlock(it->yuv_out_ + U_OFF, it->preds_[0] * 64, 8);
-  SetBlock(it->yuv_out_ + V_OFF, mb->uv_mode_ * 64, 8);
-#endif
-}
-
-//------------------------------------------------------------------------------
-// Main loops
-//
-//  VP8EncLoop(): does the final bitstream coding.
-
-static void ResetAfterSkip(VP8EncIterator* const it) {
-  if (it->mb_->type_ == 1) {
-    *it->nz_ = 0;  // reset all predictors
-    it->left_nz_[8] = 0;
-  } else {
-    *it->nz_ &= (1 << 24);  // preserve the dc_nz bit
-  }
-}
-
-int VP8EncLoop(VP8Encoder* const enc) {
-  int i, s, p;
-  int ok = 1;
-  VP8EncIterator it;
-  VP8ModeScore info;
-  const int dont_use_skip = !enc->proba_.use_skip_proba_;
-  const int rd_opt = enc->rd_opt_level_;
-  const int kAverageBytesPerMB = 5;     // TODO: have a kTable[quality/10]
-  const int bytes_per_parts =
-    enc->mb_w_ * enc->mb_h_ * kAverageBytesPerMB / enc->num_parts_;
-
-  // Initialize the bit-writers
-  for (p = 0; p < enc->num_parts_; ++p) {
-    VP8BitWriterInit(enc->parts_ + p, bytes_per_parts);
-  }
-
-  ResetStats(enc);
-  ResetSSE(enc);
-
-  VP8IteratorInit(enc, &it);
-  VP8InitFilter(&it);
-  do {
-    VP8IteratorImport(&it);
-    // Warning! order is important: first call VP8Decimate() and
-    // *then* decide how to code the skip decision if there's one.
-    if (!VP8Decimate(&it, &info, rd_opt) || dont_use_skip) {
-      CodeResiduals(it.bw_, &it, &info);
-    } else {   // reset predictors after a skip
-      ResetAfterSkip(&it);
-    }
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-    if (enc->use_layer_) {
-      VP8EncCodeLayerBlock(&it);
-    }
-#endif
-    StoreSideInfo(&it);
-    VP8StoreFilterStats(&it);
-    VP8IteratorExport(&it);
-    ok = VP8IteratorProgress(&it, 20);
-  } while (ok && VP8IteratorNext(&it, it.yuv_out_));
-
-  if (ok) {      // Finalize the partitions, check for extra errors.
-    for (p = 0; p < enc->num_parts_; ++p) {
-      VP8BitWriterFinish(enc->parts_ + p);
-      ok &= !enc->parts_[p].error_;
-    }
-  }
-
-  if (ok) {      // All good. Finish up.
-    if (enc->pic_->stats) {           // finalize byte counters...
-      for (i = 0; i <= 2; ++i) {
-        for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-          enc->residual_bytes_[i][s] = (int)((it.bit_count_[s][i] + 7) >> 3);
-        }
-      }
-    }
-    VP8AdjustFilterStrength(&it);     // ...and store filter stats.
-  } else {
-    // Something bad happened -> need to do some memory cleanup.
-    VP8EncFreeBitWriters(enc);
-  }
-
-  return ok;
-}
-
-//------------------------------------------------------------------------------
-//  VP8StatLoop(): only collect statistics (number of skips, token usage, ...)
-//                 This is used for deciding optimal probabilities. It also
-//                 modifies the quantizer value if some target (size, PNSR)
-//                 was specified.
-
-#define kHeaderSizeEstimate (15 + 20 + 10)      // TODO: fix better
-
-static int OneStatPass(VP8Encoder* const enc, float q, int rd_opt, int nb_mbs,
-                       float* const PSNR, int percent_delta) {
-  VP8EncIterator it;
-  uint64_t size = 0;
-  uint64_t distortion = 0;
-  const uint64_t pixel_count = nb_mbs * 384;
-
-  // Make sure the quality parameter is inside valid bounds
-  if (q < 0.) {
-    q = 0;
-  } else if (q > 100.) {
-    q = 100;
-  }
-
-  VP8SetSegmentParams(enc, q);      // setup segment quantizations and filters
-
-  ResetStats(enc);
-  ResetTokenStats(enc);
-
-  VP8IteratorInit(enc, &it);
-  do {
-    VP8ModeScore info;
-    VP8IteratorImport(&it);
-    if (VP8Decimate(&it, &info, rd_opt)) {
-      // Just record the number of skips and act like skip_proba is not used.
-      enc->proba_.nb_skip_++;
-    }
-    RecordResiduals(&it, &info);
-    size += info.R;
-    distortion += info.D;
-    if (percent_delta && !VP8IteratorProgress(&it, percent_delta))
-      return 0;
-  } while (VP8IteratorNext(&it, it.yuv_out_) && --nb_mbs > 0);
-  size += FinalizeSkipProba(enc);
-  size += FinalizeTokenProbas(enc);
-  size += enc->segment_hdr_.size_;
-  size = ((size + 1024) >> 11) + kHeaderSizeEstimate;
-
-  if (PSNR) {
-    *PSNR = (float)(10.* log10(255. * 255. * pixel_count / distortion));
-  }
-  return (int)size;
-}
-
-// successive refinement increments.
-static const int dqs[] = { 20, 15, 10, 8, 6, 4, 2, 1, 0 };
-
-int VP8StatLoop(VP8Encoder* const enc) {
-  const int do_search =
-    (enc->config_->target_size > 0 || enc->config_->target_PSNR > 0);
-  const int fast_probe = (enc->method_ < 2 && !do_search);
-  float q = enc->config_->quality;
-  const int max_passes = enc->config_->pass;
-  const int task_percent = 20;
-  const int percent_per_pass = (task_percent + max_passes / 2) / max_passes;
-  const int final_percent = enc->percent_ + task_percent;
-  int pass;
-  int nb_mbs;
-
-  // Fast mode: quick analysis pass over few mbs. Better than nothing.
-  nb_mbs = enc->mb_w_ * enc->mb_h_;
-  if (fast_probe && nb_mbs > 100) nb_mbs = 100;
-
-  // No target size: just do several pass without changing 'q'
-  if (!do_search) {
-    for (pass = 0; pass < max_passes; ++pass) {
-      const int rd_opt = (enc->method_ > 2);
-      if (!OneStatPass(enc, q, rd_opt, nb_mbs, NULL, percent_per_pass)) {
-        return 0;
-      }
-    }
-  } else {
-    // binary search for a size close to target
-    for (pass = 0; pass < max_passes && (dqs[pass] > 0); ++pass) {
-      const int rd_opt = 1;
-      float PSNR;
-      int criterion;
-      const int size = OneStatPass(enc, q, rd_opt, nb_mbs, &PSNR,
-                                   percent_per_pass);
-#if DEBUG_SEARCH
-      printf("#%d size=%d PSNR=%.2f q=%.2f\n", pass, size, PSNR, q);
-#endif
-      if (!size) return 0;
-      if (enc->config_->target_PSNR > 0) {
-        criterion = (PSNR < enc->config_->target_PSNR);
-      } else {
-        criterion = (size < enc->config_->target_size);
-      }
-      // dichotomize
-      if (criterion) {
-        q += dqs[pass];
-      } else {
-        q -= dqs[pass];
-      }
-    }
-  }
-  return WebPReportProgress(enc->pic_, final_percent, &enc->percent_);
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 406
drivers/webpold/enc/histogram.c

@@ -1,406 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Author: Jyrki Alakuijala ([email protected])
-//
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <math.h>
-#include <stdio.h>
-
-#include "./backward_references.h"
-#include "./histogram.h"
-#include "../dsp/lossless.h"
-#include "../utils/utils.h"
-
-static void HistogramClear(VP8LHistogram* const p) {
-  memset(p->literal_, 0, sizeof(p->literal_));
-  memset(p->red_, 0, sizeof(p->red_));
-  memset(p->blue_, 0, sizeof(p->blue_));
-  memset(p->alpha_, 0, sizeof(p->alpha_));
-  memset(p->distance_, 0, sizeof(p->distance_));
-  p->bit_cost_ = 0;
-}
-
-void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs,
-                            VP8LHistogram* const histo) {
-  int i;
-  for (i = 0; i < refs->size; ++i) {
-    VP8LHistogramAddSinglePixOrCopy(histo, &refs->refs[i]);
-  }
-}
-
-void VP8LHistogramCreate(VP8LHistogram* const p,
-                         const VP8LBackwardRefs* const refs,
-                         int palette_code_bits) {
-  if (palette_code_bits >= 0) {
-    p->palette_code_bits_ = palette_code_bits;
-  }
-  HistogramClear(p);
-  VP8LHistogramStoreRefs(refs, p);
-}
-
-void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits) {
-  p->palette_code_bits_ = palette_code_bits;
-  HistogramClear(p);
-}
-
-VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) {
-  int i;
-  VP8LHistogramSet* set;
-  VP8LHistogram* bulk;
-  const uint64_t total_size = (uint64_t)sizeof(*set)
-                            + size * sizeof(*set->histograms)
-                            + size * sizeof(**set->histograms);
-  uint8_t* memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory));
-  if (memory == NULL) return NULL;
-
-  set = (VP8LHistogramSet*)memory;
-  memory += sizeof(*set);
-  set->histograms = (VP8LHistogram**)memory;
-  memory += size * sizeof(*set->histograms);
-  bulk = (VP8LHistogram*)memory;
-  set->max_size = size;
-  set->size = size;
-  for (i = 0; i < size; ++i) {
-    set->histograms[i] = bulk + i;
-    VP8LHistogramInit(set->histograms[i], cache_bits);
-  }
-  return set;
-}
-
-// -----------------------------------------------------------------------------
-
-void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
-                                     const PixOrCopy* const v) {
-  if (PixOrCopyIsLiteral(v)) {
-    ++histo->alpha_[PixOrCopyLiteral(v, 3)];
-    ++histo->red_[PixOrCopyLiteral(v, 2)];
-    ++histo->literal_[PixOrCopyLiteral(v, 1)];
-    ++histo->blue_[PixOrCopyLiteral(v, 0)];
-  } else if (PixOrCopyIsCacheIdx(v)) {
-    int literal_ix = 256 + NUM_LENGTH_CODES + PixOrCopyCacheIdx(v);
-    ++histo->literal_[literal_ix];
-  } else {
-    int code, extra_bits_count, extra_bits_value;
-    PrefixEncode(PixOrCopyLength(v),
-                 &code, &extra_bits_count, &extra_bits_value);
-    ++histo->literal_[256 + code];
-    PrefixEncode(PixOrCopyDistance(v),
-                 &code, &extra_bits_count, &extra_bits_value);
-    ++histo->distance_[code];
-  }
-}
-
-
-
-static double BitsEntropy(const int* const array, int n) {
-  double retval = 0.;
-  int sum = 0;
-  int nonzeros = 0;
-  int max_val = 0;
-  int i;
-  double mix;
-  for (i = 0; i < n; ++i) {
-    if (array[i] != 0) {
-      sum += array[i];
-      ++nonzeros;
-      retval -= VP8LFastSLog2(array[i]);
-      if (max_val < array[i]) {
-        max_val = array[i];
-      }
-    }
-  }
-  retval += VP8LFastSLog2(sum);
-
-  if (nonzeros < 5) {
-    if (nonzeros <= 1) {
-      return 0;
-    }
-    // Two symbols, they will be 0 and 1 in a Huffman code.
-    // Let's mix in a bit of entropy to favor good clustering when
-    // distributions of these are combined.
-    if (nonzeros == 2) {
-      return 0.99 * sum + 0.01 * retval;
-    }
-    // No matter what the entropy says, we cannot be better than min_limit
-    // with Huffman coding. I am mixing a bit of entropy into the
-    // min_limit since it produces much better (~0.5 %) compression results
-    // perhaps because of better entropy clustering.
-    if (nonzeros == 3) {
-      mix = 0.95;
-    } else {
-      mix = 0.7;  // nonzeros == 4.
-    }
-  } else {
-    mix = 0.627;
-  }
-
-  {
-    double min_limit = 2 * sum - max_val;
-    min_limit = mix * min_limit + (1.0 - mix) * retval;
-    return (retval < min_limit) ? min_limit : retval;
-  }
-}
-
-double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p) {
-  double retval = BitsEntropy(&p->literal_[0], VP8LHistogramNumCodes(p))
-                + BitsEntropy(&p->red_[0], 256)
-                + BitsEntropy(&p->blue_[0], 256)
-                + BitsEntropy(&p->alpha_[0], 256)
-                + BitsEntropy(&p->distance_[0], NUM_DISTANCE_CODES);
-  // Compute the extra bits cost.
-  int i;
-  for (i = 2; i < NUM_LENGTH_CODES - 2; ++i) {
-    retval +=
-        (i >> 1) * p->literal_[256 + i + 2];
-  }
-  for (i = 2; i < NUM_DISTANCE_CODES - 2; ++i) {
-    retval += (i >> 1) * p->distance_[i + 2];
-  }
-  return retval;
-}
-
-
-// Returns the cost encode the rle-encoded entropy code.
-// The constants in this function are experimental.
-static double HuffmanCost(const int* const population, int length) {
-  // Small bias because Huffman code length is typically not stored in
-  // full length.
-  static const int kHuffmanCodeOfHuffmanCodeSize = CODE_LENGTH_CODES * 3;
-  static const double kSmallBias = 9.1;
-  double retval = kHuffmanCodeOfHuffmanCodeSize - kSmallBias;
-  int streak = 0;
-  int i = 0;
-  for (; i < length - 1; ++i) {
-    ++streak;
-    if (population[i] == population[i + 1]) {
-      continue;
-    }
- last_streak_hack:
-    // population[i] points now to the symbol in the streak of same values.
-    if (streak > 3) {
-      if (population[i] == 0) {
-        retval += 1.5625 + 0.234375 * streak;
-      } else {
-        retval += 2.578125 + 0.703125 * streak;
-      }
-    } else {
-      if (population[i] == 0) {
-        retval += 1.796875 * streak;
-      } else {
-        retval += 3.28125 * streak;
-      }
-    }
-    streak = 0;
-  }
-  if (i == length - 1) {
-    ++streak;
-    goto last_streak_hack;
-  }
-  return retval;
-}
-
-// Estimates the Huffman dictionary + other block overhead size.
-static double HistogramEstimateBitsHeader(const VP8LHistogram* const p) {
-  return HuffmanCost(&p->alpha_[0], 256) +
-         HuffmanCost(&p->red_[0], 256) +
-         HuffmanCost(&p->literal_[0], VP8LHistogramNumCodes(p)) +
-         HuffmanCost(&p->blue_[0], 256) +
-         HuffmanCost(&p->distance_[0], NUM_DISTANCE_CODES);
-}
-
-double VP8LHistogramEstimateBits(const VP8LHistogram* const p) {
-  return HistogramEstimateBitsHeader(p) + VP8LHistogramEstimateBitsBulk(p);
-}
-
-static void HistogramBuildImage(int xsize, int histo_bits,
-                                const VP8LBackwardRefs* const backward_refs,
-                                VP8LHistogramSet* const image) {
-  int i;
-  int x = 0, y = 0;
-  const int histo_xsize = VP8LSubSampleSize(xsize, histo_bits);
-  VP8LHistogram** const histograms = image->histograms;
-  assert(histo_bits > 0);
-  for (i = 0; i < backward_refs->size; ++i) {
-    const PixOrCopy* const v = &backward_refs->refs[i];
-    const int ix = (y >> histo_bits) * histo_xsize + (x >> histo_bits);
-    VP8LHistogramAddSinglePixOrCopy(histograms[ix], v);
-    x += PixOrCopyLength(v);
-    while (x >= xsize) {
-      x -= xsize;
-      ++y;
-    }
-  }
-}
-
-static uint32_t MyRand(uint32_t *seed) {
-  *seed *= 16807U;
-  if (*seed == 0) {
-    *seed = 1;
-  }
-  return *seed;
-}
-
-static int HistogramCombine(const VP8LHistogramSet* const in,
-                            VP8LHistogramSet* const out, int num_pairs) {
-  int ok = 0;
-  int i, iter;
-  uint32_t seed = 0;
-  int tries_with_no_success = 0;
-  const int min_cluster_size = 2;
-  int out_size = in->size;
-  const int outer_iters = in->size * 3;
-  VP8LHistogram* const histos = (VP8LHistogram*)malloc(2 * sizeof(*histos));
-  VP8LHistogram* cur_combo = histos + 0;    // trial merged histogram
-  VP8LHistogram* best_combo = histos + 1;   // best merged histogram so far
-  if (histos == NULL) goto End;
-
-  // Copy histograms from in[] to out[].
-  assert(in->size <= out->size);
-  for (i = 0; i < in->size; ++i) {
-    in->histograms[i]->bit_cost_ = VP8LHistogramEstimateBits(in->histograms[i]);
-    *out->histograms[i] = *in->histograms[i];
-  }
-
-  // Collapse similar histograms in 'out'.
-  for (iter = 0; iter < outer_iters && out_size >= min_cluster_size; ++iter) {
-    // We pick the best pair to be combined out of 'inner_iters' pairs.
-    double best_cost_diff = 0.;
-    int best_idx1 = 0, best_idx2 = 1;
-    int j;
-    seed += iter;
-    for (j = 0; j < num_pairs; ++j) {
-      double curr_cost_diff;
-      // Choose two histograms at random and try to combine them.
-      const uint32_t idx1 = MyRand(&seed) % out_size;
-      const uint32_t tmp = ((j & 7) + 1) % (out_size - 1);
-      const uint32_t diff = (tmp < 3) ? tmp : MyRand(&seed) % (out_size - 1);
-      const uint32_t idx2 = (idx1 + diff + 1) % out_size;
-      if (idx1 == idx2) {
-        continue;
-      }
-      *cur_combo = *out->histograms[idx1];
-      VP8LHistogramAdd(cur_combo, out->histograms[idx2]);
-      cur_combo->bit_cost_ = VP8LHistogramEstimateBits(cur_combo);
-      // Calculate cost reduction on combining.
-      curr_cost_diff = cur_combo->bit_cost_
-                     - out->histograms[idx1]->bit_cost_
-                     - out->histograms[idx2]->bit_cost_;
-      if (best_cost_diff > curr_cost_diff) {    // found a better pair?
-        {     // swap cur/best combo histograms
-          VP8LHistogram* const tmp_histo = cur_combo;
-          cur_combo = best_combo;
-          best_combo = tmp_histo;
-        }
-        best_cost_diff = curr_cost_diff;
-        best_idx1 = idx1;
-        best_idx2 = idx2;
-      }
-    }
-
-    if (best_cost_diff < 0.0) {
-      *out->histograms[best_idx1] = *best_combo;
-      // swap best_idx2 slot with last one (which is now unused)
-      --out_size;
-      if (best_idx2 != out_size) {
-        out->histograms[best_idx2] = out->histograms[out_size];
-        out->histograms[out_size] = NULL;   // just for sanity check.
-      }
-      tries_with_no_success = 0;
-    }
-    if (++tries_with_no_success >= 50) {
-      break;
-    }
-  }
-  out->size = out_size;
-  ok = 1;
-
- End:
-  free(histos);
-  return ok;
-}
-
-// -----------------------------------------------------------------------------
-// Histogram refinement
-
-// What is the bit cost of moving square_histogram from
-// cur_symbol to candidate_symbol.
-// TODO(skal): we don't really need to copy the histogram and Add(). Instead
-// we just need VP8LDualHistogramEstimateBits(A, B) estimation function.
-static double HistogramDistance(const VP8LHistogram* const square_histogram,
-                                const VP8LHistogram* const candidate) {
-  const double previous_bit_cost = candidate->bit_cost_;
-  double new_bit_cost;
-  VP8LHistogram modified_histo;
-  modified_histo = *candidate;
-  VP8LHistogramAdd(&modified_histo, square_histogram);
-  new_bit_cost = VP8LHistogramEstimateBits(&modified_histo);
-
-  return new_bit_cost - previous_bit_cost;
-}
-
-// Find the best 'out' histogram for each of the 'in' histograms.
-// Note: we assume that out[]->bit_cost_ is already up-to-date.
-static void HistogramRemap(const VP8LHistogramSet* const in,
-                           const VP8LHistogramSet* const out,
-                           uint16_t* const symbols) {
-  int i;
-  for (i = 0; i < in->size; ++i) {
-    int best_out = 0;
-    double best_bits = HistogramDistance(in->histograms[i], out->histograms[0]);
-    int k;
-    for (k = 1; k < out->size; ++k) {
-      const double cur_bits =
-          HistogramDistance(in->histograms[i], out->histograms[k]);
-      if (cur_bits < best_bits) {
-        best_bits = cur_bits;
-        best_out = k;
-      }
-    }
-    symbols[i] = best_out;
-  }
-
-  // Recompute each out based on raw and symbols.
-  for (i = 0; i < out->size; ++i) {
-    HistogramClear(out->histograms[i]);
-  }
-  for (i = 0; i < in->size; ++i) {
-    VP8LHistogramAdd(out->histograms[symbols[i]], in->histograms[i]);
-  }
-}
-
-int VP8LGetHistoImageSymbols(int xsize, int ysize,
-                             const VP8LBackwardRefs* const refs,
-                             int quality, int histo_bits, int cache_bits,
-                             VP8LHistogramSet* const image_in,
-                             uint16_t* const histogram_symbols) {
-  int ok = 0;
-  const int histo_xsize = histo_bits ? VP8LSubSampleSize(xsize, histo_bits) : 1;
-  const int histo_ysize = histo_bits ? VP8LSubSampleSize(ysize, histo_bits) : 1;
-  const int num_histo_pairs = 10 + quality / 2;  // For HistogramCombine().
-  const int histo_image_raw_size = histo_xsize * histo_ysize;
-  VP8LHistogramSet* const image_out =
-      VP8LAllocateHistogramSet(histo_image_raw_size, cache_bits);
-  if (image_out == NULL) return 0;
-
-  // Build histogram image.
-  HistogramBuildImage(xsize, histo_bits, refs, image_out);
-  // Collapse similar histograms.
-  if (!HistogramCombine(image_out, image_in, num_histo_pairs)) {
-    goto Error;
-  }
-  // Find the optimal map from original histograms to the final ones.
-  HistogramRemap(image_out, image_in, histogram_symbols);
-  ok = 1;
-
-Error:
-  free(image_out);
-  return ok;
-}

+ 0 - 115
drivers/webpold/enc/histogram.h

@@ -1,115 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Author: Jyrki Alakuijala ([email protected])
-//
-// Models the histograms of literal and distance codes.
-
-#ifndef WEBP_ENC_HISTOGRAM_H_
-#define WEBP_ENC_HISTOGRAM_H_
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "./backward_references.h"
-#include "../format_constants.h"
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// A simple container for histograms of data.
-typedef struct {
-  // literal_ contains green literal, palette-code and
-  // copy-length-prefix histogram
-  int literal_[PIX_OR_COPY_CODES_MAX];
-  int red_[256];
-  int blue_[256];
-  int alpha_[256];
-  // Backward reference prefix-code histogram.
-  int distance_[NUM_DISTANCE_CODES];
-  int palette_code_bits_;
-  double bit_cost_;   // cached value of VP8LHistogramEstimateBits(this)
-} VP8LHistogram;
-
-// Collection of histograms with fixed capacity, allocated as one
-// big memory chunk. Can be destroyed by simply calling 'free()'.
-typedef struct {
-  int size;         // number of slots currently in use
-  int max_size;     // maximum capacity
-  VP8LHistogram** histograms;
-} VP8LHistogramSet;
-
-// Create the histogram.
-//
-// The input data is the PixOrCopy data, which models the literals, stop
-// codes and backward references (both distances and lengths).  Also: if
-// palette_code_bits is >= 0, initialize the histogram with this value.
-void VP8LHistogramCreate(VP8LHistogram* const p,
-                         const VP8LBackwardRefs* const refs,
-                         int palette_code_bits);
-
-// Set the palette_code_bits and reset the stats.
-void VP8LHistogramInit(VP8LHistogram* const p, int palette_code_bits);
-
-// Collect all the references into a histogram (without reset)
-void VP8LHistogramStoreRefs(const VP8LBackwardRefs* const refs,
-                            VP8LHistogram* const histo);
-
-// Allocate an array of pointer to histograms, allocated and initialized
-// using 'cache_bits'. Return NULL in case of memory error.
-VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits);
-
-// Accumulate a token 'v' into a histogram.
-void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
-                                     const PixOrCopy* const v);
-
-// Estimate how many bits the combined entropy of literals and distance
-// approximately maps to.
-double VP8LHistogramEstimateBits(const VP8LHistogram* const p);
-
-// This function estimates the cost in bits excluding the bits needed to
-// represent the entropy code itself.
-double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p);
-
-static WEBP_INLINE void VP8LHistogramAdd(VP8LHistogram* const p,
-                                         const VP8LHistogram* const a) {
-  int i;
-  for (i = 0; i < PIX_OR_COPY_CODES_MAX; ++i) {
-    p->literal_[i] += a->literal_[i];
-  }
-  for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
-    p->distance_[i] += a->distance_[i];
-  }
-  for (i = 0; i < 256; ++i) {
-    p->red_[i] += a->red_[i];
-    p->blue_[i] += a->blue_[i];
-    p->alpha_[i] += a->alpha_[i];
-  }
-}
-
-static WEBP_INLINE int VP8LHistogramNumCodes(const VP8LHistogram* const p) {
-  return 256 + NUM_LENGTH_CODES +
-      ((p->palette_code_bits_ > 0) ? (1 << p->palette_code_bits_) : 0);
-}
-
-// Builds the histogram image.
-int VP8LGetHistoImageSymbols(int xsize, int ysize,
-                             const VP8LBackwardRefs* const refs,
-                             int quality, int histogram_bits, int cache_bits,
-                             VP8LHistogramSet* const image_in,
-                             uint16_t* const histogram_symbols);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif  // WEBP_ENC_HISTOGRAM_H_

+ 0 - 422
drivers/webpold/enc/iterator.c

@@ -1,422 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// VP8Iterator: block iterator
-//
-// Author: Skal ([email protected])
-
-#include <string.h>
-
-#include "./vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// VP8Iterator
-//------------------------------------------------------------------------------
-
-static void InitLeft(VP8EncIterator* const it) {
-  const VP8Encoder* const enc = it->enc_;
-  enc->y_left_[-1] = enc->u_left_[-1] = enc->v_left_[-1] =
-      (it->y_ > 0) ? 129 : 127;
-  memset(enc->y_left_, 129, 16);
-  memset(enc->u_left_, 129, 8);
-  memset(enc->v_left_, 129, 8);
-  it->left_nz_[8] = 0;
-}
-
-static void InitTop(VP8EncIterator* const it) {
-  const VP8Encoder* const enc = it->enc_;
-  const size_t top_size = enc->mb_w_ * 16;
-  memset(enc->y_top_, 127, 2 * top_size);
-  memset(enc->nz_, 0, enc->mb_w_ * sizeof(*enc->nz_));
-}
-
-void VP8IteratorReset(VP8EncIterator* const it) {
-  VP8Encoder* const enc = it->enc_;
-  it->x_ = 0;
-  it->y_ = 0;
-  it->y_offset_ = 0;
-  it->uv_offset_ = 0;
-  it->mb_ = enc->mb_info_;
-  it->preds_ = enc->preds_;
-  it->nz_ = enc->nz_;
-  it->bw_ = &enc->parts_[0];
-  it->done_ = enc->mb_w_* enc->mb_h_;
-  InitTop(it);
-  InitLeft(it);
-  memset(it->bit_count_, 0, sizeof(it->bit_count_));
-  it->do_trellis_ = 0;
-}
-
-void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it) {
-  it->enc_ = enc;
-  it->y_stride_  = enc->pic_->y_stride;
-  it->uv_stride_ = enc->pic_->uv_stride;
-  // TODO(later): for multithreading, these should be owned by 'it'.
-  it->yuv_in_   = enc->yuv_in_;
-  it->yuv_out_  = enc->yuv_out_;
-  it->yuv_out2_ = enc->yuv_out2_;
-  it->yuv_p_    = enc->yuv_p_;
-  it->lf_stats_ = enc->lf_stats_;
-  it->percent0_ = enc->percent_;
-  VP8IteratorReset(it);
-}
-
-int VP8IteratorProgress(const VP8EncIterator* const it, int delta) {
-  VP8Encoder* const enc = it->enc_;
-  if (delta && enc->pic_->progress_hook) {
-    const int percent = (enc->mb_h_ <= 1)
-                      ? it->percent0_
-                      : it->percent0_ + delta * it->y_ / (enc->mb_h_ - 1);
-    return WebPReportProgress(enc->pic_, percent, &enc->percent_);
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Import the source samples into the cache. Takes care of replicating
-// boundary pixels if necessary.
-
-static void ImportBlock(const uint8_t* src, int src_stride,
-                        uint8_t* dst, int w, int h, int size) {
-  int i;
-  for (i = 0; i < h; ++i) {
-    memcpy(dst, src, w);
-    if (w < size) {
-      memset(dst + w, dst[w - 1], size - w);
-    }
-    dst += BPS;
-    src += src_stride;
-  }
-  for (i = h; i < size; ++i) {
-    memcpy(dst, dst - BPS, size);
-    dst += BPS;
-  }
-}
-
-void VP8IteratorImport(const VP8EncIterator* const it) {
-  const VP8Encoder* const enc = it->enc_;
-  const int x = it->x_, y = it->y_;
-  const WebPPicture* const pic = enc->pic_;
-  const uint8_t* const ysrc = pic->y + (y * pic->y_stride + x) * 16;
-  const uint8_t* const usrc = pic->u + (y * pic->uv_stride + x) * 8;
-  const uint8_t* const vsrc = pic->v + (y * pic->uv_stride + x) * 8;
-  uint8_t* const ydst = it->yuv_in_ + Y_OFF;
-  uint8_t* const udst = it->yuv_in_ + U_OFF;
-  uint8_t* const vdst = it->yuv_in_ + V_OFF;
-  int w = (pic->width - x * 16);
-  int h = (pic->height - y * 16);
-
-  if (w > 16) w = 16;
-  if (h > 16) h = 16;
-
-  // Luma plane
-  ImportBlock(ysrc, pic->y_stride, ydst, w, h, 16);
-
-  {   // U/V planes
-    const int uv_w = (w + 1) >> 1;
-    const int uv_h = (h + 1) >> 1;
-    ImportBlock(usrc, pic->uv_stride, udst, uv_w, uv_h, 8);
-    ImportBlock(vsrc, pic->uv_stride, vdst, uv_w, uv_h, 8);
-  }
-}
-
-//------------------------------------------------------------------------------
-// Copy back the compressed samples into user space if requested.
-
-static void ExportBlock(const uint8_t* src, uint8_t* dst, int dst_stride,
-                        int w, int h) {
-  while (h-- > 0) {
-    memcpy(dst, src, w);
-    dst += dst_stride;
-    src += BPS;
-  }
-}
-
-void VP8IteratorExport(const VP8EncIterator* const it) {
-  const VP8Encoder* const enc = it->enc_;
-  if (enc->config_->show_compressed) {
-    const int x = it->x_, y = it->y_;
-    const uint8_t* const ysrc = it->yuv_out_ + Y_OFF;
-    const uint8_t* const usrc = it->yuv_out_ + U_OFF;
-    const uint8_t* const vsrc = it->yuv_out_ + V_OFF;
-    const WebPPicture* const pic = enc->pic_;
-    uint8_t* const ydst = pic->y + (y * pic->y_stride + x) * 16;
-    uint8_t* const udst = pic->u + (y * pic->uv_stride + x) * 8;
-    uint8_t* const vdst = pic->v + (y * pic->uv_stride + x) * 8;
-    int w = (pic->width - x * 16);
-    int h = (pic->height - y * 16);
-
-    if (w > 16) w = 16;
-    if (h > 16) h = 16;
-
-    // Luma plane
-    ExportBlock(ysrc, ydst, pic->y_stride, w, h);
-
-    {   // U/V planes
-      const int uv_w = (w + 1) >> 1;
-      const int uv_h = (h + 1) >> 1;
-      ExportBlock(usrc, udst, pic->uv_stride, uv_w, uv_h);
-      ExportBlock(vsrc, vdst, pic->uv_stride, uv_w, uv_h);
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// Non-zero contexts setup/teardown
-
-// Nz bits:
-//  0  1  2  3  Y
-//  4  5  6  7
-//  8  9 10 11
-// 12 13 14 15
-// 16 17        U
-// 18 19
-// 20 21        V
-// 22 23
-// 24           DC-intra16
-
-// Convert packed context to byte array
-#define BIT(nz, n) (!!((nz) & (1 << (n))))
-
-void VP8IteratorNzToBytes(VP8EncIterator* const it) {
-  const int tnz = it->nz_[0], lnz = it->nz_[-1];
-  int* const top_nz = it->top_nz_;
-  int* const left_nz = it->left_nz_;
-
-  // Top-Y
-  top_nz[0] = BIT(tnz, 12);
-  top_nz[1] = BIT(tnz, 13);
-  top_nz[2] = BIT(tnz, 14);
-  top_nz[3] = BIT(tnz, 15);
-  // Top-U
-  top_nz[4] = BIT(tnz, 18);
-  top_nz[5] = BIT(tnz, 19);
-  // Top-V
-  top_nz[6] = BIT(tnz, 22);
-  top_nz[7] = BIT(tnz, 23);
-  // DC
-  top_nz[8] = BIT(tnz, 24);
-
-  // left-Y
-  left_nz[0] = BIT(lnz,  3);
-  left_nz[1] = BIT(lnz,  7);
-  left_nz[2] = BIT(lnz, 11);
-  left_nz[3] = BIT(lnz, 15);
-  // left-U
-  left_nz[4] = BIT(lnz, 17);
-  left_nz[5] = BIT(lnz, 19);
-  // left-V
-  left_nz[6] = BIT(lnz, 21);
-  left_nz[7] = BIT(lnz, 23);
-  // left-DC is special, iterated separately
-}
-
-void VP8IteratorBytesToNz(VP8EncIterator* const it) {
-  uint32_t nz = 0;
-  const int* const top_nz = it->top_nz_;
-  const int* const left_nz = it->left_nz_;
-  // top
-  nz |= (top_nz[0] << 12) | (top_nz[1] << 13);
-  nz |= (top_nz[2] << 14) | (top_nz[3] << 15);
-  nz |= (top_nz[4] << 18) | (top_nz[5] << 19);
-  nz |= (top_nz[6] << 22) | (top_nz[7] << 23);
-  nz |= (top_nz[8] << 24);  // we propagate the _top_ bit, esp. for intra4
-  // left
-  nz |= (left_nz[0] << 3) | (left_nz[1] << 7);
-  nz |= (left_nz[2] << 11);
-  nz |= (left_nz[4] << 17) | (left_nz[6] << 21);
-
-  *it->nz_ = nz;
-}
-
-#undef BIT
-
-//------------------------------------------------------------------------------
-// Advance to the next position, doing the bookeeping.
-
-int VP8IteratorNext(VP8EncIterator* const it,
-                    const uint8_t* const block_to_save) {
-  VP8Encoder* const enc = it->enc_;
-  if (block_to_save) {
-    const int x = it->x_, y = it->y_;
-    const uint8_t* const ysrc = block_to_save + Y_OFF;
-    const uint8_t* const usrc = block_to_save + U_OFF;
-    if (x < enc->mb_w_ - 1) {   // left
-      int i;
-      for (i = 0; i < 16; ++i) {
-        enc->y_left_[i] = ysrc[15 + i * BPS];
-      }
-      for (i = 0; i < 8; ++i) {
-        enc->u_left_[i] = usrc[7 + i * BPS];
-        enc->v_left_[i] = usrc[15 + i * BPS];
-      }
-      // top-left (before 'top'!)
-      enc->y_left_[-1] = enc->y_top_[x * 16 + 15];
-      enc->u_left_[-1] = enc->uv_top_[x * 16 + 0 + 7];
-      enc->v_left_[-1] = enc->uv_top_[x * 16 + 8 + 7];
-    }
-    if (y < enc->mb_h_ - 1) {  // top
-      memcpy(enc->y_top_ + x * 16, ysrc + 15 * BPS, 16);
-      memcpy(enc->uv_top_ + x * 16, usrc + 7 * BPS, 8 + 8);
-    }
-  }
-
-  it->mb_++;
-  it->preds_ += 4;
-  it->nz_++;
-  it->x_++;
-  if (it->x_ == enc->mb_w_) {
-    it->x_ = 0;
-    it->y_++;
-    it->bw_ = &enc->parts_[it->y_ & (enc->num_parts_ - 1)];
-    it->preds_ = enc->preds_ + it->y_ * 4 * enc->preds_w_;
-    it->nz_ = enc->nz_;
-    InitLeft(it);
-  }
-  return (0 < --it->done_);
-}
-
-//------------------------------------------------------------------------------
-// Helper function to set mode properties
-
-void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode) {
-  uint8_t* preds = it->preds_;
-  int y;
-  for (y = 0; y < 4; ++y) {
-    memset(preds, mode, 4);
-    preds += it->enc_->preds_w_;
-  }
-  it->mb_->type_ = 1;
-}
-
-void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes) {
-  uint8_t* preds = it->preds_;
-  int y;
-  for (y = 4; y > 0; --y) {
-    memcpy(preds, modes, 4 * sizeof(*modes));
-    preds += it->enc_->preds_w_;
-    modes += 4;
-  }
-  it->mb_->type_ = 0;
-}
-
-void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode) {
-  it->mb_->uv_mode_ = mode;
-}
-
-void VP8SetSkip(const VP8EncIterator* const it, int skip) {
-  it->mb_->skip_ = skip;
-}
-
-void VP8SetSegment(const VP8EncIterator* const it, int segment) {
-  it->mb_->segment_ = segment;
-}
-
-//------------------------------------------------------------------------------
-// Intra4x4 sub-blocks iteration
-//
-//  We store and update the boundary samples into an array of 37 pixels. They
-//  are updated as we iterate and reconstructs each intra4x4 blocks in turn.
-//  The position of the samples has the following snake pattern:
-//
-// 16|17 18 19 20|21 22 23 24|25 26 27 28|29 30 31 32|33 34 35 36  <- Top-right
-// --+-----------+-----------+-----------+-----------+
-// 15|         19|         23|         27|         31|
-// 14|         18|         22|         26|         30|
-// 13|         17|         21|         25|         29|
-// 12|13 14 15 16|17 18 19 20|21 22 23 24|25 26 27 28|
-// --+-----------+-----------+-----------+-----------+
-// 11|         15|         19|         23|         27|
-// 10|         14|         18|         22|         26|
-//  9|         13|         17|         21|         25|
-//  8| 9 10 11 12|13 14 15 16|17 18 19 20|21 22 23 24|
-// --+-----------+-----------+-----------+-----------+
-//  7|         11|         15|         19|         23|
-//  6|         10|         14|         18|         22|
-//  5|          9|         13|         17|         21|
-//  4| 5  6  7  8| 9 10 11 12|13 14 15 16|17 18 19 20|
-// --+-----------+-----------+-----------+-----------+
-//  3|          7|         11|         15|         19|
-//  2|          6|         10|         14|         18|
-//  1|          5|          9|         13|         17|
-//  0| 1  2  3  4| 5  6  7  8| 9 10 11 12|13 14 15 16|
-// --+-----------+-----------+-----------+-----------+
-
-// Array to record the position of the top sample to pass to the prediction
-// functions in dsp.c.
-static const uint8_t VP8TopLeftI4[16] = {
-  17, 21, 25, 29,
-  13, 17, 21, 25,
-  9,  13, 17, 21,
-  5,   9, 13, 17
-};
-
-void VP8IteratorStartI4(VP8EncIterator* const it) {
-  const VP8Encoder* const enc = it->enc_;
-  int i;
-
-  it->i4_ = 0;    // first 4x4 sub-block
-  it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[0];
-
-  // Import the boundary samples
-  for (i = 0; i < 17; ++i) {    // left
-    it->i4_boundary_[i] = enc->y_left_[15 - i];
-  }
-  for (i = 0; i < 16; ++i) {    // top
-    it->i4_boundary_[17 + i] = enc->y_top_[it->x_ * 16 + i];
-  }
-  // top-right samples have a special case on the far right of the picture
-  if (it->x_ < enc->mb_w_ - 1) {
-    for (i = 16; i < 16 + 4; ++i) {
-      it->i4_boundary_[17 + i] = enc->y_top_[it->x_ * 16 + i];
-    }
-  } else {    // else, replicate the last valid pixel four times
-    for (i = 16; i < 16 + 4; ++i) {
-      it->i4_boundary_[17 + i] = it->i4_boundary_[17 + 15];
-    }
-  }
-  VP8IteratorNzToBytes(it);  // import the non-zero context
-}
-
-int VP8IteratorRotateI4(VP8EncIterator* const it,
-                        const uint8_t* const yuv_out) {
-  const uint8_t* const blk = yuv_out + VP8Scan[it->i4_];
-  uint8_t* const top = it->i4_top_;
-  int i;
-
-  // Update the cache with 7 fresh samples
-  for (i = 0; i <= 3; ++i) {
-    top[-4 + i] = blk[i + 3 * BPS];   // store future top samples
-  }
-  if ((it->i4_ & 3) != 3) {  // if not on the right sub-blocks #3, #7, #11, #15
-    for (i = 0; i <= 2; ++i) {        // store future left samples
-      top[i] = blk[3 + (2 - i) * BPS];
-    }
-  } else {  // else replicate top-right samples, as says the specs.
-    for (i = 0; i <= 3; ++i) {
-      top[i] = top[i + 4];
-    }
-  }
-  // move pointers to next sub-block
-  ++it->i4_;
-  if (it->i4_ == 16) {    // we're done
-    return 0;
-  }
-
-  it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[it->i4_];
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 49
drivers/webpold/enc/layer.c

@@ -1,49 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Enhancement layer (for YUV444/422)
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-
-#include "./vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-
-void VP8EncInitLayer(VP8Encoder* const enc) {
-  enc->use_layer_ = (enc->pic_->u0 != NULL);
-  enc->layer_data_size_ = 0;
-  enc->layer_data_ = NULL;
-  if (enc->use_layer_) {
-    VP8BitWriterInit(&enc->layer_bw_, enc->mb_w_ * enc->mb_h_ * 3);
-  }
-}
-
-void VP8EncCodeLayerBlock(VP8EncIterator* it) {
-  (void)it;   // remove a warning
-}
-
-int VP8EncFinishLayer(VP8Encoder* const enc) {
-  if (enc->use_layer_) {
-    enc->layer_data_ = VP8BitWriterFinish(&enc->layer_bw_);
-    enc->layer_data_size_ = VP8BitWriterSize(&enc->layer_bw_);
-  }
-  return 1;
-}
-
-void VP8EncDeleteLayer(VP8Encoder* enc) {
-  free(enc->layer_data_);
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 1041
drivers/webpold/enc/picture.c

@@ -1,1041 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// WebPPicture utils: colorspace conversion, crop, ...
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "./vp8enci.h"
-#include "../utils/rescaler.h"
-#include "../utils/utils.h"
-#include "../dsp/dsp.h"
-#include "../dsp/yuv.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define HALVE(x) (((x) + 1) >> 1)
-#define IS_YUV_CSP(csp, YUV_CSP) (((csp) & WEBP_CSP_UV_MASK) == (YUV_CSP))
-
-static const union {
-  uint32_t argb;
-  uint8_t  bytes[4];
-} test_endian = { 0xff000000u };
-#define ALPHA_IS_LAST (test_endian.bytes[3] == 0xff)
-
-//------------------------------------------------------------------------------
-// WebPPicture
-//------------------------------------------------------------------------------
-
-int WebPPictureAlloc(WebPPicture* picture) {
-  if (picture != NULL) {
-    const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK;
-    const int has_alpha = picture->colorspace & WEBP_CSP_ALPHA_BIT;
-    const int width = picture->width;
-    const int height = picture->height;
-
-    if (!picture->use_argb) {
-      const int y_stride = width;
-      const int uv_width = HALVE(width);
-      const int uv_height = HALVE(height);
-      const int uv_stride = uv_width;
-      int uv0_stride = 0;
-      int a_width, a_stride;
-      uint64_t y_size, uv_size, uv0_size, a_size, total_size;
-      uint8_t* mem;
-
-      // U/V
-      switch (uv_csp) {
-        case WEBP_YUV420:
-          break;
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-        case WEBP_YUV400:    // for now, we'll just reset the U/V samples
-          break;
-        case WEBP_YUV422:
-          uv0_stride = uv_width;
-          break;
-        case WEBP_YUV444:
-          uv0_stride = width;
-          break;
-#endif
-        default:
-          return 0;
-      }
-      uv0_size = height * uv0_stride;
-
-      // alpha
-      a_width = has_alpha ? width : 0;
-      a_stride = a_width;
-      y_size = (uint64_t)y_stride * height;
-      uv_size = (uint64_t)uv_stride * uv_height;
-      a_size =  (uint64_t)a_stride * height;
-
-      total_size = y_size + a_size + 2 * uv_size + 2 * uv0_size;
-
-      // Security and validation checks
-      if (width <= 0 || height <= 0 ||         // luma/alpha param error
-          uv_width < 0 || uv_height < 0) {     // u/v param error
-        return 0;
-      }
-      // Clear previous buffer and allocate a new one.
-      WebPPictureFree(picture);   // erase previous buffer
-      mem = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*mem));
-      if (mem == NULL) return 0;
-
-      // From now on, we're in the clear, we can no longer fail...
-      picture->memory_ = (void*)mem;
-      picture->y_stride  = y_stride;
-      picture->uv_stride = uv_stride;
-      picture->a_stride  = a_stride;
-      picture->uv0_stride = uv0_stride;
-      // TODO(skal): we could align the y/u/v planes and adjust stride.
-      picture->y = mem;
-      mem += y_size;
-
-      picture->u = mem;
-      mem += uv_size;
-      picture->v = mem;
-      mem += uv_size;
-
-      if (a_size) {
-        picture->a = mem;
-        mem += a_size;
-      }
-      if (uv0_size) {
-        picture->u0 = mem;
-        mem += uv0_size;
-        picture->v0 = mem;
-        mem += uv0_size;
-      }
-    } else {
-      void* memory;
-      const uint64_t argb_size = (uint64_t)width * height;
-      if (width <= 0 || height <= 0) {
-        return 0;
-      }
-      // Clear previous buffer and allocate a new one.
-      WebPPictureFree(picture);   // erase previous buffer
-      memory = WebPSafeMalloc(argb_size, sizeof(*picture->argb));
-      if (memory == NULL) return 0;
-
-      // TODO(skal): align plane to cache line?
-      picture->memory_argb_ = memory;
-      picture->argb = (uint32_t*)memory;
-      picture->argb_stride = width;
-    }
-  }
-  return 1;
-}
-
-// Remove reference to the ARGB buffer (doesn't free anything).
-static void PictureResetARGB(WebPPicture* const picture) {
-  picture->memory_argb_ = NULL;
-  picture->argb = NULL;
-  picture->argb_stride = 0;
-}
-
-// Remove reference to the YUVA buffer (doesn't free anything).
-static void PictureResetYUVA(WebPPicture* const picture) {
-  picture->memory_ = NULL;
-  picture->y = picture->u = picture->v = picture->a = NULL;
-  picture->u0 = picture->v0 = NULL;
-  picture->y_stride = picture->uv_stride = 0;
-  picture->a_stride = 0;
-  picture->uv0_stride = 0;
-}
-
-// Grab the 'specs' (writer, *opaque, width, height...) from 'src' and copy them
-// into 'dst'. Mark 'dst' as not owning any memory.
-static void WebPPictureGrabSpecs(const WebPPicture* const src,
-                                 WebPPicture* const dst) {
-  assert(src != NULL && dst != NULL);
-  *dst = *src;
-  PictureResetYUVA(dst);
-  PictureResetARGB(dst);
-}
-
-// Allocate a new argb buffer, discarding any existing one and preserving
-// the other YUV(A) buffer.
-static int PictureAllocARGB(WebPPicture* const picture) {
-  WebPPicture tmp;
-  free(picture->memory_argb_);
-  PictureResetARGB(picture);
-  picture->use_argb = 1;
-  WebPPictureGrabSpecs(picture, &tmp);
-  if (!WebPPictureAlloc(&tmp)) {
-    return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
-  }
-  picture->memory_argb_ = tmp.memory_argb_;
-  picture->argb = tmp.argb;
-  picture->argb_stride = tmp.argb_stride;
-  return 1;
-}
-
-// Release memory owned by 'picture' (both YUV and ARGB buffers).
-void WebPPictureFree(WebPPicture* picture) {
-  if (picture != NULL) {
-    free(picture->memory_);
-    free(picture->memory_argb_);
-    PictureResetYUVA(picture);
-    PictureResetARGB(picture);
-  }
-}
-
-//------------------------------------------------------------------------------
-// Picture copying
-
-// Not worth moving to dsp/enc.c (only used here).
-static void CopyPlane(const uint8_t* src, int src_stride,
-                      uint8_t* dst, int dst_stride, int width, int height) {
-  while (height-- > 0) {
-    memcpy(dst, src, width);
-    src += src_stride;
-    dst += dst_stride;
-  }
-}
-
-// Adjust top-left corner to chroma sample position.
-static void SnapTopLeftPosition(const WebPPicture* const pic,
-                                int* const left, int* const top) {
-  if (!pic->use_argb) {
-    const int is_yuv422 = IS_YUV_CSP(pic->colorspace, WEBP_YUV422);
-    if (IS_YUV_CSP(pic->colorspace, WEBP_YUV420) || is_yuv422) {
-      *left &= ~1;
-      if (!is_yuv422) *top &= ~1;
-    }
-  }
-}
-
-// Adjust top-left corner and verify that the sub-rectangle is valid.
-static int AdjustAndCheckRectangle(const WebPPicture* const pic,
-                                   int* const left, int* const top,
-                                   int width, int height) {
-  SnapTopLeftPosition(pic, left, top);
-  if ((*left) < 0 || (*top) < 0) return 0;
-  if (width <= 0 || height <= 0) return 0;
-  if ((*left) + width > pic->width) return 0;
-  if ((*top) + height > pic->height) return 0;
-  return 1;
-}
-
-int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
-  if (src == NULL || dst == NULL) return 0;
-  if (src == dst) return 1;
-
-  WebPPictureGrabSpecs(src, dst);
-  if (!WebPPictureAlloc(dst)) return 0;
-
-  if (!src->use_argb) {
-    CopyPlane(src->y, src->y_stride,
-              dst->y, dst->y_stride, dst->width, dst->height);
-    CopyPlane(src->u, src->uv_stride,
-              dst->u, dst->uv_stride, HALVE(dst->width), HALVE(dst->height));
-    CopyPlane(src->v, src->uv_stride,
-              dst->v, dst->uv_stride, HALVE(dst->width), HALVE(dst->height));
-    if (dst->a != NULL)  {
-      CopyPlane(src->a, src->a_stride,
-                dst->a, dst->a_stride, dst->width, dst->height);
-    }
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-    if (dst->u0 != NULL)  {
-      int uv0_width = src->width;
-      if (IS_YUV_CSP(dst->colorspace, WEBP_YUV422)) {
-        uv0_width = HALVE(uv0_width);
-      }
-      CopyPlane(src->u0, src->uv0_stride,
-                dst->u0, dst->uv0_stride, uv0_width, dst->height);
-      CopyPlane(src->v0, src->uv0_stride,
-                dst->v0, dst->uv0_stride, uv0_width, dst->height);
-    }
-#endif
-  } else {
-    CopyPlane((const uint8_t*)src->argb, 4 * src->argb_stride,
-              (uint8_t*)dst->argb, 4 * dst->argb_stride,
-              4 * dst->width, dst->height);
-  }
-  return 1;
-}
-
-int WebPPictureIsView(const WebPPicture* picture) {
-  if (picture == NULL) return 0;
-  if (picture->use_argb) {
-    return (picture->memory_argb_ == NULL);
-  }
-  return (picture->memory_ == NULL);
-}
-
-int WebPPictureView(const WebPPicture* src,
-                    int left, int top, int width, int height,
-                    WebPPicture* dst) {
-  if (src == NULL || dst == NULL) return 0;
-
-  // verify rectangle position.
-  if (!AdjustAndCheckRectangle(src, &left, &top, width, height)) return 0;
-
-  if (src != dst) {  // beware of aliasing! We don't want to leak 'memory_'.
-    WebPPictureGrabSpecs(src, dst);
-  }
-  dst->width = width;
-  dst->height = height;
-  if (!src->use_argb) {
-    dst->y = src->y + top * src->y_stride + left;
-    dst->u = src->u + (top >> 1) * src->uv_stride + (left >> 1);
-    dst->v = src->v + (top >> 1) * src->uv_stride + (left >> 1);
-    if (src->a != NULL) {
-      dst->a = src->a + top * src->a_stride + left;
-    }
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-    if (src->u0 != NULL) {
-      const int left_pos =
-          IS_YUV_CSP(dst->colorspace, WEBP_YUV422) ? (left >> 1) : left;
-      dst->u0 = src->u0 + top * src->uv0_stride + left_pos;
-      dst->v0 = src->v0 + top * src->uv0_stride + left_pos;
-    }
-#endif
-  } else {
-    dst->argb = src->argb + top * src->argb_stride + left;
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Picture cropping
-
-int WebPPictureCrop(WebPPicture* pic,
-                    int left, int top, int width, int height) {
-  WebPPicture tmp;
-
-  if (pic == NULL) return 0;
-  if (!AdjustAndCheckRectangle(pic, &left, &top, width, height)) return 0;
-
-  WebPPictureGrabSpecs(pic, &tmp);
-  tmp.width = width;
-  tmp.height = height;
-  if (!WebPPictureAlloc(&tmp)) return 0;
-
-  if (!pic->use_argb) {
-    const int y_offset = top * pic->y_stride + left;
-    const int uv_offset = (top / 2) * pic->uv_stride + left / 2;
-    CopyPlane(pic->y + y_offset, pic->y_stride,
-              tmp.y, tmp.y_stride, width, height);
-    CopyPlane(pic->u + uv_offset, pic->uv_stride,
-              tmp.u, tmp.uv_stride, HALVE(width), HALVE(height));
-    CopyPlane(pic->v + uv_offset, pic->uv_stride,
-              tmp.v, tmp.uv_stride, HALVE(width), HALVE(height));
-
-    if (tmp.a != NULL) {
-      const int a_offset = top * pic->a_stride + left;
-      CopyPlane(pic->a + a_offset, pic->a_stride,
-                tmp.a, tmp.a_stride, width, height);
-    }
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-    if (tmp.u0 != NULL) {
-      int w = width;
-      int left_pos = left;
-      if (IS_YUV_CSP(tmp.colorspace, WEBP_YUV422)) {
-        w = HALVE(w);
-        left_pos = HALVE(left_pos);
-      }
-      CopyPlane(pic->u0 + top * pic->uv0_stride + left_pos, pic->uv0_stride,
-                tmp.u0, tmp.uv0_stride, w, height);
-      CopyPlane(pic->v0 + top * pic->uv0_stride + left_pos, pic->uv0_stride,
-                tmp.v0, tmp.uv0_stride, w, height);
-    }
-#endif
-  } else {
-    const uint8_t* const src =
-        (const uint8_t*)(pic->argb + top * pic->argb_stride + left);
-    CopyPlane(src, pic->argb_stride * 4,
-              (uint8_t*)tmp.argb, tmp.argb_stride * 4,
-              width * 4, height);
-  }
-  WebPPictureFree(pic);
-  *pic = tmp;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Simple picture rescaler
-
-static void RescalePlane(const uint8_t* src,
-                         int src_width, int src_height, int src_stride,
-                         uint8_t* dst,
-                         int dst_width, int dst_height, int dst_stride,
-                         int32_t* const work,
-                         int num_channels) {
-  WebPRescaler rescaler;
-  int y = 0;
-  WebPRescalerInit(&rescaler, src_width, src_height,
-                   dst, dst_width, dst_height, dst_stride,
-                   num_channels,
-                   src_width, dst_width,
-                   src_height, dst_height,
-                   work);
-  memset(work, 0, 2 * dst_width * num_channels * sizeof(*work));
-  while (y < src_height) {
-    y += WebPRescalerImport(&rescaler, src_height - y,
-                            src + y * src_stride, src_stride);
-    WebPRescalerExport(&rescaler);
-  }
-}
-
-int WebPPictureRescale(WebPPicture* pic, int width, int height) {
-  WebPPicture tmp;
-  int prev_width, prev_height;
-  int32_t* work;
-
-  if (pic == NULL) return 0;
-  prev_width = pic->width;
-  prev_height = pic->height;
-  // if width is unspecified, scale original proportionally to height ratio.
-  if (width == 0) {
-    width = (prev_width * height + prev_height / 2) / prev_height;
-  }
-  // if height is unspecified, scale original proportionally to width ratio.
-  if (height == 0) {
-    height = (prev_height * width + prev_width / 2) / prev_width;
-  }
-  // Check if the overall dimensions still make sense.
-  if (width <= 0 || height <= 0) return 0;
-
-  WebPPictureGrabSpecs(pic, &tmp);
-  tmp.width = width;
-  tmp.height = height;
-  if (!WebPPictureAlloc(&tmp)) return 0;
-
-  if (!pic->use_argb) {
-    work = (int32_t*)WebPSafeMalloc(2ULL * width, sizeof(*work));
-    if (work == NULL) {
-      WebPPictureFree(&tmp);
-      return 0;
-    }
-
-    RescalePlane(pic->y, prev_width, prev_height, pic->y_stride,
-                 tmp.y, width, height, tmp.y_stride, work, 1);
-    RescalePlane(pic->u,
-                 HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
-                 tmp.u,
-                 HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
-    RescalePlane(pic->v,
-                 HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
-                 tmp.v,
-                 HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
-
-    if (tmp.a != NULL) {
-      RescalePlane(pic->a, prev_width, prev_height, pic->a_stride,
-                   tmp.a, width, height, tmp.a_stride, work, 1);
-    }
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-    if (tmp.u0 != NULL) {
-      const int s = IS_YUV_CSP(tmp.colorspace, WEBP_YUV422) ? 2 : 1;
-      RescalePlane(
-          pic->u0, (prev_width + s / 2) / s, prev_height, pic->uv0_stride,
-          tmp.u0, (width + s / 2) / s, height, tmp.uv0_stride, work, 1);
-      RescalePlane(
-          pic->v0, (prev_width + s / 2) / s, prev_height, pic->uv0_stride,
-          tmp.v0, (width + s / 2) / s, height, tmp.uv0_stride, work, 1);
-    }
-#endif
-  } else {
-    work = (int32_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work));
-    if (work == NULL) {
-      WebPPictureFree(&tmp);
-      return 0;
-    }
-
-    RescalePlane((const uint8_t*)pic->argb, prev_width, prev_height,
-                 pic->argb_stride * 4,
-                 (uint8_t*)tmp.argb, width, height,
-                 tmp.argb_stride * 4,
-                 work, 4);
-
-  }
-  WebPPictureFree(pic);
-  free(work);
-  *pic = tmp;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// WebPMemoryWriter: Write-to-memory
-
-void WebPMemoryWriterInit(WebPMemoryWriter* writer) {
-  writer->mem = NULL;
-  writer->size = 0;
-  writer->max_size = 0;
-}
-
-int WebPMemoryWrite(const uint8_t* data, size_t data_size,
-                    const WebPPicture* picture) {
-  WebPMemoryWriter* const w = (WebPMemoryWriter*)picture->custom_ptr;
-  uint64_t next_size;
-  if (w == NULL) {
-    return 1;
-  }
-  next_size = (uint64_t)w->size + data_size;
-  if (next_size > w->max_size) {
-    uint8_t* new_mem;
-    uint64_t next_max_size = 2ULL * w->max_size;
-    if (next_max_size < next_size) next_max_size = next_size;
-    if (next_max_size < 8192ULL) next_max_size = 8192ULL;
-    new_mem = (uint8_t*)WebPSafeMalloc(next_max_size, 1);
-    if (new_mem == NULL) {
-      return 0;
-    }
-    if (w->size > 0) {
-      memcpy(new_mem, w->mem, w->size);
-    }
-    free(w->mem);
-    w->mem = new_mem;
-    // down-cast is ok, thanks to WebPSafeMalloc
-    w->max_size = (size_t)next_max_size;
-  }
-  if (data_size > 0) {
-    memcpy(w->mem + w->size, data, data_size);
-    w->size += data_size;
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Detection of non-trivial transparency
-
-// Returns true if alpha[] has non-0xff values.
-static int CheckNonOpaque(const uint8_t* alpha, int width, int height,
-                          int x_step, int y_step) {
-  if (alpha == NULL) return 0;
-  while (height-- > 0) {
-    int x;
-    for (x = 0; x < width * x_step; x += x_step) {
-      if (alpha[x] != 0xff) return 1;  // TODO(skal): check 4/8 bytes at a time.
-    }
-    alpha += y_step;
-  }
-  return 0;
-}
-
-// Checking for the presence of non-opaque alpha.
-int WebPPictureHasTransparency(const WebPPicture* picture) {
-  if (picture == NULL) return 0;
-  if (!picture->use_argb) {
-    return CheckNonOpaque(picture->a, picture->width, picture->height,
-                          1, picture->a_stride);
-  } else {
-    int x, y;
-    const uint32_t* argb = picture->argb;
-    if (argb == NULL) return 0;
-    for (y = 0; y < picture->height; ++y) {
-      for (x = 0; x < picture->width; ++x) {
-        if (argb[x] < 0xff000000u) return 1;   // test any alpha values != 0xff
-      }
-      argb += picture->argb_stride;
-    }
-  }
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// RGB -> YUV conversion
-
-// TODO: we can do better than simply 2x2 averaging on U/V samples.
-#define SUM4(ptr) ((ptr)[0] + (ptr)[step] + \
-                   (ptr)[rgb_stride] + (ptr)[rgb_stride + step])
-#define SUM2H(ptr) (2 * (ptr)[0] + 2 * (ptr)[step])
-#define SUM2V(ptr) (2 * (ptr)[0] + 2 * (ptr)[rgb_stride])
-#define SUM1(ptr)  (4 * (ptr)[0])
-#define RGB_TO_UV(x, y, SUM) {                           \
-  const int src = (2 * (step * (x) + (y) * rgb_stride)); \
-  const int dst = (x) + (y) * picture->uv_stride;        \
-  const int r = SUM(r_ptr + src);                        \
-  const int g = SUM(g_ptr + src);                        \
-  const int b = SUM(b_ptr + src);                        \
-  picture->u[dst] = VP8RGBToU(r, g, b);                  \
-  picture->v[dst] = VP8RGBToV(r, g, b);                  \
-}
-
-#define RGB_TO_UV0(x_in, x_out, y, SUM) {                \
-  const int src = (step * (x_in) + (y) * rgb_stride);    \
-  const int dst = (x_out) + (y) * picture->uv0_stride;   \
-  const int r = SUM(r_ptr + src);                        \
-  const int g = SUM(g_ptr + src);                        \
-  const int b = SUM(b_ptr + src);                        \
-  picture->u0[dst] = VP8RGBToU(r, g, b);                 \
-  picture->v0[dst] = VP8RGBToV(r, g, b);                 \
-}
-
-static void MakeGray(WebPPicture* const picture) {
-  int y;
-  const int uv_width = HALVE(picture->width);
-  const int uv_height = HALVE(picture->height);
-  for (y = 0; y < uv_height; ++y) {
-    memset(picture->u + y * picture->uv_stride, 128, uv_width);
-    memset(picture->v + y * picture->uv_stride, 128, uv_width);
-  }
-}
-
-static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
-                              const uint8_t* const g_ptr,
-                              const uint8_t* const b_ptr,
-                              const uint8_t* const a_ptr,
-                              int step,         // bytes per pixel
-                              int rgb_stride,   // bytes per scanline
-                              WebPPicture* const picture) {
-  const WebPEncCSP uv_csp = picture->colorspace & WEBP_CSP_UV_MASK;
-  int x, y;
-  const int width = picture->width;
-  const int height = picture->height;
-  const int has_alpha = CheckNonOpaque(a_ptr, width, height, step, rgb_stride);
-
-  picture->colorspace = uv_csp;
-  picture->use_argb = 0;
-  if (has_alpha) {
-    picture->colorspace |= WEBP_CSP_ALPHA_BIT;
-  }
-  if (!WebPPictureAlloc(picture)) return 0;
-
-  // Import luma plane
-  for (y = 0; y < height; ++y) {
-    for (x = 0; x < width; ++x) {
-      const int offset = step * x + y * rgb_stride;
-      picture->y[x + y * picture->y_stride] =
-          VP8RGBToY(r_ptr[offset], g_ptr[offset], b_ptr[offset]);
-    }
-  }
-
-  // Downsample U/V plane
-  if (uv_csp != WEBP_YUV400) {
-    for (y = 0; y < (height >> 1); ++y) {
-      for (x = 0; x < (width >> 1); ++x) {
-        RGB_TO_UV(x, y, SUM4);
-      }
-      if (width & 1) {
-        RGB_TO_UV(x, y, SUM2V);
-      }
-    }
-    if (height & 1) {
-      for (x = 0; x < (width >> 1); ++x) {
-        RGB_TO_UV(x, y, SUM2H);
-      }
-      if (width & 1) {
-        RGB_TO_UV(x, y, SUM1);
-      }
-    }
-
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-    // Store original U/V samples too
-    if (uv_csp == WEBP_YUV422) {
-      for (y = 0; y < height; ++y) {
-        for (x = 0; x < (width >> 1); ++x) {
-          RGB_TO_UV0(2 * x, x, y, SUM2H);
-        }
-        if (width & 1) {
-          RGB_TO_UV0(2 * x, x, y, SUM1);
-        }
-      }
-    } else if (uv_csp == WEBP_YUV444) {
-      for (y = 0; y < height; ++y) {
-        for (x = 0; x < width; ++x) {
-          RGB_TO_UV0(x, x, y, SUM1);
-        }
-      }
-    }
-#endif
-  } else {
-    MakeGray(picture);
-  }
-
-  if (has_alpha) {
-    assert(step >= 4);
-    for (y = 0; y < height; ++y) {
-      for (x = 0; x < width; ++x) {
-        picture->a[x + y * picture->a_stride] =
-            a_ptr[step * x + y * rgb_stride];
-      }
-    }
-  }
-  return 1;
-}
-
-static int Import(WebPPicture* const picture,
-                  const uint8_t* const rgb, int rgb_stride,
-                  int step, int swap_rb, int import_alpha) {
-  const uint8_t* const r_ptr = rgb + (swap_rb ? 2 : 0);
-  const uint8_t* const g_ptr = rgb + 1;
-  const uint8_t* const b_ptr = rgb + (swap_rb ? 0 : 2);
-  const uint8_t* const a_ptr = import_alpha ? rgb + 3 : NULL;
-  const int width = picture->width;
-  const int height = picture->height;
-
-  if (!picture->use_argb) {
-    return ImportYUVAFromRGBA(r_ptr, g_ptr, b_ptr, a_ptr, step, rgb_stride,
-                              picture);
-  }
-  if (import_alpha) {
-    picture->colorspace |= WEBP_CSP_ALPHA_BIT;
-  } else {
-    picture->colorspace &= ~WEBP_CSP_ALPHA_BIT;
-  }
-  if (!WebPPictureAlloc(picture)) return 0;
-
-  if (!import_alpha) {
-    int x, y;
-    for (y = 0; y < height; ++y) {
-      for (x = 0; x < width; ++x) {
-        const int offset = step * x + y * rgb_stride;
-        const uint32_t argb =
-            0xff000000u |
-            (r_ptr[offset] << 16) |
-            (g_ptr[offset] <<  8) |
-            (b_ptr[offset]);
-        picture->argb[x + y * picture->argb_stride] = argb;
-      }
-    }
-  } else {
-    int x, y;
-    assert(step >= 4);
-    for (y = 0; y < height; ++y) {
-      for (x = 0; x < width; ++x) {
-        const int offset = step * x + y * rgb_stride;
-        const uint32_t argb = (a_ptr[offset] << 24) |
-                              (r_ptr[offset] << 16) |
-                              (g_ptr[offset] <<  8) |
-                              (b_ptr[offset]);
-        picture->argb[x + y * picture->argb_stride] = argb;
-      }
-    }
-  }
-  return 1;
-}
-#undef SUM4
-#undef SUM2V
-#undef SUM2H
-#undef SUM1
-#undef RGB_TO_UV
-
-int WebPPictureImportRGB(WebPPicture* picture,
-                         const uint8_t* rgb, int rgb_stride) {
-  return Import(picture, rgb, rgb_stride, 3, 0, 0);
-}
-
-int WebPPictureImportBGR(WebPPicture* picture,
-                         const uint8_t* rgb, int rgb_stride) {
-  return Import(picture, rgb, rgb_stride, 3, 1, 0);
-}
-
-int WebPPictureImportRGBA(WebPPicture* picture,
-                          const uint8_t* rgba, int rgba_stride) {
-  return Import(picture, rgba, rgba_stride, 4, 0, 1);
-}
-
-int WebPPictureImportBGRA(WebPPicture* picture,
-                          const uint8_t* rgba, int rgba_stride) {
-  return Import(picture, rgba, rgba_stride, 4, 1, 1);
-}
-
-int WebPPictureImportRGBX(WebPPicture* picture,
-                          const uint8_t* rgba, int rgba_stride) {
-  return Import(picture, rgba, rgba_stride, 4, 0, 0);
-}
-
-int WebPPictureImportBGRX(WebPPicture* picture,
-                          const uint8_t* rgba, int rgba_stride) {
-  return Import(picture, rgba, rgba_stride, 4, 1, 0);
-}
-
-//------------------------------------------------------------------------------
-// Automatic YUV <-> ARGB conversions.
-
-int WebPPictureYUVAToARGB(WebPPicture* picture) {
-  if (picture == NULL) return 0;
-  if (picture->memory_ == NULL || picture->y == NULL ||
-      picture->u == NULL || picture->v == NULL) {
-    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
-  }
-  if ((picture->colorspace & WEBP_CSP_ALPHA_BIT) && picture->a == NULL) {
-    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
-  }
-  if ((picture->colorspace & WEBP_CSP_UV_MASK) != WEBP_YUV420) {
-    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
-  }
-  // Allocate a new argb buffer (discarding the previous one).
-  if (!PictureAllocARGB(picture)) return 0;
-
-  // Convert
-  {
-    int y;
-    const int width = picture->width;
-    const int height = picture->height;
-    const int argb_stride = 4 * picture->argb_stride;
-    uint8_t* dst = (uint8_t*)picture->argb;
-    const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y;
-    WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter(ALPHA_IS_LAST);
-
-    // First row, with replicated top samples.
-    upsample(NULL, cur_y, cur_u, cur_v, cur_u, cur_v, NULL, dst, width);
-    cur_y += picture->y_stride;
-    dst += argb_stride;
-    // Center rows.
-    for (y = 1; y + 1 < height; y += 2) {
-      const uint8_t* const top_u = cur_u;
-      const uint8_t* const top_v = cur_v;
-      cur_u += picture->uv_stride;
-      cur_v += picture->uv_stride;
-      upsample(cur_y, cur_y + picture->y_stride, top_u, top_v, cur_u, cur_v,
-               dst, dst + argb_stride, width);
-      cur_y += 2 * picture->y_stride;
-      dst += 2 * argb_stride;
-    }
-    // Last row (if needed), with replicated bottom samples.
-    if (height > 1 && !(height & 1)) {
-      upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
-    }
-    // Insert alpha values if needed, in replacement for the default 0xff ones.
-    if (picture->colorspace & WEBP_CSP_ALPHA_BIT) {
-      for (y = 0; y < height; ++y) {
-        uint32_t* const dst = picture->argb + y * picture->argb_stride;
-        const uint8_t* const src = picture->a + y * picture->a_stride;
-        int x;
-        for (x = 0; x < width; ++x) {
-          dst[x] = (dst[x] & 0x00ffffffu) | (src[x] << 24);
-        }
-      }
-    }
-  }
-  return 1;
-}
-
-int WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP colorspace) {
-  if (picture == NULL) return 0;
-  if (picture->argb == NULL) {
-    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
-  } else {
-    const uint8_t* const argb = (const uint8_t*)picture->argb;
-    const uint8_t* const r = ALPHA_IS_LAST ? argb + 2 : argb + 1;
-    const uint8_t* const g = ALPHA_IS_LAST ? argb + 1 : argb + 2;
-    const uint8_t* const b = ALPHA_IS_LAST ? argb + 0 : argb + 3;
-    const uint8_t* const a = ALPHA_IS_LAST ? argb + 3 : argb + 0;
-    // We work on a tmp copy of 'picture', because ImportYUVAFromRGBA()
-    // would be calling WebPPictureFree(picture) otherwise.
-    WebPPicture tmp = *picture;
-    PictureResetARGB(&tmp);  // reset ARGB buffer so that it's not free()'d.
-    tmp.use_argb = 0;
-    tmp.colorspace = colorspace & WEBP_CSP_UV_MASK;
-    if (!ImportYUVAFromRGBA(r, g, b, a, 4, 4 * picture->argb_stride, &tmp)) {
-      return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
-    }
-    // Copy back the YUV specs into 'picture'.
-    tmp.argb = picture->argb;
-    tmp.argb_stride = picture->argb_stride;
-    tmp.memory_argb_ = picture->memory_argb_;
-    *picture = tmp;
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Helper: clean up fully transparent area to help compressibility.
-
-#define SIZE 8
-#define SIZE2 (SIZE / 2)
-static int is_transparent_area(const uint8_t* ptr, int stride, int size) {
-  int y, x;
-  for (y = 0; y < size; ++y) {
-    for (x = 0; x < size; ++x) {
-      if (ptr[x]) {
-        return 0;
-      }
-    }
-    ptr += stride;
-  }
-  return 1;
-}
-
-static WEBP_INLINE void flatten(uint8_t* ptr, int v, int stride, int size) {
-  int y;
-  for (y = 0; y < size; ++y) {
-    memset(ptr, v, size);
-    ptr += stride;
-  }
-}
-
-void WebPCleanupTransparentArea(WebPPicture* pic) {
-  int x, y, w, h;
-  const uint8_t* a_ptr;
-  int values[3] = { 0 };
-
-  if (pic == NULL) return;
-
-  a_ptr = pic->a;
-  if (a_ptr == NULL) return;    // nothing to do
-
-  w = pic->width / SIZE;
-  h = pic->height / SIZE;
-  for (y = 0; y < h; ++y) {
-    int need_reset = 1;
-    for (x = 0; x < w; ++x) {
-      const int off_a = (y * pic->a_stride + x) * SIZE;
-      const int off_y = (y * pic->y_stride + x) * SIZE;
-      const int off_uv = (y * pic->uv_stride + x) * SIZE2;
-      if (is_transparent_area(a_ptr + off_a, pic->a_stride, SIZE)) {
-        if (need_reset) {
-          values[0] = pic->y[off_y];
-          values[1] = pic->u[off_uv];
-          values[2] = pic->v[off_uv];
-          need_reset = 0;
-        }
-        flatten(pic->y + off_y, values[0], pic->y_stride, SIZE);
-        flatten(pic->u + off_uv, values[1], pic->uv_stride, SIZE2);
-        flatten(pic->v + off_uv, values[2], pic->uv_stride, SIZE2);
-      } else {
-        need_reset = 1;
-      }
-    }
-    // ignore the left-overs on right/bottom
-  }
-}
-
-#undef SIZE
-#undef SIZE2
-
-
-//------------------------------------------------------------------------------
-// Distortion
-
-// Max value returned in case of exact similarity.
-static const double kMinDistortion_dB = 99.;
-
-int WebPPictureDistortion(const WebPPicture* pic1, const WebPPicture* pic2,
-                          int type, float result[5]) {
-  int c;
-  DistoStats stats[5];
-  int has_alpha;
-
-  if (pic1 == NULL || pic2 == NULL ||
-      pic1->width != pic2->width || pic1->height != pic2->height ||
-      pic1->y == NULL || pic2->y == NULL ||
-      pic1->u == NULL || pic2->u == NULL ||
-      pic1->v == NULL || pic2->v == NULL ||
-      result == NULL) {
-    return 0;
-  }
-  // TODO(skal): provide distortion for ARGB too.
-  if (pic1->use_argb == 1 || pic1->use_argb != pic2->use_argb) {
-    return 0;
-  }
-
-  has_alpha = !!(pic1->colorspace & WEBP_CSP_ALPHA_BIT);
-  if (has_alpha != !!(pic2->colorspace & WEBP_CSP_ALPHA_BIT) ||
-      (has_alpha && (pic1->a == NULL || pic2->a == NULL))) {
-    return 0;
-  }
-
-  memset(stats, 0, sizeof(stats));
-  VP8SSIMAccumulatePlane(pic1->y, pic1->y_stride,
-                         pic2->y, pic2->y_stride,
-                         pic1->width, pic1->height, &stats[0]);
-  VP8SSIMAccumulatePlane(pic1->u, pic1->uv_stride,
-                         pic2->u, pic2->uv_stride,
-                         (pic1->width + 1) >> 1, (pic1->height + 1) >> 1,
-                         &stats[1]);
-  VP8SSIMAccumulatePlane(pic1->v, pic1->uv_stride,
-                         pic2->v, pic2->uv_stride,
-                         (pic1->width + 1) >> 1, (pic1->height + 1) >> 1,
-                         &stats[2]);
-  if (has_alpha) {
-    VP8SSIMAccumulatePlane(pic1->a, pic1->a_stride,
-                           pic2->a, pic2->a_stride,
-                           pic1->width, pic1->height, &stats[3]);
-  }
-  for (c = 0; c <= 4; ++c) {
-    if (type == 1) {
-      const double v = VP8SSIMGet(&stats[c]);
-      result[c] = (float)((v < 1.) ? -10.0 * log10(1. - v)
-                                   : kMinDistortion_dB);
-    } else {
-      const double v = VP8SSIMGetSquaredError(&stats[c]);
-      result[c] = (float)((v > 0.) ? -4.3429448 * log(v / (255 * 255.))
-                                   : kMinDistortion_dB);
-    }
-    // Accumulate forward
-    if (c < 4) VP8SSIMAddStats(&stats[c], &stats[4]);
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Simplest high-level calls:
-
-typedef int (*Importer)(WebPPicture* const, const uint8_t* const, int);
-
-static size_t Encode(const uint8_t* rgba, int width, int height, int stride,
-                     Importer import, float quality_factor, int lossless,
-                     uint8_t** output) {
-  WebPPicture pic;
-  WebPConfig config;
-  WebPMemoryWriter wrt;
-  int ok;
-
-  if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, quality_factor) ||
-      !WebPPictureInit(&pic)) {
-    return 0;  // shouldn't happen, except if system installation is broken
-  }
-
-  config.lossless = !!lossless;
-  pic.use_argb = !!lossless;
-  pic.width = width;
-  pic.height = height;
-  pic.writer = WebPMemoryWrite;
-  pic.custom_ptr = &wrt;
-  WebPMemoryWriterInit(&wrt);
-
-  ok = import(&pic, rgba, stride) && WebPEncode(&config, &pic);
-  WebPPictureFree(&pic);
-  if (!ok) {
-    free(wrt.mem);
-    *output = NULL;
-    return 0;
-  }
-  *output = wrt.mem;
-  return wrt.size;
-}
-
-#define ENCODE_FUNC(NAME, IMPORTER)                                     \
-size_t NAME(const uint8_t* in, int w, int h, int bps, float q,          \
-            uint8_t** out) {                                            \
-  return Encode(in, w, h, bps, IMPORTER, q, 0, out);                    \
-}
-
-ENCODE_FUNC(WebPEncodeRGB, WebPPictureImportRGB);
-ENCODE_FUNC(WebPEncodeBGR, WebPPictureImportBGR);
-ENCODE_FUNC(WebPEncodeRGBA, WebPPictureImportRGBA);
-ENCODE_FUNC(WebPEncodeBGRA, WebPPictureImportBGRA);
-
-#undef ENCODE_FUNC
-
-#define LOSSLESS_DEFAULT_QUALITY 70.
-#define LOSSLESS_ENCODE_FUNC(NAME, IMPORTER)                                 \
-size_t NAME(const uint8_t* in, int w, int h, int bps, uint8_t** out) {       \
-  return Encode(in, w, h, bps, IMPORTER, LOSSLESS_DEFAULT_QUALITY, 1, out);  \
-}
-
-LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGB, WebPPictureImportRGB);
-LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGR, WebPPictureImportBGR);
-LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessRGBA, WebPPictureImportRGBA);
-LOSSLESS_ENCODE_FUNC(WebPEncodeLosslessBGRA, WebPPictureImportBGRA);
-
-#undef LOSSLESS_ENCODE_FUNC
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 930
drivers/webpold/enc/quant.c

@@ -1,930 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//   Quantization
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <math.h>
-
-#include "./vp8enci.h"
-#include "./cost.h"
-
-#define DO_TRELLIS_I4  1
-#define DO_TRELLIS_I16 1   // not a huge gain, but ok at low bitrate.
-#define DO_TRELLIS_UV  0   // disable trellis for UV. Risky. Not worth.
-#define USE_TDISTO 1
-
-#define MID_ALPHA 64      // neutral value for susceptibility
-#define MIN_ALPHA 30      // lowest usable value for susceptibility
-#define MAX_ALPHA 100     // higher meaninful value for susceptibility
-
-#define SNS_TO_DQ 0.9     // Scaling constant between the sns value and the QP
-                          // power-law modulation. Must be strictly less than 1.
-
-#define MULT_8B(a, b) (((a) * (b) + 128) >> 8)
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-
-static WEBP_INLINE int clip(int v, int m, int M) {
-  return v < m ? m : v > M ? M : v;
-}
-
-static const uint8_t kZigzag[16] = {
-  0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
-};
-
-static const uint8_t kDcTable[128] = {
-  4,     5,   6,   7,   8,   9,  10,  10,
-  11,   12,  13,  14,  15,  16,  17,  17,
-  18,   19,  20,  20,  21,  21,  22,  22,
-  23,   23,  24,  25,  25,  26,  27,  28,
-  29,   30,  31,  32,  33,  34,  35,  36,
-  37,   37,  38,  39,  40,  41,  42,  43,
-  44,   45,  46,  46,  47,  48,  49,  50,
-  51,   52,  53,  54,  55,  56,  57,  58,
-  59,   60,  61,  62,  63,  64,  65,  66,
-  67,   68,  69,  70,  71,  72,  73,  74,
-  75,   76,  76,  77,  78,  79,  80,  81,
-  82,   83,  84,  85,  86,  87,  88,  89,
-  91,   93,  95,  96,  98, 100, 101, 102,
-  104, 106, 108, 110, 112, 114, 116, 118,
-  122, 124, 126, 128, 130, 132, 134, 136,
-  138, 140, 143, 145, 148, 151, 154, 157
-};
-
-static const uint16_t kAcTable[128] = {
-  4,     5,   6,   7,   8,   9,  10,  11,
-  12,   13,  14,  15,  16,  17,  18,  19,
-  20,   21,  22,  23,  24,  25,  26,  27,
-  28,   29,  30,  31,  32,  33,  34,  35,
-  36,   37,  38,  39,  40,  41,  42,  43,
-  44,   45,  46,  47,  48,  49,  50,  51,
-  52,   53,  54,  55,  56,  57,  58,  60,
-  62,   64,  66,  68,  70,  72,  74,  76,
-  78,   80,  82,  84,  86,  88,  90,  92,
-  94,   96,  98, 100, 102, 104, 106, 108,
-  110, 112, 114, 116, 119, 122, 125, 128,
-  131, 134, 137, 140, 143, 146, 149, 152,
-  155, 158, 161, 164, 167, 170, 173, 177,
-  181, 185, 189, 193, 197, 201, 205, 209,
-  213, 217, 221, 225, 229, 234, 239, 245,
-  249, 254, 259, 264, 269, 274, 279, 284
-};
-
-static const uint16_t kAcTable2[128] = {
-  8,     8,   9,  10,  12,  13,  15,  17,
-  18,   20,  21,  23,  24,  26,  27,  29,
-  31,   32,  34,  35,  37,  38,  40,  41,
-  43,   44,  46,  48,  49,  51,  52,  54,
-  55,   57,  58,  60,  62,  63,  65,  66,
-  68,   69,  71,  72,  74,  75,  77,  79,
-  80,   82,  83,  85,  86,  88,  89,  93,
-  96,   99, 102, 105, 108, 111, 114, 117,
-  120, 124, 127, 130, 133, 136, 139, 142,
-  145, 148, 151, 155, 158, 161, 164, 167,
-  170, 173, 176, 179, 184, 189, 193, 198,
-  203, 207, 212, 217, 221, 226, 230, 235,
-  240, 244, 249, 254, 258, 263, 268, 274,
-  280, 286, 292, 299, 305, 311, 317, 323,
-  330, 336, 342, 348, 354, 362, 370, 379,
-  385, 393, 401, 409, 416, 424, 432, 440
-};
-
-static const uint16_t kCoeffThresh[16] = {
-  0,  10, 20, 30,
-  10, 20, 30, 30,
-  20, 30, 30, 30,
-  30, 30, 30, 30
-};
-
-// TODO(skal): tune more. Coeff thresholding?
-static const uint8_t kBiasMatrices[3][16] = {  // [3] = [luma-ac,luma-dc,chroma]
-  { 96, 96, 96, 96,
-    96, 96, 96, 96,
-    96, 96, 96, 96,
-    96, 96, 96, 96 },
-  { 96, 96, 96, 96,
-    96, 96, 96, 96,
-    96, 96, 96, 96,
-    96, 96, 96, 96 },
-  { 96, 96, 96, 96,
-    96, 96, 96, 96,
-    96, 96, 96, 96,
-    96, 96, 96, 96 }
-};
-
-// Sharpening by (slightly) raising the hi-frequency coeffs (only for trellis).
-// Hack-ish but helpful for mid-bitrate range. Use with care.
-static const uint8_t kFreqSharpening[16] = {
-  0,  30, 60, 90,
-  30, 60, 90, 90,
-  60, 90, 90, 90,
-  90, 90, 90, 90
-};
-
-//------------------------------------------------------------------------------
-// Initialize quantization parameters in VP8Matrix
-
-// Returns the average quantizer
-static int ExpandMatrix(VP8Matrix* const m, int type) {
-  int i;
-  int sum = 0;
-  for (i = 2; i < 16; ++i) {
-    m->q_[i] = m->q_[1];
-  }
-  for (i = 0; i < 16; ++i) {
-    const int j = kZigzag[i];
-    const int bias = kBiasMatrices[type][j];
-    m->iq_[j] = (1 << QFIX) / m->q_[j];
-    m->bias_[j] = BIAS(bias);
-    // TODO(skal): tune kCoeffThresh[]
-    m->zthresh_[j] = ((256 /*+ kCoeffThresh[j]*/ - bias) * m->q_[j] + 127) >> 8;
-    m->sharpen_[j] = (kFreqSharpening[j] * m->q_[j]) >> 11;
-    sum += m->q_[j];
-  }
-  return (sum + 8) >> 4;
-}
-
-static void SetupMatrices(VP8Encoder* enc) {
-  int i;
-  const int tlambda_scale =
-    (enc->method_ >= 4) ? enc->config_->sns_strength
-                        : 0;
-  const int num_segments = enc->segment_hdr_.num_segments_;
-  for (i = 0; i < num_segments; ++i) {
-    VP8SegmentInfo* const m = &enc->dqm_[i];
-    const int q = m->quant_;
-    int q4, q16, quv;
-    m->y1_.q_[0] = kDcTable[clip(q + enc->dq_y1_dc_, 0, 127)];
-    m->y1_.q_[1] = kAcTable[clip(q,                  0, 127)];
-
-    m->y2_.q_[0] = kDcTable[ clip(q + enc->dq_y2_dc_, 0, 127)] * 2;
-    m->y2_.q_[1] = kAcTable2[clip(q + enc->dq_y2_ac_, 0, 127)];
-
-    m->uv_.q_[0] = kDcTable[clip(q + enc->dq_uv_dc_, 0, 117)];
-    m->uv_.q_[1] = kAcTable[clip(q + enc->dq_uv_ac_, 0, 127)];
-
-    q4  = ExpandMatrix(&m->y1_, 0);
-    q16 = ExpandMatrix(&m->y2_, 1);
-    quv = ExpandMatrix(&m->uv_, 2);
-
-    // TODO: Switch to kLambda*[] tables?
-    {
-      m->lambda_i4_  = (3 * q4 * q4) >> 7;
-      m->lambda_i16_ = (3 * q16 * q16);
-      m->lambda_uv_  = (3 * quv * quv) >> 6;
-      m->lambda_mode_    = (1 * q4 * q4) >> 7;
-      m->lambda_trellis_i4_  = (7 * q4 * q4) >> 3;
-      m->lambda_trellis_i16_ = (q16 * q16) >> 2;
-      m->lambda_trellis_uv_  = (quv *quv) << 1;
-      m->tlambda_            = (tlambda_scale * q4) >> 5;
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// Initialize filtering parameters
-
-// Very small filter-strength values have close to no visual effect. So we can
-// save a little decoding-CPU by turning filtering off for these.
-#define FSTRENGTH_CUTOFF 3
-
-static void SetupFilterStrength(VP8Encoder* const enc) {
-  int i;
-  const int level0 = enc->config_->filter_strength;
-  for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
-    // Segments with lower quantizer will be less filtered. TODO: tune (wrt SNS)
-    const int level = level0 * 256 * enc->dqm_[i].quant_ / 128;
-    const int f = level / (256 + enc->dqm_[i].beta_);
-    enc->dqm_[i].fstrength_ = (f < FSTRENGTH_CUTOFF) ? 0 : (f > 63) ? 63 : f;
-  }
-  // We record the initial strength (mainly for the case of 1-segment only).
-  enc->filter_hdr_.level_ = enc->dqm_[0].fstrength_;
-  enc->filter_hdr_.simple_ = (enc->config_->filter_type == 0);
-  enc->filter_hdr_.sharpness_ = enc->config_->filter_sharpness;
-}
-
-//------------------------------------------------------------------------------
-
-// Note: if you change the values below, remember that the max range
-// allowed by the syntax for DQ_UV is [-16,16].
-#define MAX_DQ_UV (6)
-#define MIN_DQ_UV (-4)
-
-// We want to emulate jpeg-like behaviour where the expected "good" quality
-// is around q=75. Internally, our "good" middle is around c=50. So we
-// map accordingly using linear piece-wise function
-static double QualityToCompression(double q) {
-  const double c = q / 100.;
-  return (c < 0.75) ? c * (2. / 3.) : 2. * c - 1.;
-}
-
-void VP8SetSegmentParams(VP8Encoder* const enc, float quality) {
-  int i;
-  int dq_uv_ac, dq_uv_dc;
-  const int num_segments = enc->config_->segments;
-  const double amp = SNS_TO_DQ * enc->config_->sns_strength / 100. / 128.;
-  const double c_base = QualityToCompression(quality);
-  for (i = 0; i < num_segments; ++i) {
-    // The file size roughly scales as pow(quantizer, 3.). Actually, the
-    // exponent is somewhere between 2.8 and 3.2, but we're mostly interested
-    // in the mid-quant range. So we scale the compressibility inversely to
-    // this power-law: quant ~= compression ^ 1/3. This law holds well for
-    // low quant. Finer modelling for high-quant would make use of kAcTable[]
-    // more explicitely.
-    // Additionally, we modulate the base exponent 1/3 to accommodate for the
-    // quantization susceptibility and allow denser segments to be quantized
-    // more.
-    const double expn = (1. - amp * enc->dqm_[i].alpha_) / 3.;
-    const double c = pow(c_base, expn);
-    const int q = (int)(127. * (1. - c));
-    assert(expn > 0.);
-    enc->dqm_[i].quant_ = clip(q, 0, 127);
-  }
-
-  // purely indicative in the bitstream (except for the 1-segment case)
-  enc->base_quant_ = enc->dqm_[0].quant_;
-
-  // fill-in values for the unused segments (required by the syntax)
-  for (i = num_segments; i < NUM_MB_SEGMENTS; ++i) {
-    enc->dqm_[i].quant_ = enc->base_quant_;
-  }
-
-  // uv_alpha_ is normally spread around ~60. The useful range is
-  // typically ~30 (quite bad) to ~100 (ok to decimate UV more).
-  // We map it to the safe maximal range of MAX/MIN_DQ_UV for dq_uv.
-  dq_uv_ac = (enc->uv_alpha_ - MID_ALPHA) * (MAX_DQ_UV - MIN_DQ_UV)
-                                          / (MAX_ALPHA - MIN_ALPHA);
-  // we rescale by the user-defined strength of adaptation
-  dq_uv_ac = dq_uv_ac * enc->config_->sns_strength / 100;
-  // and make it safe.
-  dq_uv_ac = clip(dq_uv_ac, MIN_DQ_UV, MAX_DQ_UV);
-  // We also boost the dc-uv-quant a little, based on sns-strength, since
-  // U/V channels are quite more reactive to high quants (flat DC-blocks
-  // tend to appear, and are displeasant).
-  dq_uv_dc = -4 * enc->config_->sns_strength / 100;
-  dq_uv_dc = clip(dq_uv_dc, -15, 15);   // 4bit-signed max allowed
-
-  enc->dq_y1_dc_ = 0;       // TODO(skal): dq-lum
-  enc->dq_y2_dc_ = 0;
-  enc->dq_y2_ac_ = 0;
-  enc->dq_uv_dc_ = dq_uv_dc;
-  enc->dq_uv_ac_ = dq_uv_ac;
-
-  SetupMatrices(enc);
-
-  SetupFilterStrength(enc);   // initialize segments' filtering, eventually
-}
-
-//------------------------------------------------------------------------------
-// Form the predictions in cache
-
-// Must be ordered using {DC_PRED, TM_PRED, V_PRED, H_PRED} as index
-const int VP8I16ModeOffsets[4] = { I16DC16, I16TM16, I16VE16, I16HE16 };
-const int VP8UVModeOffsets[4] = { C8DC8, C8TM8, C8VE8, C8HE8 };
-
-// Must be indexed using {B_DC_PRED -> B_HU_PRED} as index
-const int VP8I4ModeOffsets[NUM_BMODES] = {
-  I4DC4, I4TM4, I4VE4, I4HE4, I4RD4, I4VR4, I4LD4, I4VL4, I4HD4, I4HU4
-};
-
-void VP8MakeLuma16Preds(const VP8EncIterator* const it) {
-  const VP8Encoder* const enc = it->enc_;
-  const uint8_t* const left = it->x_ ? enc->y_left_ : NULL;
-  const uint8_t* const top = it->y_ ? enc->y_top_ + it->x_ * 16 : NULL;
-  VP8EncPredLuma16(it->yuv_p_, left, top);
-}
-
-void VP8MakeChroma8Preds(const VP8EncIterator* const it) {
-  const VP8Encoder* const enc = it->enc_;
-  const uint8_t* const left = it->x_ ? enc->u_left_ : NULL;
-  const uint8_t* const top = it->y_ ? enc->uv_top_ + it->x_ * 16 : NULL;
-  VP8EncPredChroma8(it->yuv_p_, left, top);
-}
-
-void VP8MakeIntra4Preds(const VP8EncIterator* const it) {
-  VP8EncPredLuma4(it->yuv_p_, it->i4_top_);
-}
-
-//------------------------------------------------------------------------------
-// Quantize
-
-// Layout:
-// +----+
-// |YYYY| 0
-// |YYYY| 4
-// |YYYY| 8
-// |YYYY| 12
-// +----+
-// |UUVV| 16
-// |UUVV| 20
-// +----+
-
-const int VP8Scan[16 + 4 + 4] = {
-  // Luma
-  0 +  0 * BPS,  4 +  0 * BPS, 8 +  0 * BPS, 12 +  0 * BPS,
-  0 +  4 * BPS,  4 +  4 * BPS, 8 +  4 * BPS, 12 +  4 * BPS,
-  0 +  8 * BPS,  4 +  8 * BPS, 8 +  8 * BPS, 12 +  8 * BPS,
-  0 + 12 * BPS,  4 + 12 * BPS, 8 + 12 * BPS, 12 + 12 * BPS,
-
-  0 + 0 * BPS,   4 + 0 * BPS, 0 + 4 * BPS,  4 + 4 * BPS,    // U
-  8 + 0 * BPS,  12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS     // V
-};
-
-//------------------------------------------------------------------------------
-// Distortion measurement
-
-static const uint16_t kWeightY[16] = {
-  38, 32, 20, 9, 32, 28, 17, 7, 20, 17, 10, 4, 9, 7, 4, 2
-};
-
-static const uint16_t kWeightTrellis[16] = {
-#if USE_TDISTO == 0
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
-#else
-  30, 27, 19, 11,
-  27, 24, 17, 10,
-  19, 17, 12,  8,
-  11, 10,  8,  6
-#endif
-};
-
-// Init/Copy the common fields in score.
-static void InitScore(VP8ModeScore* const rd) {
-  rd->D  = 0;
-  rd->SD = 0;
-  rd->R  = 0;
-  rd->nz = 0;
-  rd->score = MAX_COST;
-}
-
-static void CopyScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
-  dst->D  = src->D;
-  dst->SD = src->SD;
-  dst->R  = src->R;
-  dst->nz = src->nz;      // note that nz is not accumulated, but just copied.
-  dst->score = src->score;
-}
-
-static void AddScore(VP8ModeScore* const dst, const VP8ModeScore* const src) {
-  dst->D  += src->D;
-  dst->SD += src->SD;
-  dst->R  += src->R;
-  dst->nz |= src->nz;     // here, new nz bits are accumulated.
-  dst->score += src->score;
-}
-
-//------------------------------------------------------------------------------
-// Performs trellis-optimized quantization.
-
-// Trellis
-
-typedef struct {
-  int prev;        // best previous
-  int level;       // level
-  int sign;        // sign of coeff_i
-  score_t cost;    // bit cost
-  score_t error;   // distortion = sum of (|coeff_i| - level_i * Q_i)^2
-  int ctx;         // context (only depends on 'level'. Could be spared.)
-} Node;
-
-// If a coefficient was quantized to a value Q (using a neutral bias),
-// we test all alternate possibilities between [Q-MIN_DELTA, Q+MAX_DELTA]
-// We don't test negative values though.
-#define MIN_DELTA 0   // how much lower level to try
-#define MAX_DELTA 1   // how much higher
-#define NUM_NODES (MIN_DELTA + 1 + MAX_DELTA)
-#define NODE(n, l) (nodes[(n) + 1][(l) + MIN_DELTA])
-
-static WEBP_INLINE void SetRDScore(int lambda, VP8ModeScore* const rd) {
-  // TODO: incorporate the "* 256" in the tables?
-  rd->score = rd->R * lambda + 256 * (rd->D + rd->SD);
-}
-
-static WEBP_INLINE score_t RDScoreTrellis(int lambda, score_t rate,
-                                          score_t distortion) {
-  return rate * lambda + 256 * distortion;
-}
-
-static int TrellisQuantizeBlock(const VP8EncIterator* const it,
-                                int16_t in[16], int16_t out[16],
-                                int ctx0, int coeff_type,
-                                const VP8Matrix* const mtx,
-                                int lambda) {
-  ProbaArray* const last_costs = it->enc_->proba_.coeffs_[coeff_type];
-  CostArray* const costs = it->enc_->proba_.level_cost_[coeff_type];
-  const int first = (coeff_type == 0) ? 1 : 0;
-  Node nodes[17][NUM_NODES];
-  int best_path[3] = {-1, -1, -1};   // store best-last/best-level/best-previous
-  score_t best_score;
-  int best_node;
-  int last = first - 1;
-  int n, m, p, nz;
-
-  {
-    score_t cost;
-    score_t max_error;
-    const int thresh = mtx->q_[1] * mtx->q_[1] / 4;
-    const int last_proba = last_costs[VP8EncBands[first]][ctx0][0];
-
-    // compute maximal distortion.
-    max_error = 0;
-    for (n = first; n < 16; ++n) {
-      const int j  = kZigzag[n];
-      const int err = in[j] * in[j];
-      max_error += kWeightTrellis[j] * err;
-      if (err > thresh) last = n;
-    }
-    // we don't need to go inspect up to n = 16 coeffs. We can just go up
-    // to last + 1 (inclusive) without losing much.
-    if (last < 15) ++last;
-
-    // compute 'skip' score. This is the max score one can do.
-    cost = VP8BitCost(0, last_proba);
-    best_score = RDScoreTrellis(lambda, cost, max_error);
-
-    // initialize source node.
-    n = first - 1;
-    for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
-      NODE(n, m).cost = 0;
-      NODE(n, m).error = max_error;
-      NODE(n, m).ctx = ctx0;
-    }
-  }
-
-  // traverse trellis.
-  for (n = first; n <= last; ++n) {
-    const int j  = kZigzag[n];
-    const int Q  = mtx->q_[j];
-    const int iQ = mtx->iq_[j];
-    const int B = BIAS(0x00);     // neutral bias
-    // note: it's important to take sign of the _original_ coeff,
-    // so we don't have to consider level < 0 afterward.
-    const int sign = (in[j] < 0);
-    int coeff0 = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
-    int level0;
-    if (coeff0 > 2047) coeff0 = 2047;
-
-    level0 = QUANTDIV(coeff0, iQ, B);
-    // test all alternate level values around level0.
-    for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
-      Node* const cur = &NODE(n, m);
-      int delta_error, new_error;
-      score_t cur_score = MAX_COST;
-      int level = level0 + m;
-      int last_proba;
-
-      cur->sign = sign;
-      cur->level = level;
-      cur->ctx = (level == 0) ? 0 : (level == 1) ? 1 : 2;
-      if (level >= 2048 || level < 0) {   // node is dead?
-        cur->cost = MAX_COST;
-        continue;
-      }
-      last_proba = last_costs[VP8EncBands[n + 1]][cur->ctx][0];
-
-      // Compute delta_error = how much coding this level will
-      // subtract as distortion to max_error
-      new_error = coeff0 - level * Q;
-      delta_error =
-        kWeightTrellis[j] * (coeff0 * coeff0 - new_error * new_error);
-
-      // Inspect all possible non-dead predecessors. Retain only the best one.
-      for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) {
-        const Node* const prev = &NODE(n - 1, p);
-        const int prev_ctx = prev->ctx;
-        const uint16_t* const tcost = costs[VP8EncBands[n]][prev_ctx];
-        const score_t total_error = prev->error - delta_error;
-        score_t cost, base_cost, score;
-
-        if (prev->cost >= MAX_COST) {   // dead node?
-          continue;
-        }
-
-        // Base cost of both terminal/non-terminal
-        base_cost = prev->cost + VP8LevelCost(tcost, level);
-
-        // Examine node assuming it's a non-terminal one.
-        cost = base_cost;
-        if (level && n < 15) {
-          cost += VP8BitCost(1, last_proba);
-        }
-        score = RDScoreTrellis(lambda, cost, total_error);
-        if (score < cur_score) {
-          cur_score = score;
-          cur->cost  = cost;
-          cur->error = total_error;
-          cur->prev  = p;
-        }
-
-        // Now, record best terminal node (and thus best entry in the graph).
-        if (level) {
-          cost = base_cost;
-          if (n < 15) cost += VP8BitCost(0, last_proba);
-          score = RDScoreTrellis(lambda, cost, total_error);
-          if (score < best_score) {
-            best_score = score;
-            best_path[0] = n;   // best eob position
-            best_path[1] = m;   // best level
-            best_path[2] = p;   // best predecessor
-          }
-        }
-      }
-    }
-  }
-
-  // Fresh start
-  memset(in + first, 0, (16 - first) * sizeof(*in));
-  memset(out + first, 0, (16 - first) * sizeof(*out));
-  if (best_path[0] == -1) {
-    return 0;   // skip!
-  }
-
-  // Unwind the best path.
-  // Note: best-prev on terminal node is not necessarily equal to the
-  // best_prev for non-terminal. So we patch best_path[2] in.
-  n = best_path[0];
-  best_node = best_path[1];
-  NODE(n, best_node).prev = best_path[2];   // force best-prev for terminal
-  nz = 0;
-
-  for (; n >= first; --n) {
-    const Node* const node = &NODE(n, best_node);
-    const int j = kZigzag[n];
-    out[n] = node->sign ? -node->level : node->level;
-    nz |= (node->level != 0);
-    in[j] = out[n] * mtx->q_[j];
-    best_node = node->prev;
-  }
-  return nz;
-}
-
-#undef NODE
-
-//------------------------------------------------------------------------------
-// Performs: difference, transform, quantize, back-transform, add
-// all at once. Output is the reconstructed block in *yuv_out, and the
-// quantized levels in *levels.
-
-static int ReconstructIntra16(VP8EncIterator* const it,
-                              VP8ModeScore* const rd,
-                              uint8_t* const yuv_out,
-                              int mode) {
-  const VP8Encoder* const enc = it->enc_;
-  const uint8_t* const ref = it->yuv_p_ + VP8I16ModeOffsets[mode];
-  const uint8_t* const src = it->yuv_in_ + Y_OFF;
-  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
-  int nz = 0;
-  int n;
-  int16_t tmp[16][16], dc_tmp[16];
-
-  for (n = 0; n < 16; ++n) {
-    VP8FTransform(src + VP8Scan[n], ref + VP8Scan[n], tmp[n]);
-  }
-  VP8FTransformWHT(tmp[0], dc_tmp);
-  nz |= VP8EncQuantizeBlock(dc_tmp, rd->y_dc_levels, 0, &dqm->y2_) << 24;
-
-  if (DO_TRELLIS_I16 && it->do_trellis_) {
-    int x, y;
-    VP8IteratorNzToBytes(it);
-    for (y = 0, n = 0; y < 4; ++y) {
-      for (x = 0; x < 4; ++x, ++n) {
-        const int ctx = it->top_nz_[x] + it->left_nz_[y];
-        const int non_zero =
-           TrellisQuantizeBlock(it, tmp[n], rd->y_ac_levels[n], ctx, 0,
-                                &dqm->y1_, dqm->lambda_trellis_i16_);
-        it->top_nz_[x] = it->left_nz_[y] = non_zero;
-        nz |= non_zero << n;
-      }
-    }
-  } else {
-    for (n = 0; n < 16; ++n) {
-      nz |= VP8EncQuantizeBlock(tmp[n], rd->y_ac_levels[n], 1, &dqm->y1_) << n;
-    }
-  }
-
-  // Transform back
-  VP8ITransformWHT(dc_tmp, tmp[0]);
-  for (n = 0; n < 16; n += 2) {
-    VP8ITransform(ref + VP8Scan[n], tmp[n], yuv_out + VP8Scan[n], 1);
-  }
-
-  return nz;
-}
-
-static int ReconstructIntra4(VP8EncIterator* const it,
-                             int16_t levels[16],
-                             const uint8_t* const src,
-                             uint8_t* const yuv_out,
-                             int mode) {
-  const VP8Encoder* const enc = it->enc_;
-  const uint8_t* const ref = it->yuv_p_ + VP8I4ModeOffsets[mode];
-  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
-  int nz = 0;
-  int16_t tmp[16];
-
-  VP8FTransform(src, ref, tmp);
-  if (DO_TRELLIS_I4 && it->do_trellis_) {
-    const int x = it->i4_ & 3, y = it->i4_ >> 2;
-    const int ctx = it->top_nz_[x] + it->left_nz_[y];
-    nz = TrellisQuantizeBlock(it, tmp, levels, ctx, 3, &dqm->y1_,
-                              dqm->lambda_trellis_i4_);
-  } else {
-    nz = VP8EncQuantizeBlock(tmp, levels, 0, &dqm->y1_);
-  }
-  VP8ITransform(ref, tmp, yuv_out, 0);
-  return nz;
-}
-
-static int ReconstructUV(VP8EncIterator* const it, VP8ModeScore* const rd,
-                         uint8_t* const yuv_out, int mode) {
-  const VP8Encoder* const enc = it->enc_;
-  const uint8_t* const ref = it->yuv_p_ + VP8UVModeOffsets[mode];
-  const uint8_t* const src = it->yuv_in_ + U_OFF;
-  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
-  int nz = 0;
-  int n;
-  int16_t tmp[8][16];
-
-  for (n = 0; n < 8; ++n) {
-    VP8FTransform(src + VP8Scan[16 + n], ref + VP8Scan[16 + n], tmp[n]);
-  }
-  if (DO_TRELLIS_UV && it->do_trellis_) {
-    int ch, x, y;
-    for (ch = 0, n = 0; ch <= 2; ch += 2) {
-      for (y = 0; y < 2; ++y) {
-        for (x = 0; x < 2; ++x, ++n) {
-          const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
-          const int non_zero =
-            TrellisQuantizeBlock(it, tmp[n], rd->uv_levels[n], ctx, 2,
-                                 &dqm->uv_, dqm->lambda_trellis_uv_);
-          it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero;
-          nz |= non_zero << n;
-        }
-      }
-    }
-  } else {
-    for (n = 0; n < 8; ++n) {
-      nz |= VP8EncQuantizeBlock(tmp[n], rd->uv_levels[n], 0, &dqm->uv_) << n;
-    }
-  }
-
-  for (n = 0; n < 8; n += 2) {
-    VP8ITransform(ref + VP8Scan[16 + n], tmp[n], yuv_out + VP8Scan[16 + n], 1);
-  }
-  return (nz << 16);
-}
-
-//------------------------------------------------------------------------------
-// RD-opt decision. Reconstruct each modes, evalue distortion and bit-cost.
-// Pick the mode is lower RD-cost = Rate + lamba * Distortion.
-
-static void SwapPtr(uint8_t** a, uint8_t** b) {
-  uint8_t* const tmp = *a;
-  *a = *b;
-  *b = tmp;
-}
-
-static void SwapOut(VP8EncIterator* const it) {
-  SwapPtr(&it->yuv_out_, &it->yuv_out2_);
-}
-
-static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* const rd) {
-  const VP8Encoder* const enc = it->enc_;
-  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
-  const int lambda = dqm->lambda_i16_;
-  const int tlambda = dqm->tlambda_;
-  const uint8_t* const src = it->yuv_in_ + Y_OFF;
-  VP8ModeScore rd16;
-  int mode;
-
-  rd->mode_i16 = -1;
-  for (mode = 0; mode < 4; ++mode) {
-    uint8_t* const tmp_dst = it->yuv_out2_ + Y_OFF;  // scratch buffer
-    int nz;
-
-    // Reconstruct
-    nz = ReconstructIntra16(it, &rd16, tmp_dst, mode);
-
-    // Measure RD-score
-    rd16.D = VP8SSE16x16(src, tmp_dst);
-    rd16.SD = tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY))
-            : 0;
-    rd16.R = VP8GetCostLuma16(it, &rd16);
-    rd16.R += VP8FixedCostsI16[mode];
-
-    // Since we always examine Intra16 first, we can overwrite *rd directly.
-    SetRDScore(lambda, &rd16);
-    if (mode == 0 || rd16.score < rd->score) {
-      CopyScore(rd, &rd16);
-      rd->mode_i16 = mode;
-      rd->nz = nz;
-      memcpy(rd->y_ac_levels, rd16.y_ac_levels, sizeof(rd16.y_ac_levels));
-      memcpy(rd->y_dc_levels, rd16.y_dc_levels, sizeof(rd16.y_dc_levels));
-      SwapOut(it);
-    }
-  }
-  SetRDScore(dqm->lambda_mode_, rd);   // finalize score for mode decision.
-  VP8SetIntra16Mode(it, rd->mode_i16);
-}
-
-//------------------------------------------------------------------------------
-
-// return the cost array corresponding to the surrounding prediction modes.
-static const uint16_t* GetCostModeI4(VP8EncIterator* const it,
-                                     const uint8_t modes[16]) {
-  const int preds_w = it->enc_->preds_w_;
-  const int x = (it->i4_ & 3), y = it->i4_ >> 2;
-  const int left = (x == 0) ? it->preds_[y * preds_w - 1] : modes[it->i4_ - 1];
-  const int top = (y == 0) ? it->preds_[-preds_w + x] : modes[it->i4_ - 4];
-  return VP8FixedCostsI4[top][left];
-}
-
-static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
-  const VP8Encoder* const enc = it->enc_;
-  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
-  const int lambda = dqm->lambda_i4_;
-  const int tlambda = dqm->tlambda_;
-  const uint8_t* const src0 = it->yuv_in_ + Y_OFF;
-  uint8_t* const best_blocks = it->yuv_out2_ + Y_OFF;
-  int total_header_bits = 0;
-  VP8ModeScore rd_best;
-
-  if (enc->max_i4_header_bits_ == 0) {
-    return 0;
-  }
-
-  InitScore(&rd_best);
-  rd_best.score = 211;  // '211' is the value of VP8BitCost(0, 145)
-  VP8IteratorStartI4(it);
-  do {
-    VP8ModeScore rd_i4;
-    int mode;
-    int best_mode = -1;
-    const uint8_t* const src = src0 + VP8Scan[it->i4_];
-    const uint16_t* const mode_costs = GetCostModeI4(it, rd->modes_i4);
-    uint8_t* best_block = best_blocks + VP8Scan[it->i4_];
-    uint8_t* tmp_dst = it->yuv_p_ + I4TMP;    // scratch buffer.
-
-    InitScore(&rd_i4);
-    VP8MakeIntra4Preds(it);
-    for (mode = 0; mode < NUM_BMODES; ++mode) {
-      VP8ModeScore rd_tmp;
-      int16_t tmp_levels[16];
-
-      // Reconstruct
-      rd_tmp.nz =
-          ReconstructIntra4(it, tmp_levels, src, tmp_dst, mode) << it->i4_;
-
-      // Compute RD-score
-      rd_tmp.D = VP8SSE4x4(src, tmp_dst);
-      rd_tmp.SD =
-          tlambda ? MULT_8B(tlambda, VP8TDisto4x4(src, tmp_dst, kWeightY))
-                  : 0;
-      rd_tmp.R = VP8GetCostLuma4(it, tmp_levels);
-      rd_tmp.R += mode_costs[mode];
-
-      SetRDScore(lambda, &rd_tmp);
-      if (best_mode < 0 || rd_tmp.score < rd_i4.score) {
-        CopyScore(&rd_i4, &rd_tmp);
-        best_mode = mode;
-        SwapPtr(&tmp_dst, &best_block);
-        memcpy(rd_best.y_ac_levels[it->i4_], tmp_levels, sizeof(tmp_levels));
-      }
-    }
-    SetRDScore(dqm->lambda_mode_, &rd_i4);
-    AddScore(&rd_best, &rd_i4);
-    total_header_bits += mode_costs[best_mode];
-    if (rd_best.score >= rd->score ||
-        total_header_bits > enc->max_i4_header_bits_) {
-      return 0;
-    }
-    // Copy selected samples if not in the right place already.
-    if (best_block != best_blocks + VP8Scan[it->i4_])
-      VP8Copy4x4(best_block, best_blocks + VP8Scan[it->i4_]);
-    rd->modes_i4[it->i4_] = best_mode;
-    it->top_nz_[it->i4_ & 3] = it->left_nz_[it->i4_ >> 2] = (rd_i4.nz ? 1 : 0);
-  } while (VP8IteratorRotateI4(it, best_blocks));
-
-  // finalize state
-  CopyScore(rd, &rd_best);
-  VP8SetIntra4Mode(it, rd->modes_i4);
-  SwapOut(it);
-  memcpy(rd->y_ac_levels, rd_best.y_ac_levels, sizeof(rd->y_ac_levels));
-  return 1;   // select intra4x4 over intra16x16
-}
-
-//------------------------------------------------------------------------------
-
-static void PickBestUV(VP8EncIterator* const it, VP8ModeScore* const rd) {
-  const VP8Encoder* const enc = it->enc_;
-  const VP8SegmentInfo* const dqm = &enc->dqm_[it->mb_->segment_];
-  const int lambda = dqm->lambda_uv_;
-  const uint8_t* const src = it->yuv_in_ + U_OFF;
-  uint8_t* const tmp_dst = it->yuv_out2_ + U_OFF;  // scratch buffer
-  uint8_t* const dst0 = it->yuv_out_ + U_OFF;
-  VP8ModeScore rd_best;
-  int mode;
-
-  rd->mode_uv = -1;
-  InitScore(&rd_best);
-  for (mode = 0; mode < 4; ++mode) {
-    VP8ModeScore rd_uv;
-
-    // Reconstruct
-    rd_uv.nz = ReconstructUV(it, &rd_uv, tmp_dst, mode);
-
-    // Compute RD-score
-    rd_uv.D  = VP8SSE16x8(src, tmp_dst);
-    rd_uv.SD = 0;    // TODO: should we call TDisto? it tends to flatten areas.
-    rd_uv.R  = VP8GetCostUV(it, &rd_uv);
-    rd_uv.R += VP8FixedCostsUV[mode];
-
-    SetRDScore(lambda, &rd_uv);
-    if (mode == 0 || rd_uv.score < rd_best.score) {
-      CopyScore(&rd_best, &rd_uv);
-      rd->mode_uv = mode;
-      memcpy(rd->uv_levels, rd_uv.uv_levels, sizeof(rd->uv_levels));
-      memcpy(dst0, tmp_dst, UV_SIZE);   //  TODO: SwapUVOut() ?
-    }
-  }
-  VP8SetIntraUVMode(it, rd->mode_uv);
-  AddScore(rd, &rd_best);
-}
-
-//------------------------------------------------------------------------------
-// Final reconstruction and quantization.
-
-static void SimpleQuantize(VP8EncIterator* const it, VP8ModeScore* const rd) {
-  const VP8Encoder* const enc = it->enc_;
-  const int i16 = (it->mb_->type_ == 1);
-  int nz = 0;
-
-  if (i16) {
-    nz = ReconstructIntra16(it, rd, it->yuv_out_ + Y_OFF, it->preds_[0]);
-  } else {
-    VP8IteratorStartI4(it);
-    do {
-      const int mode =
-          it->preds_[(it->i4_ & 3) + (it->i4_ >> 2) * enc->preds_w_];
-      const uint8_t* const src = it->yuv_in_ + Y_OFF + VP8Scan[it->i4_];
-      uint8_t* const dst = it->yuv_out_ + Y_OFF + VP8Scan[it->i4_];
-      VP8MakeIntra4Preds(it);
-      nz |= ReconstructIntra4(it, rd->y_ac_levels[it->i4_],
-                              src, dst, mode) << it->i4_;
-    } while (VP8IteratorRotateI4(it, it->yuv_out_ + Y_OFF));
-  }
-
-  nz |= ReconstructUV(it, rd, it->yuv_out_ + U_OFF, it->mb_->uv_mode_);
-  rd->nz = nz;
-}
-
-//------------------------------------------------------------------------------
-// Entry point
-
-int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, int rd_opt) {
-  int is_skipped;
-
-  InitScore(rd);
-
-  // We can perform predictions for Luma16x16 and Chroma8x8 already.
-  // Luma4x4 predictions needs to be done as-we-go.
-  VP8MakeLuma16Preds(it);
-  VP8MakeChroma8Preds(it);
-
-  // for rd_opt = 2, we perform trellis-quant on the final decision only.
-  // for rd_opt > 2, we use it for every scoring (=much slower).
-  if (rd_opt > 0) {
-    it->do_trellis_ = (rd_opt > 2);
-    PickBestIntra16(it, rd);
-    if (it->enc_->method_ >= 2) {
-      PickBestIntra4(it, rd);
-    }
-    PickBestUV(it, rd);
-    if (rd_opt == 2) {
-      it->do_trellis_ = 1;
-      SimpleQuantize(it, rd);
-    }
-  } else {
-    // TODO: for method_ == 2, pick the best intra4/intra16 based on SSE
-    it->do_trellis_ = (it->enc_->method_ == 2);
-    SimpleQuantize(it, rd);
-  }
-  is_skipped = (rd->nz == 0);
-  VP8SetSkip(it, is_skipped);
-  return is_skipped;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 437
drivers/webpold/enc/syntax.c

@@ -1,437 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Header syntax writing
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-
-#include "../format_constants.h"
-#include "./vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Helper functions
-
-// TODO(later): Move to webp/format_constants.h?
-static void PutLE24(uint8_t* const data, uint32_t val) {
-  data[0] = (val >>  0) & 0xff;
-  data[1] = (val >>  8) & 0xff;
-  data[2] = (val >> 16) & 0xff;
-}
-
-static void PutLE32(uint8_t* const data, uint32_t val) {
-  PutLE24(data, val);
-  data[3] = (val >> 24) & 0xff;
-}
-
-static int IsVP8XNeeded(const VP8Encoder* const enc) {
-  return !!enc->has_alpha_;  // Currently the only case when VP8X is needed.
-                             // This could change in the future.
-}
-
-static int PutPaddingByte(const WebPPicture* const pic) {
-
-  const uint8_t pad_byte[1] = { 0 };
-  return !!pic->writer(pad_byte, 1, pic);
-}
-
-//------------------------------------------------------------------------------
-// Writers for header's various pieces (in order of appearance)
-
-static WebPEncodingError PutRIFFHeader(const VP8Encoder* const enc,
-                                       size_t riff_size) {
-  const WebPPicture* const pic = enc->pic_;
-  uint8_t riff[RIFF_HEADER_SIZE] = {
-    'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P'
-  };
-  assert(riff_size == (uint32_t)riff_size);
-  PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
-  if (!pic->writer(riff, sizeof(riff), pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-  return VP8_ENC_OK;
-}
-
-static WebPEncodingError PutVP8XHeader(const VP8Encoder* const enc) {
-  const WebPPicture* const pic = enc->pic_;
-  uint8_t vp8x[CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE] = {
-    'V', 'P', '8', 'X'
-  };
-  uint32_t flags = 0;
-
-  assert(IsVP8XNeeded(enc));
-  assert(pic->width >= 1 && pic->height >= 1);
-  assert(pic->width <= MAX_CANVAS_SIZE && pic->height <= MAX_CANVAS_SIZE);
-
-  if (enc->has_alpha_) {
-    flags |= ALPHA_FLAG_BIT;
-  }
-
-  PutLE32(vp8x + TAG_SIZE,              VP8X_CHUNK_SIZE);
-  PutLE32(vp8x + CHUNK_HEADER_SIZE,     flags);
-  PutLE24(vp8x + CHUNK_HEADER_SIZE + 4, pic->width - 1);
-  PutLE24(vp8x + CHUNK_HEADER_SIZE + 7, pic->height - 1);
-  if(!pic->writer(vp8x, sizeof(vp8x), pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-  return VP8_ENC_OK;
-}
-
-static WebPEncodingError PutAlphaChunk(const VP8Encoder* const enc) {
-  const WebPPicture* const pic = enc->pic_;
-  uint8_t alpha_chunk_hdr[CHUNK_HEADER_SIZE] = {
-    'A', 'L', 'P', 'H'
-  };
-
-  assert(enc->has_alpha_);
-
-  // Alpha chunk header.
-  PutLE32(alpha_chunk_hdr + TAG_SIZE, enc->alpha_data_size_);
-  if (!pic->writer(alpha_chunk_hdr, sizeof(alpha_chunk_hdr), pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-
-  // Alpha chunk data.
-  if (!pic->writer(enc->alpha_data_, enc->alpha_data_size_, pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-
-  // Padding.
-  if ((enc->alpha_data_size_ & 1) && !PutPaddingByte(pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-  return VP8_ENC_OK;
-}
-
-static WebPEncodingError PutVP8Header(const WebPPicture* const pic,
-                                      size_t vp8_size) {
-  uint8_t vp8_chunk_hdr[CHUNK_HEADER_SIZE] = {
-    'V', 'P', '8', ' '
-  };
-  assert(vp8_size == (uint32_t)vp8_size);
-  PutLE32(vp8_chunk_hdr + TAG_SIZE, (uint32_t)vp8_size);
-  if (!pic->writer(vp8_chunk_hdr, sizeof(vp8_chunk_hdr), pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-  return VP8_ENC_OK;
-}
-
-static WebPEncodingError PutVP8FrameHeader(const WebPPicture* const pic,
-                                           int profile, size_t size0) {
-  uint8_t vp8_frm_hdr[VP8_FRAME_HEADER_SIZE];
-  uint32_t bits;
-
-  if (size0 >= VP8_MAX_PARTITION0_SIZE) {  // partition #0 is too big to fit
-    return VP8_ENC_ERROR_PARTITION0_OVERFLOW;
-  }
-
-  // Paragraph 9.1.
-  bits = 0                         // keyframe (1b)
-       | (profile << 1)            // profile (3b)
-       | (1 << 4)                  // visible (1b)
-       | ((uint32_t)size0 << 5);   // partition length (19b)
-  vp8_frm_hdr[0] = (bits >>  0) & 0xff;
-  vp8_frm_hdr[1] = (bits >>  8) & 0xff;
-  vp8_frm_hdr[2] = (bits >> 16) & 0xff;
-  // signature
-  vp8_frm_hdr[3] = (VP8_SIGNATURE >> 16) & 0xff;
-  vp8_frm_hdr[4] = (VP8_SIGNATURE >>  8) & 0xff;
-  vp8_frm_hdr[5] = (VP8_SIGNATURE >>  0) & 0xff;
-  // dimensions
-  vp8_frm_hdr[6] = pic->width & 0xff;
-  vp8_frm_hdr[7] = pic->width >> 8;
-  vp8_frm_hdr[8] = pic->height & 0xff;
-  vp8_frm_hdr[9] = pic->height >> 8;
-
-  if (!pic->writer(vp8_frm_hdr, sizeof(vp8_frm_hdr), pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-  return VP8_ENC_OK;
-}
-
-// WebP Headers.
-static int PutWebPHeaders(const VP8Encoder* const enc, size_t size0,
-                          size_t vp8_size, size_t riff_size) {
-  WebPPicture* const pic = enc->pic_;
-  WebPEncodingError err = VP8_ENC_OK;
-
-  // RIFF header.
-  err = PutRIFFHeader(enc, riff_size);
-  if (err != VP8_ENC_OK) goto Error;
-
-  // VP8X.
-  if (IsVP8XNeeded(enc)) {
-    err = PutVP8XHeader(enc);
-    if (err != VP8_ENC_OK) goto Error;
-  }
-
-  // Alpha.
-  if (enc->has_alpha_) {
-    err = PutAlphaChunk(enc);
-    if (err != VP8_ENC_OK) goto Error;
-  }
-
-  // VP8 header.
-  err = PutVP8Header(pic, vp8_size);
-  if (err != VP8_ENC_OK) goto Error;
-
-  // VP8 frame header.
-  err = PutVP8FrameHeader(pic, enc->profile_, size0);
-  if (err != VP8_ENC_OK) goto Error;
-
-  // All OK.
-  return 1;
-
-  // Error.
- Error:
-  return WebPEncodingSetError(pic, err);
-}
-
-// Segmentation header
-static void PutSegmentHeader(VP8BitWriter* const bw,
-                             const VP8Encoder* const enc) {
-  const VP8SegmentHeader* const hdr = &enc->segment_hdr_;
-  const VP8Proba* const proba = &enc->proba_;
-  if (VP8PutBitUniform(bw, (hdr->num_segments_ > 1))) {
-    // We always 'update' the quant and filter strength values
-    const int update_data = 1;
-    int s;
-    VP8PutBitUniform(bw, hdr->update_map_);
-    if (VP8PutBitUniform(bw, update_data)) {
-      // we always use absolute values, not relative ones
-      VP8PutBitUniform(bw, 1);   // (segment_feature_mode = 1. Paragraph 9.3.)
-      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-        VP8PutSignedValue(bw, enc->dqm_[s].quant_, 7);
-      }
-      for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
-        VP8PutSignedValue(bw, enc->dqm_[s].fstrength_, 6);
-      }
-    }
-    if (hdr->update_map_) {
-      for (s = 0; s < 3; ++s) {
-        if (VP8PutBitUniform(bw, (proba->segments_[s] != 255u))) {
-          VP8PutValue(bw, proba->segments_[s], 8);
-        }
-      }
-    }
-  }
-}
-
-// Filtering parameters header
-static void PutFilterHeader(VP8BitWriter* const bw,
-                            const VP8FilterHeader* const hdr) {
-  const int use_lf_delta = (hdr->i4x4_lf_delta_ != 0);
-  VP8PutBitUniform(bw, hdr->simple_);
-  VP8PutValue(bw, hdr->level_, 6);
-  VP8PutValue(bw, hdr->sharpness_, 3);
-  if (VP8PutBitUniform(bw, use_lf_delta)) {
-    // '0' is the default value for i4x4_lf_delta_ at frame #0.
-    const int need_update = (hdr->i4x4_lf_delta_ != 0);
-    if (VP8PutBitUniform(bw, need_update)) {
-      // we don't use ref_lf_delta => emit four 0 bits
-      VP8PutValue(bw, 0, 4);
-      // we use mode_lf_delta for i4x4
-      VP8PutSignedValue(bw, hdr->i4x4_lf_delta_, 6);
-      VP8PutValue(bw, 0, 3);    // all others unused
-    }
-  }
-}
-
-// Nominal quantization parameters
-static void PutQuant(VP8BitWriter* const bw,
-                     const VP8Encoder* const enc) {
-  VP8PutValue(bw, enc->base_quant_, 7);
-  VP8PutSignedValue(bw, enc->dq_y1_dc_, 4);
-  VP8PutSignedValue(bw, enc->dq_y2_dc_, 4);
-  VP8PutSignedValue(bw, enc->dq_y2_ac_, 4);
-  VP8PutSignedValue(bw, enc->dq_uv_dc_, 4);
-  VP8PutSignedValue(bw, enc->dq_uv_ac_, 4);
-}
-
-// Partition sizes
-static int EmitPartitionsSize(const VP8Encoder* const enc,
-                              WebPPicture* const pic) {
-  uint8_t buf[3 * (MAX_NUM_PARTITIONS - 1)];
-  int p;
-  for (p = 0; p < enc->num_parts_ - 1; ++p) {
-    const size_t part_size = VP8BitWriterSize(enc->parts_ + p);
-    if (part_size >= VP8_MAX_PARTITION_SIZE) {
-      return WebPEncodingSetError(pic, VP8_ENC_ERROR_PARTITION_OVERFLOW);
-    }
-    buf[3 * p + 0] = (part_size >>  0) & 0xff;
-    buf[3 * p + 1] = (part_size >>  8) & 0xff;
-    buf[3 * p + 2] = (part_size >> 16) & 0xff;
-  }
-  return p ? pic->writer(buf, 3 * p, pic) : 1;
-}
-
-//------------------------------------------------------------------------------
-
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-
-#define KTRAILER_SIZE 8
-
-static int WriteExtensions(VP8Encoder* const enc) {
-  uint8_t buffer[KTRAILER_SIZE];
-  VP8BitWriter* const bw = &enc->bw_;
-  WebPPicture* const pic = enc->pic_;
-
-  // Layer (bytes 0..3)
-  PutLE24(buffer + 0, enc->layer_data_size_);
-  buffer[3] = enc->pic_->colorspace & WEBP_CSP_UV_MASK;
-  if (enc->layer_data_size_ > 0) {
-    assert(enc->use_layer_);
-    // append layer data to last partition
-    if (!VP8BitWriterAppend(&enc->parts_[enc->num_parts_ - 1],
-                            enc->layer_data_, enc->layer_data_size_)) {
-      return WebPEncodingSetError(pic, VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY);
-    }
-  }
-
-  buffer[KTRAILER_SIZE - 1] = 0x01;  // marker
-  if (!VP8BitWriterAppend(bw, buffer, KTRAILER_SIZE)) {
-    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY);
-  }
-  return 1;
-}
-
-#endif    /* WEBP_EXPERIMENTAL_FEATURES */
-
-//------------------------------------------------------------------------------
-
-static size_t GeneratePartition0(VP8Encoder* const enc) {
-  VP8BitWriter* const bw = &enc->bw_;
-  const int mb_size = enc->mb_w_ * enc->mb_h_;
-  uint64_t pos1, pos2, pos3;
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-  const int need_extensions = enc->use_layer_;
-#endif
-
-  pos1 = VP8BitWriterPos(bw);
-  VP8BitWriterInit(bw, mb_size * 7 / 8);        // ~7 bits per macroblock
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-  VP8PutBitUniform(bw, need_extensions);   // extensions
-#else
-  VP8PutBitUniform(bw, 0);   // colorspace
-#endif
-  VP8PutBitUniform(bw, 0);   // clamp type
-
-  PutSegmentHeader(bw, enc);
-  PutFilterHeader(bw, &enc->filter_hdr_);
-  VP8PutValue(bw, enc->config_->partitions, 2);
-  PutQuant(bw, enc);
-  VP8PutBitUniform(bw, 0);   // no proba update
-  VP8WriteProbas(bw, &enc->proba_);
-  pos2 = VP8BitWriterPos(bw);
-  VP8CodeIntraModes(enc);
-  VP8BitWriterFinish(bw);
-
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-  if (need_extensions && !WriteExtensions(enc)) {
-    return 0;
-  }
-#endif
-
-  pos3 = VP8BitWriterPos(bw);
-
-  if (enc->pic_->stats) {
-    enc->pic_->stats->header_bytes[0] = (int)((pos2 - pos1 + 7) >> 3);
-    enc->pic_->stats->header_bytes[1] = (int)((pos3 - pos2 + 7) >> 3);
-    enc->pic_->stats->alpha_data_size = (int)enc->alpha_data_size_;
-    enc->pic_->stats->layer_data_size = (int)enc->layer_data_size_;
-  }
-  return !bw->error_;
-}
-
-void VP8EncFreeBitWriters(VP8Encoder* const enc) {
-  int p;
-  VP8BitWriterWipeOut(&enc->bw_);
-  for (p = 0; p < enc->num_parts_; ++p) {
-    VP8BitWriterWipeOut(enc->parts_ + p);
-  }
-}
-
-int VP8EncWrite(VP8Encoder* const enc) {
-  WebPPicture* const pic = enc->pic_;
-  VP8BitWriter* const bw = &enc->bw_;
-  const int task_percent = 19;
-  const int percent_per_part = task_percent / enc->num_parts_;
-  const int final_percent = enc->percent_ + task_percent;
-  int ok = 0;
-  size_t vp8_size, pad, riff_size;
-  int p;
-
-  // Partition #0 with header and partition sizes
-  ok = !!GeneratePartition0(enc);
-
-  // Compute VP8 size
-  vp8_size = VP8_FRAME_HEADER_SIZE +
-             VP8BitWriterSize(bw) +
-             3 * (enc->num_parts_ - 1);
-  for (p = 0; p < enc->num_parts_; ++p) {
-    vp8_size += VP8BitWriterSize(enc->parts_ + p);
-  }
-  pad = vp8_size & 1;
-  vp8_size += pad;
-
-  // Compute RIFF size
-  // At the minimum it is: "WEBPVP8 nnnn" + VP8 data size.
-  riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8_size;
-  if (IsVP8XNeeded(enc)) {  // Add size for: VP8X header + data.
-    riff_size += CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
-  }
-  if (enc->has_alpha_) {  // Add size for: ALPH header + data.
-    const uint32_t padded_alpha_size = enc->alpha_data_size_ +
-                                       (enc->alpha_data_size_ & 1);
-    riff_size += CHUNK_HEADER_SIZE + padded_alpha_size;
-  }
-  // Sanity check.
-  if (riff_size > 0xfffffffeU) {
-    return WebPEncodingSetError(pic, VP8_ENC_ERROR_FILE_TOO_BIG);
-  }
-
-  // Emit headers and partition #0
-  {
-    const uint8_t* const part0 = VP8BitWriterBuf(bw);
-    const size_t size0 = VP8BitWriterSize(bw);
-    ok = ok && PutWebPHeaders(enc, size0, vp8_size, riff_size)
-            && pic->writer(part0, size0, pic)
-            && EmitPartitionsSize(enc, pic);
-    VP8BitWriterWipeOut(bw);    // will free the internal buffer.
-  }
-
-  // Token partitions
-  for (p = 0; p < enc->num_parts_; ++p) {
-    const uint8_t* const buf = VP8BitWriterBuf(enc->parts_ + p);
-    const size_t size = VP8BitWriterSize(enc->parts_ + p);
-    if (size)
-      ok = ok && pic->writer(buf, size, pic);
-    VP8BitWriterWipeOut(enc->parts_ + p);    // will free the internal buffer.
-    ok = ok && WebPReportProgress(pic, enc->percent_ + percent_per_part,
-                                  &enc->percent_);
-  }
-
-  // Padding byte
-  if (ok && pad) {
-    ok = PutPaddingByte(pic);
-  }
-
-  enc->coded_size_ = (int)(CHUNK_HEADER_SIZE + riff_size);
-  ok = ok && WebPReportProgress(pic, final_percent, &enc->percent_);
-  return ok;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 510
drivers/webpold/enc/tree.c

@@ -1,510 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Token probabilities
-//
-// Author: Skal ([email protected])
-
-#include "./vp8enci.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Default probabilities
-
-// Paragraph 13.5
-const uint8_t
-  VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
-  // genereated using vp8_default_coef_probs() in entropy.c:129
-  { { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 },
-      { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 },
-      { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 },
-      { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 },
-      { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 },
-    },
-    { { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 },
-      { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 },
-      { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 },
-    },
-    { { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 },
-      { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 },
-      { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 },
-      { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 },
-      { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 },
-      { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 },
-      { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
-    }
-  },
-  { { { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 },
-      { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 },
-      { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 }
-    },
-    { { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 },
-      { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 },
-      { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 }
-    },
-    { { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 },
-      { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 },
-      { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 }
-    },
-    { { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 },
-      { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 },
-      { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 },
-      { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 },
-      { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 }
-    },
-    { { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 },
-      { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 },
-      { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 }
-    },
-    { { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 },
-      { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 },
-      { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 }
-    },
-    { { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 },
-      { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 }
-    }
-  },
-  { { { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 },
-      { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 },
-      { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 }
-    },
-    { { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 },
-      { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 },
-      { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 },
-      { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 },
-      { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 }
-    },
-    { { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 },
-      { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 },
-      { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 },
-      { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    },
-    { { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
-    }
-  },
-  { { { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 },
-      { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 },
-      { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 }
-    },
-    { { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 },
-      { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 },
-      { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 }
-    },
-    { { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 },
-      { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 },
-      { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 }
-    },
-    { { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 },
-      { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 },
-      { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 }
-    },
-    { { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 },
-      { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 },
-      { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 }
-    },
-    { { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 },
-      { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 },
-      { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 }
-    },
-    { { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 },
-      { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 },
-      { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 }
-    },
-    { { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
-      { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
-    }
-  }
-};
-
-void VP8DefaultProbas(VP8Encoder* const enc) {
-  VP8Proba* const probas = &enc->proba_;
-  probas->use_skip_proba_ = 0;
-  memset(probas->segments_, 255u, sizeof(probas->segments_));
-  memcpy(probas->coeffs_, VP8CoeffsProba0, sizeof(VP8CoeffsProba0));
-  // Note: we could hard-code the level_costs_ corresponding to VP8CoeffsProba0,
-  // but that's ~11k of static data. Better call VP8CalculateLevelCosts() later.
-  probas->dirty_ = 1;
-}
-
-// Paragraph 11.5.  900bytes.
-static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = {
-  { { 231, 120, 48, 89, 115, 113, 120, 152, 112 },
-    { 152, 179, 64, 126, 170, 118, 46, 70, 95 },
-    { 175, 69, 143, 80, 85, 82, 72, 155, 103 },
-    { 56, 58, 10, 171, 218, 189, 17, 13, 152 },
-    { 114, 26, 17, 163, 44, 195, 21, 10, 173 },
-    { 121, 24, 80, 195, 26, 62, 44, 64, 85 },
-    { 144, 71, 10, 38, 171, 213, 144, 34, 26 },
-    { 170, 46, 55, 19, 136, 160, 33, 206, 71 },
-    { 63, 20, 8, 114, 114, 208, 12, 9, 226 },
-    { 81, 40, 11, 96, 182, 84, 29, 16, 36 } },
-  { { 134, 183, 89, 137, 98, 101, 106, 165, 148 },
-    { 72, 187, 100, 130, 157, 111, 32, 75, 80 },
-    { 66, 102, 167, 99, 74, 62, 40, 234, 128 },
-    { 41, 53, 9, 178, 241, 141, 26, 8, 107 },
-    { 74, 43, 26, 146, 73, 166, 49, 23, 157 },
-    { 65, 38, 105, 160, 51, 52, 31, 115, 128 },
-    { 104, 79, 12, 27, 217, 255, 87, 17, 7 },
-    { 87, 68, 71, 44, 114, 51, 15, 186, 23 },
-    { 47, 41, 14, 110, 182, 183, 21, 17, 194 },
-    { 66, 45, 25, 102, 197, 189, 23, 18, 22 } },
-  { { 88, 88, 147, 150, 42, 46, 45, 196, 205 },
-    { 43, 97, 183, 117, 85, 38, 35, 179, 61 },
-    { 39, 53, 200, 87, 26, 21, 43, 232, 171 },
-    { 56, 34, 51, 104, 114, 102, 29, 93, 77 },
-    { 39, 28, 85, 171, 58, 165, 90, 98, 64 },
-    { 34, 22, 116, 206, 23, 34, 43, 166, 73 },
-    { 107, 54, 32, 26, 51, 1, 81, 43, 31 },
-    { 68, 25, 106, 22, 64, 171, 36, 225, 114 },
-    { 34, 19, 21, 102, 132, 188, 16, 76, 124 },
-    { 62, 18, 78, 95, 85, 57, 50, 48, 51 } },
-  { { 193, 101, 35, 159, 215, 111, 89, 46, 111 },
-    { 60, 148, 31, 172, 219, 228, 21, 18, 111 },
-    { 112, 113, 77, 85, 179, 255, 38, 120, 114 },
-    { 40, 42, 1, 196, 245, 209, 10, 25, 109 },
-    { 88, 43, 29, 140, 166, 213, 37, 43, 154 },
-    { 61, 63, 30, 155, 67, 45, 68, 1, 209 },
-    { 100, 80, 8, 43, 154, 1, 51, 26, 71 },
-    { 142, 78, 78, 16, 255, 128, 34, 197, 171 },
-    { 41, 40, 5, 102, 211, 183, 4, 1, 221 },
-    { 51, 50, 17, 168, 209, 192, 23, 25, 82 } },
-  { { 138, 31, 36, 171, 27, 166, 38, 44, 229 },
-    { 67, 87, 58, 169, 82, 115, 26, 59, 179 },
-    { 63, 59, 90, 180, 59, 166, 93, 73, 154 },
-    { 40, 40, 21, 116, 143, 209, 34, 39, 175 },
-    { 47, 15, 16, 183, 34, 223, 49, 45, 183 },
-    { 46, 17, 33, 183, 6, 98, 15, 32, 183 },
-    { 57, 46, 22, 24, 128, 1, 54, 17, 37 },
-    { 65, 32, 73, 115, 28, 128, 23, 128, 205 },
-    { 40, 3, 9, 115, 51, 192, 18, 6, 223 },
-    { 87, 37, 9, 115, 59, 77, 64, 21, 47 } },
-  { { 104, 55, 44, 218, 9, 54, 53, 130, 226 },
-    { 64, 90, 70, 205, 40, 41, 23, 26, 57 },
-    { 54, 57, 112, 184, 5, 41, 38, 166, 213 },
-    { 30, 34, 26, 133, 152, 116, 10, 32, 134 },
-    { 39, 19, 53, 221, 26, 114, 32, 73, 255 },
-    { 31, 9, 65, 234, 2, 15, 1, 118, 73 },
-    { 75, 32, 12, 51, 192, 255, 160, 43, 51 },
-    { 88, 31, 35, 67, 102, 85, 55, 186, 85 },
-    { 56, 21, 23, 111, 59, 205, 45, 37, 192 },
-    { 55, 38, 70, 124, 73, 102, 1, 34, 98 } },
-  { { 125, 98, 42, 88, 104, 85, 117, 175, 82 },
-    { 95, 84, 53, 89, 128, 100, 113, 101, 45 },
-    { 75, 79, 123, 47, 51, 128, 81, 171, 1 },
-    { 57, 17, 5, 71, 102, 57, 53, 41, 49 },
-    { 38, 33, 13, 121, 57, 73, 26, 1, 85 },
-    { 41, 10, 67, 138, 77, 110, 90, 47, 114 },
-    { 115, 21, 2, 10, 102, 255, 166, 23, 6 },
-    { 101, 29, 16, 10, 85, 128, 101, 196, 26 },
-    { 57, 18, 10, 102, 102, 213, 34, 20, 43 },
-    { 117, 20, 15, 36, 163, 128, 68, 1, 26 } },
-  { { 102, 61, 71, 37, 34, 53, 31, 243, 192 },
-    { 69, 60, 71, 38, 73, 119, 28, 222, 37 },
-    { 68, 45, 128, 34, 1, 47, 11, 245, 171 },
-    { 62, 17, 19, 70, 146, 85, 55, 62, 70 },
-    { 37, 43, 37, 154, 100, 163, 85, 160, 1 },
-    { 63, 9, 92, 136, 28, 64, 32, 201, 85 },
-    { 75, 15, 9, 9, 64, 255, 184, 119, 16 },
-    { 86, 6, 28, 5, 64, 255, 25, 248, 1 },
-    { 56, 8, 17, 132, 137, 255, 55, 116, 128 },
-    { 58, 15, 20, 82, 135, 57, 26, 121, 40 } },
-  { { 164, 50, 31, 137, 154, 133, 25, 35, 218 },
-    { 51, 103, 44, 131, 131, 123, 31, 6, 158 },
-    { 86, 40, 64, 135, 148, 224, 45, 183, 128 },
-    { 22, 26, 17, 131, 240, 154, 14, 1, 209 },
-    { 45, 16, 21, 91, 64, 222, 7, 1, 197 },
-    { 56, 21, 39, 155, 60, 138, 23, 102, 213 },
-    { 83, 12, 13, 54, 192, 255, 68, 47, 28 },
-    { 85, 26, 85, 85, 128, 128, 32, 146, 171 },
-    { 18, 11, 7, 63, 144, 171, 4, 4, 246 },
-    { 35, 27, 10, 146, 174, 171, 12, 26, 128 } },
-  { { 190, 80, 35, 99, 180, 80, 126, 54, 45 },
-    { 85, 126, 47, 87, 176, 51, 41, 20, 32 },
-    { 101, 75, 128, 139, 118, 146, 116, 128, 85 },
-    { 56, 41, 15, 176, 236, 85, 37, 9, 62 },
-    { 71, 30, 17, 119, 118, 255, 17, 18, 138 },
-    { 101, 38, 60, 138, 55, 70, 43, 26, 142 },
-    { 146, 36, 19, 30, 171, 255, 97, 27, 20 },
-    { 138, 45, 61, 62, 219, 1, 81, 188, 64 },
-    { 32, 41, 20, 117, 151, 142, 20, 21, 163 },
-    { 112, 19, 12, 61, 195, 128, 48, 4, 24 } }
-};
-
-static int PutI4Mode(VP8BitWriter* const bw, int mode,
-                     const uint8_t* const prob) {
-  if (VP8PutBit(bw, mode != B_DC_PRED, prob[0])) {
-    if (VP8PutBit(bw, mode != B_TM_PRED, prob[1])) {
-      if (VP8PutBit(bw, mode != B_VE_PRED, prob[2])) {
-        if (!VP8PutBit(bw, mode >= B_LD_PRED, prob[3])) {
-          if (VP8PutBit(bw, mode != B_HE_PRED, prob[4])) {
-            VP8PutBit(bw, mode != B_RD_PRED, prob[5]);
-          }
-        } else {
-          if (VP8PutBit(bw, mode != B_LD_PRED, prob[6])) {
-            if (VP8PutBit(bw, mode != B_VL_PRED, prob[7])) {
-              VP8PutBit(bw, mode != B_HD_PRED, prob[8]);
-            }
-          }
-        }
-      }
-    }
-  }
-  return mode;
-}
-
-static void PutI16Mode(VP8BitWriter* const bw, int mode) {
-  if (VP8PutBit(bw, (mode == TM_PRED || mode == H_PRED), 156)) {
-    VP8PutBit(bw, mode == TM_PRED, 128);    // TM or HE
-  } else {
-    VP8PutBit(bw, mode == V_PRED, 163);     // VE or DC
-  }
-}
-
-static void PutUVMode(VP8BitWriter* const bw, int uv_mode) {
-  if (VP8PutBit(bw, uv_mode != DC_PRED, 142)) {
-    if (VP8PutBit(bw, uv_mode != V_PRED, 114)) {
-      VP8PutBit(bw, uv_mode != H_PRED, 183);    // else: TM_PRED
-    }
-  }
-}
-
-static void PutSegment(VP8BitWriter* const bw, int s, const uint8_t* p) {
-  if (VP8PutBit(bw, s >= 2, p[0])) p += 1;
-  VP8PutBit(bw, s & 1, p[1]);
-}
-
-void VP8CodeIntraModes(VP8Encoder* const enc) {
-  VP8BitWriter* const bw = &enc->bw_;
-  VP8EncIterator it;
-  VP8IteratorInit(enc, &it);
-  do {
-    const VP8MBInfo* mb = it.mb_;
-    const uint8_t* preds = it.preds_;
-    if (enc->segment_hdr_.update_map_) {
-      PutSegment(bw, mb->segment_, enc->proba_.segments_);
-    }
-    if (enc->proba_.use_skip_proba_) {
-      VP8PutBit(bw, mb->skip_, enc->proba_.skip_proba_);
-    }
-    if (VP8PutBit(bw, (mb->type_ != 0), 145)) {  // i16x16
-      PutI16Mode(bw, preds[0]);
-    } else {
-      const int preds_w = enc->preds_w_;
-      const uint8_t* top_pred = preds - preds_w;
-      int x, y;
-      for (y = 0; y < 4; ++y) {
-        int left = preds[-1];
-        for (x = 0; x < 4; ++x) {
-          const uint8_t* const probas = kBModesProba[top_pred[x]][left];
-          left = PutI4Mode(bw, preds[x], probas);
-        }
-        top_pred = preds;
-        preds += preds_w;
-      }
-    }
-    PutUVMode(bw, mb->uv_mode_);
-  } while (VP8IteratorNext(&it, 0));
-}
-
-//------------------------------------------------------------------------------
-// Paragraph 13
-
-const uint8_t
-    VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS] = {
-  { { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 },
-      { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  },
-  { { { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 },
-      { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 }
-    },
-    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  },
-  { { { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  },
-  { { { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 },
-      { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    },
-    { { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
-      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
-    }
-  }
-};
-
-void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas) {
-  int t, b, c, p;
-  for (t = 0; t < NUM_TYPES; ++t) {
-    for (b = 0; b < NUM_BANDS; ++b) {
-      for (c = 0; c < NUM_CTX; ++c) {
-        for (p = 0; p < NUM_PROBAS; ++p) {
-          const uint8_t p0 = probas->coeffs_[t][b][c][p];
-          const int update = (p0 != VP8CoeffsProba0[t][b][c][p]);
-          if (VP8PutBit(bw, update, VP8CoeffsUpdateProba[t][b][c][p])) {
-            VP8PutValue(bw, p0, 8);
-          }
-        }
-      }
-    }
-  }
-  if (VP8PutBitUniform(bw, probas->use_skip_proba_)) {
-    VP8PutValue(bw, probas->skip_proba_, 8);
-  }
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 525
drivers/webpold/enc/vp8enci.h

@@ -1,525 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//   WebP encoder: internal header.
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_ENC_VP8ENCI_H_
-#define WEBP_ENC_VP8ENCI_H_
-
-#include <string.h>     // for memcpy()
-#include "../encode.h"
-#include "../dsp/dsp.h"
-#include "../utils/bit_writer.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Various defines and enums
-
-// version numbers
-#define ENC_MAJ_VERSION 0
-#define ENC_MIN_VERSION 2
-#define ENC_REV_VERSION 0
-
-// size of histogram used by CollectHistogram.
-#define MAX_COEFF_THRESH   64
-
-// intra prediction modes
-enum { B_DC_PRED = 0,   // 4x4 modes
-       B_TM_PRED = 1,
-       B_VE_PRED = 2,
-       B_HE_PRED = 3,
-       B_RD_PRED = 4,
-       B_VR_PRED = 5,
-       B_LD_PRED = 6,
-       B_VL_PRED = 7,
-       B_HD_PRED = 8,
-       B_HU_PRED = 9,
-       NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED,  // = 10
-
-       // Luma16 or UV modes
-       DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED,
-       H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED
-     };
-
-enum { NUM_MB_SEGMENTS = 4,
-       MAX_NUM_PARTITIONS = 8,
-       NUM_TYPES = 4,   // 0: i16-AC,  1: i16-DC,  2:chroma-AC,  3:i4-AC
-       NUM_BANDS = 8,
-       NUM_CTX = 3,
-       NUM_PROBAS = 11,
-       MAX_LF_LEVELS = 64,      // Maximum loop filter level
-       MAX_VARIABLE_LEVEL = 67  // last (inclusive) level with variable cost
-     };
-
-// YUV-cache parameters. Cache is 16-pixels wide.
-// The original or reconstructed samples can be accessed using VP8Scan[]
-// The predicted blocks can be accessed using offsets to yuv_p_ and
-// the arrays VP8*ModeOffsets[];
-//         +----+      YUV Samples area. See VP8Scan[] for accessing the blocks.
-//  Y_OFF  |YYYY| <- original samples  (enc->yuv_in_)
-//         |YYYY|
-//         |YYYY|
-//         |YYYY|
-//  U_OFF  |UUVV| V_OFF  (=U_OFF + 8)
-//         |UUVV|
-//         +----+
-//  Y_OFF  |YYYY| <- compressed/decoded samples  ('yuv_out_')
-//         |YYYY|    There are two buffers like this ('yuv_out_'/'yuv_out2_')
-//         |YYYY|
-//         |YYYY|
-//  U_OFF  |UUVV| V_OFF
-//         |UUVV|
-//          x2 (for yuv_out2_)
-//         +----+     Prediction area ('yuv_p_', size = PRED_SIZE)
-// I16DC16 |YYYY|  Intra16 predictions (16x16 block each)
-//         |YYYY|
-//         |YYYY|
-//         |YYYY|
-// I16TM16 |YYYY|
-//         |YYYY|
-//         |YYYY|
-//         |YYYY|
-// I16VE16 |YYYY|
-//         |YYYY|
-//         |YYYY|
-//         |YYYY|
-// I16HE16 |YYYY|
-//         |YYYY|
-//         |YYYY|
-//         |YYYY|
-//         +----+  Chroma U/V predictions (16x8 block each)
-// C8DC8   |UUVV|
-//         |UUVV|
-// C8TM8   |UUVV|
-//         |UUVV|
-// C8VE8   |UUVV|
-//         |UUVV|
-// C8HE8   |UUVV|
-//         |UUVV|
-//         +----+  Intra 4x4 predictions (4x4 block each)
-//         |YYYY| I4DC4 I4TM4 I4VE4 I4HE4
-//         |YYYY| I4RD4 I4VR4 I4LD4 I4VL4
-//         |YY..| I4HD4 I4HU4 I4TMP
-//         +----+
-#define BPS       16   // this is the common stride
-#define Y_SIZE   (BPS * 16)
-#define UV_SIZE  (BPS * 8)
-#define YUV_SIZE (Y_SIZE + UV_SIZE)
-#define PRED_SIZE (6 * 16 * BPS + 12 * BPS)
-#define Y_OFF    (0)
-#define U_OFF    (Y_SIZE)
-#define V_OFF    (U_OFF + 8)
-#define ALIGN_CST 15
-#define DO_ALIGN(PTR) ((uintptr_t)((PTR) + ALIGN_CST) & ~ALIGN_CST)
-
-extern const int VP8Scan[16 + 4 + 4];           // in quant.c
-extern const int VP8UVModeOffsets[4];           // in analyze.c
-extern const int VP8I16ModeOffsets[4];
-extern const int VP8I4ModeOffsets[NUM_BMODES];
-
-// Layout of prediction blocks
-// intra 16x16
-#define I16DC16 (0 * 16 * BPS)
-#define I16TM16 (1 * 16 * BPS)
-#define I16VE16 (2 * 16 * BPS)
-#define I16HE16 (3 * 16 * BPS)
-// chroma 8x8, two U/V blocks side by side (hence: 16x8 each)
-#define C8DC8 (4 * 16 * BPS)
-#define C8TM8 (4 * 16 * BPS + 8 * BPS)
-#define C8VE8 (5 * 16 * BPS)
-#define C8HE8 (5 * 16 * BPS + 8 * BPS)
-// intra 4x4
-#define I4DC4 (6 * 16 * BPS +  0)
-#define I4TM4 (6 * 16 * BPS +  4)
-#define I4VE4 (6 * 16 * BPS +  8)
-#define I4HE4 (6 * 16 * BPS + 12)
-#define I4RD4 (6 * 16 * BPS + 4 * BPS +  0)
-#define I4VR4 (6 * 16 * BPS + 4 * BPS +  4)
-#define I4LD4 (6 * 16 * BPS + 4 * BPS +  8)
-#define I4VL4 (6 * 16 * BPS + 4 * BPS + 12)
-#define I4HD4 (6 * 16 * BPS + 8 * BPS +  0)
-#define I4HU4 (6 * 16 * BPS + 8 * BPS +  4)
-#define I4TMP (6 * 16 * BPS + 8 * BPS +  8)
-
-typedef int64_t score_t;     // type used for scores, rate, distortion
-#define MAX_COST ((score_t)0x7fffffffffffffLL)
-
-#define QFIX 17
-#define BIAS(b)  ((b) << (QFIX - 8))
-// Fun fact: this is the _only_ line where we're actually being lossy and
-// discarding bits.
-static WEBP_INLINE int QUANTDIV(int n, int iQ, int B) {
-  return (n * iQ + B) >> QFIX;
-}
-extern const uint8_t VP8Zigzag[16];
-
-//------------------------------------------------------------------------------
-// Headers
-
-typedef uint32_t proba_t;   // 16b + 16b
-typedef uint8_t ProbaArray[NUM_CTX][NUM_PROBAS];
-typedef proba_t StatsArray[NUM_CTX][NUM_PROBAS];
-typedef uint16_t CostArray[NUM_CTX][MAX_VARIABLE_LEVEL + 1];
-typedef double LFStats[NUM_MB_SEGMENTS][MAX_LF_LEVELS];  // filter stats
-
-typedef struct VP8Encoder VP8Encoder;
-
-// segment features
-typedef struct {
-  int num_segments_;      // Actual number of segments. 1 segment only = unused.
-  int update_map_;        // whether to update the segment map or not.
-                          // must be 0 if there's only 1 segment.
-  int size_;              // bit-cost for transmitting the segment map
-} VP8SegmentHeader;
-
-// Struct collecting all frame-persistent probabilities.
-typedef struct {
-  uint8_t segments_[3];     // probabilities for segment tree
-  uint8_t skip_proba_;      // final probability of being skipped.
-  ProbaArray coeffs_[NUM_TYPES][NUM_BANDS];      // 924 bytes
-  StatsArray stats_[NUM_TYPES][NUM_BANDS];       // 4224 bytes
-  CostArray level_cost_[NUM_TYPES][NUM_BANDS];   // 11.4k
-  int dirty_;               // if true, need to call VP8CalculateLevelCosts()
-  int use_skip_proba_;      // Note: we always use skip_proba for now.
-  int nb_skip_;             // number of skipped blocks
-} VP8Proba;
-
-// Filter parameters. Not actually used in the code (we don't perform
-// the in-loop filtering), but filled from user's config
-typedef struct {
-  int simple_;             // filtering type: 0=complex, 1=simple
-  int level_;              // base filter level [0..63]
-  int sharpness_;          // [0..7]
-  int i4x4_lf_delta_;      // delta filter level for i4x4 relative to i16x16
-} VP8FilterHeader;
-
-//------------------------------------------------------------------------------
-// Informations about the macroblocks.
-
-typedef struct {
-  // block type
-  unsigned int type_:2;     // 0=i4x4, 1=i16x16
-  unsigned int uv_mode_:2;
-  unsigned int skip_:1;
-  unsigned int segment_:2;
-  uint8_t alpha_;      // quantization-susceptibility
-} VP8MBInfo;
-
-typedef struct VP8Matrix {
-  uint16_t q_[16];        // quantizer steps
-  uint16_t iq_[16];       // reciprocals, fixed point.
-  uint16_t bias_[16];     // rounding bias
-  uint16_t zthresh_[16];  // value under which a coefficient is zeroed
-  uint16_t sharpen_[16];  // frequency boosters for slight sharpening
-} VP8Matrix;
-
-typedef struct {
-  VP8Matrix y1_, y2_, uv_;  // quantization matrices
-  int alpha_;      // quant-susceptibility, range [-127,127]. Zero is neutral.
-                   // Lower values indicate a lower risk of blurriness.
-  int beta_;       // filter-susceptibility, range [0,255].
-  int quant_;      // final segment quantizer.
-  int fstrength_;  // final in-loop filtering strength
-  // reactivities
-  int lambda_i16_, lambda_i4_, lambda_uv_;
-  int lambda_mode_, lambda_trellis_, tlambda_;
-  int lambda_trellis_i16_, lambda_trellis_i4_, lambda_trellis_uv_;
-} VP8SegmentInfo;
-
-// Handy transcient struct to accumulate score and info during RD-optimization
-// and mode evaluation.
-typedef struct {
-  score_t D, SD, R, score;    // Distortion, spectral distortion, rate, score.
-  int16_t y_dc_levels[16];    // Quantized levels for luma-DC, luma-AC, chroma.
-  int16_t y_ac_levels[16][16];
-  int16_t uv_levels[4 + 4][16];
-  int mode_i16;               // mode number for intra16 prediction
-  uint8_t modes_i4[16];       // mode numbers for intra4 predictions
-  int mode_uv;                // mode number of chroma prediction
-  uint32_t nz;                // non-zero blocks
-} VP8ModeScore;
-
-// Iterator structure to iterate through macroblocks, pointing to the
-// right neighbouring data (samples, predictions, contexts, ...)
-typedef struct {
-  int x_, y_;                      // current macroblock
-  int y_offset_, uv_offset_;       // offset to the luma / chroma planes
-  int y_stride_, uv_stride_;       // respective strides
-  uint8_t*      yuv_in_;           // borrowed from enc_ (for now)
-  uint8_t*      yuv_out_;          // ''
-  uint8_t*      yuv_out2_;         // ''
-  uint8_t*      yuv_p_;            // ''
-  VP8Encoder*   enc_;              // back-pointer
-  VP8MBInfo*    mb_;               // current macroblock
-  VP8BitWriter* bw_;               // current bit-writer
-  uint8_t*      preds_;            // intra mode predictors (4x4 blocks)
-  uint32_t*     nz_;               // non-zero pattern
-  uint8_t       i4_boundary_[37];  // 32+5 boundary samples needed by intra4x4
-  uint8_t*      i4_top_;           // pointer to the current top boundary sample
-  int           i4_;               // current intra4x4 mode being tested
-  int           top_nz_[9];        // top-non-zero context.
-  int           left_nz_[9];       // left-non-zero. left_nz[8] is independent.
-  uint64_t      bit_count_[4][3];  // bit counters for coded levels.
-  uint64_t      luma_bits_;        // macroblock bit-cost for luma
-  uint64_t      uv_bits_;          // macroblock bit-cost for chroma
-  LFStats*      lf_stats_;         // filter stats (borrowed from enc_)
-  int           do_trellis_;       // if true, perform extra level optimisation
-  int           done_;             // true when scan is finished
-  int           percent0_;         // saved initial progress percent
-} VP8EncIterator;
-
-  // in iterator.c
-// must be called first.
-void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it);
-// restart a scan.
-void VP8IteratorReset(VP8EncIterator* const it);
-// import samples from source
-void VP8IteratorImport(const VP8EncIterator* const it);
-// export decimated samples
-void VP8IteratorExport(const VP8EncIterator* const it);
-// go to next macroblock. Returns !done_. If *block_to_save is non-null, will
-// save the boundary values to top_/left_ arrays. block_to_save can be
-// it->yuv_out_ or it->yuv_in_.
-int VP8IteratorNext(VP8EncIterator* const it,
-                    const uint8_t* const block_to_save);
-// Report progression based on macroblock rows. Return 0 for user-abort request.
-int VP8IteratorProgress(const VP8EncIterator* const it,
-                        int final_delta_percent);
-// Intra4x4 iterations
-void VP8IteratorStartI4(VP8EncIterator* const it);
-// returns true if not done.
-int VP8IteratorRotateI4(VP8EncIterator* const it,
-                        const uint8_t* const yuv_out);
-
-// Non-zero context setup/teardown
-void VP8IteratorNzToBytes(VP8EncIterator* const it);
-void VP8IteratorBytesToNz(VP8EncIterator* const it);
-
-// Helper functions to set mode properties
-void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode);
-void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes);
-void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode);
-void VP8SetSkip(const VP8EncIterator* const it, int skip);
-void VP8SetSegment(const VP8EncIterator* const it, int segment);
-
-//------------------------------------------------------------------------------
-// Paginated token buffer
-
-// WIP: #define USE_TOKEN_BUFFER
-
-#ifdef USE_TOKEN_BUFFER
-
-#define MAX_NUM_TOKEN 2048
-
-typedef struct VP8Tokens VP8Tokens;
-struct VP8Tokens {
-  uint16_t tokens_[MAX_NUM_TOKEN];  // bit#15: bit, bits 0..14: slot
-  int left_;
-  VP8Tokens* next_;
-};
-
-typedef struct {
-  VP8Tokens* rows_;
-  uint16_t* tokens_;    // set to (*last_)->tokens_
-  VP8Tokens** last_;
-  int left_;
-  int error_;  // true in case of malloc error
-} VP8TBuffer;
-
-void VP8TBufferInit(VP8TBuffer* const b);    // initialize an empty buffer
-int VP8TBufferNewPage(VP8TBuffer* const b);  // allocate a new page
-void VP8TBufferClear(VP8TBuffer* const b);   // de-allocate memory
-
-int VP8EmitTokens(const VP8TBuffer* const b, VP8BitWriter* const bw,
-                  const uint8_t* const probas);
-
-static WEBP_INLINE int VP8AddToken(VP8TBuffer* const b,
-                                   int bit, int proba_idx) {
-  if (b->left_ > 0 || VP8TBufferNewPage(b)) {
-    const int slot = --b->left_;
-    b->tokens_[slot] = (bit << 15) | proba_idx;
-  }
-  return bit;
-}
-
-#endif  // USE_TOKEN_BUFFER
-
-//------------------------------------------------------------------------------
-// VP8Encoder
-
-struct VP8Encoder {
-  const WebPConfig* config_;    // user configuration and parameters
-  WebPPicture* pic_;            // input / output picture
-
-  // headers
-  VP8FilterHeader   filter_hdr_;     // filtering information
-  VP8SegmentHeader  segment_hdr_;    // segment information
-
-  int profile_;                      // VP8's profile, deduced from Config.
-
-  // dimension, in macroblock units.
-  int mb_w_, mb_h_;
-  int preds_w_;   // stride of the *preds_ prediction plane (=4*mb_w + 1)
-
-  // number of partitions (1, 2, 4 or 8 = MAX_NUM_PARTITIONS)
-  int num_parts_;
-
-  // per-partition boolean decoders.
-  VP8BitWriter bw_;                         // part0
-  VP8BitWriter parts_[MAX_NUM_PARTITIONS];  // token partitions
-
-  int percent_;                             // for progress
-
-  // transparency blob
-  int has_alpha_;
-  uint8_t* alpha_data_;       // non-NULL if transparency is present
-  uint32_t alpha_data_size_;
-
-  // enhancement layer
-  int use_layer_;
-  VP8BitWriter layer_bw_;
-  uint8_t* layer_data_;
-  size_t layer_data_size_;
-
-  // quantization info (one set of DC/AC dequant factor per segment)
-  VP8SegmentInfo dqm_[NUM_MB_SEGMENTS];
-  int base_quant_;                 // nominal quantizer value. Only used
-                                   // for relative coding of segments' quant.
-  int uv_alpha_;                   // U/V quantization susceptibility
-  // global offset of quantizers, shared by all segments
-  int dq_y1_dc_;
-  int dq_y2_dc_, dq_y2_ac_;
-  int dq_uv_dc_, dq_uv_ac_;
-
-  // probabilities and statistics
-  VP8Proba proba_;
-  uint64_t sse_[4];        // sum of Y/U/V/A squared errors for all macroblocks
-  uint64_t sse_count_;     // pixel count for the sse_[] stats
-  int      coded_size_;
-  int      residual_bytes_[3][4];
-  int      block_count_[3];
-
-  // quality/speed settings
-  int method_;              // 0=fastest, 6=best/slowest.
-  int rd_opt_level_;        // Deduced from method_.
-  int max_i4_header_bits_;  // partition #0 safeness factor
-
-  // Memory
-  VP8MBInfo* mb_info_;   // contextual macroblock infos (mb_w_ + 1)
-  uint8_t*   preds_;     // predictions modes: (4*mb_w+1) * (4*mb_h+1)
-  uint32_t*  nz_;        // non-zero bit context: mb_w+1
-  uint8_t*   yuv_in_;    // input samples
-  uint8_t*   yuv_out_;   // output samples
-  uint8_t*   yuv_out2_;  // secondary scratch out-buffer. swapped with yuv_out_.
-  uint8_t*   yuv_p_;     // scratch buffer for prediction
-  uint8_t   *y_top_;     // top luma samples.
-  uint8_t   *uv_top_;    // top u/v samples.
-                         // U and V are packed into 16 pixels (8 U + 8 V)
-  uint8_t   *y_left_;    // left luma samples (adressable from index -1 to 15).
-  uint8_t   *u_left_;    // left u samples (adressable from index -1 to 7)
-  uint8_t   *v_left_;    // left v samples (adressable from index -1 to 7)
-
-  LFStats   *lf_stats_;  // autofilter stats (if NULL, autofilter is off)
-};
-
-//------------------------------------------------------------------------------
-// internal functions. Not public.
-
-  // in tree.c
-extern const uint8_t VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
-extern const uint8_t
-    VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
-// Reset the token probabilities to their initial (default) values
-void VP8DefaultProbas(VP8Encoder* const enc);
-// Write the token probabilities
-void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas);
-// Writes the partition #0 modes (that is: all intra modes)
-void VP8CodeIntraModes(VP8Encoder* const enc);
-
-  // in syntax.c
-// Generates the final bitstream by coding the partition0 and headers,
-// and appending an assembly of all the pre-coded token partitions.
-// Return true if everything is ok.
-int VP8EncWrite(VP8Encoder* const enc);
-// Release memory allocated for bit-writing in VP8EncLoop & seq.
-void VP8EncFreeBitWriters(VP8Encoder* const enc);
-
-  // in frame.c
-extern const uint8_t VP8EncBands[16 + 1];
-// Form all the four Intra16x16 predictions in the yuv_p_ cache
-void VP8MakeLuma16Preds(const VP8EncIterator* const it);
-// Form all the four Chroma8x8 predictions in the yuv_p_ cache
-void VP8MakeChroma8Preds(const VP8EncIterator* const it);
-// Form all the ten Intra4x4 predictions in the yuv_p_ cache
-// for the 4x4 block it->i4_
-void VP8MakeIntra4Preds(const VP8EncIterator* const it);
-// Rate calculation
-int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd);
-int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]);
-int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd);
-// Main stat / coding passes
-int VP8EncLoop(VP8Encoder* const enc);
-int VP8StatLoop(VP8Encoder* const enc);
-
-  // in webpenc.c
-// Assign an error code to a picture. Return false for convenience.
-int WebPEncodingSetError(const WebPPicture* const pic, WebPEncodingError error);
-int WebPReportProgress(const WebPPicture* const pic,
-                       int percent, int* const percent_store);
-
-  // in analysis.c
-// Main analysis loop. Decides the segmentations and complexity.
-// Assigns a first guess for Intra16 and uvmode_ prediction modes.
-int VP8EncAnalyze(VP8Encoder* const enc);
-
-  // in quant.c
-// Sets up segment's quantization values, base_quant_ and filter strengths.
-void VP8SetSegmentParams(VP8Encoder* const enc, float quality);
-// Pick best modes and fills the levels. Returns true if skipped.
-int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, int rd_opt);
-
-  // in alpha.c
-void VP8EncInitAlpha(VP8Encoder* const enc);    // initialize alpha compression
-int VP8EncFinishAlpha(VP8Encoder* const enc);   // finalize compressed data
-void VP8EncDeleteAlpha(VP8Encoder* const enc);  // delete compressed data
-
-  // in layer.c
-void VP8EncInitLayer(VP8Encoder* const enc);     // init everything
-void VP8EncCodeLayerBlock(VP8EncIterator* it);   // code one more macroblock
-int VP8EncFinishLayer(VP8Encoder* const enc);    // finalize coding
-void VP8EncDeleteLayer(VP8Encoder* enc);         // reclaim memory
-
-  // in filter.c
-
-// SSIM utils
-typedef struct {
-  double w, xm, ym, xxm, xym, yym;
-} DistoStats;
-void VP8SSIMAddStats(const DistoStats* const src, DistoStats* const dst);
-void VP8SSIMAccumulatePlane(const uint8_t* src1, int stride1,
-                            const uint8_t* src2, int stride2,
-                            int W, int H, DistoStats* const stats);
-double VP8SSIMGet(const DistoStats* const stats);
-double VP8SSIMGetSquaredError(const DistoStats* const stats);
-
-// autofilter
-void VP8InitFilter(VP8EncIterator* const it);
-void VP8StoreFilterStats(VP8EncIterator* const it);
-void VP8AdjustFilterStrength(VP8EncIterator* const it);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_ENC_VP8ENCI_H_ */

+ 0 - 1150
drivers/webpold/enc/vp8l.c

@@ -1,1150 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// main entry for the lossless encoder.
-//
-// Author: Vikas Arora ([email protected])
-//
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "./backward_references.h"
-#include "./vp8enci.h"
-#include "./vp8li.h"
-#include "../dsp/lossless.h"
-#include "../utils/bit_writer.h"
-#include "../utils/huffman_encode.h"
-#include "../utils/utils.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define PALETTE_KEY_RIGHT_SHIFT   22  // Key for 1K buffer.
-#define MAX_HUFF_IMAGE_SIZE       (16 * 1024 * 1024)
-#define MAX_COLORS_FOR_GRAPH      64
-
-// -----------------------------------------------------------------------------
-// Palette
-
-static int CompareColors(const void* p1, const void* p2) {
-  const uint32_t a = *(const uint32_t*)p1;
-  const uint32_t b = *(const uint32_t*)p2;
-  return (a < b) ? -1 : (a > b) ? 1 : 0;
-}
-
-// If number of colors in the image is less than or equal to MAX_PALETTE_SIZE,
-// creates a palette and returns true, else returns false.
-static int AnalyzeAndCreatePalette(const WebPPicture* const pic,
-                                   uint32_t palette[MAX_PALETTE_SIZE],
-                                   int* const palette_size) {
-  int i, x, y, key;
-  int num_colors = 0;
-  uint8_t in_use[MAX_PALETTE_SIZE * 4] = { 0 };
-  uint32_t colors[MAX_PALETTE_SIZE * 4];
-  static const uint32_t kHashMul = 0x1e35a7bd;
-  const uint32_t* argb = pic->argb;
-  const int width = pic->width;
-  const int height = pic->height;
-  uint32_t last_pix = ~argb[0];   // so we're sure that last_pix != argb[0]
-
-  for (y = 0; y < height; ++y) {
-    for (x = 0; x < width; ++x) {
-      if (argb[x] == last_pix) {
-        continue;
-      }
-      last_pix = argb[x];
-      key = (kHashMul * last_pix) >> PALETTE_KEY_RIGHT_SHIFT;
-      while (1) {
-        if (!in_use[key]) {
-          colors[key] = last_pix;
-          in_use[key] = 1;
-          ++num_colors;
-          if (num_colors > MAX_PALETTE_SIZE) {
-            return 0;
-          }
-          break;
-        } else if (colors[key] == last_pix) {
-          // The color is already there.
-          break;
-        } else {
-          // Some other color sits there.
-          // Do linear conflict resolution.
-          ++key;
-          key &= (MAX_PALETTE_SIZE * 4 - 1);  // key mask for 1K buffer.
-        }
-      }
-    }
-    argb += pic->argb_stride;
-  }
-
-  // TODO(skal): could we reuse in_use[] to speed up ApplyPalette()?
-  num_colors = 0;
-  for (i = 0; i < (int)(sizeof(in_use) / sizeof(in_use[0])); ++i) {
-    if (in_use[i]) {
-      palette[num_colors] = colors[i];
-      ++num_colors;
-    }
-  }
-
-  qsort(palette, num_colors, sizeof(*palette), CompareColors);
-  *palette_size = num_colors;
-  return 1;
-}
-
-static int AnalyzeEntropy(const uint32_t* argb,
-                          int width, int height, int argb_stride,
-                          double* const nonpredicted_bits,
-                          double* const predicted_bits) {
-  int x, y;
-  const uint32_t* last_line = NULL;
-  uint32_t last_pix = argb[0];    // so we're sure that pix_diff == 0
-
-  VP8LHistogram* nonpredicted = NULL;
-  VP8LHistogram* predicted =
-      (VP8LHistogram*)malloc(2 * sizeof(*predicted));
-  if (predicted == NULL) return 0;
-  nonpredicted = predicted + 1;
-
-  VP8LHistogramInit(predicted, 0);
-  VP8LHistogramInit(nonpredicted, 0);
-  for (y = 0; y < height; ++y) {
-    for (x = 0; x < width; ++x) {
-      const uint32_t pix = argb[x];
-      const uint32_t pix_diff = VP8LSubPixels(pix, last_pix);
-      if (pix_diff == 0) continue;
-      if (last_line != NULL && pix == last_line[x]) {
-        continue;
-      }
-      last_pix = pix;
-      {
-        const PixOrCopy pix_token = PixOrCopyCreateLiteral(pix);
-        const PixOrCopy pix_diff_token = PixOrCopyCreateLiteral(pix_diff);
-        VP8LHistogramAddSinglePixOrCopy(nonpredicted, &pix_token);
-        VP8LHistogramAddSinglePixOrCopy(predicted, &pix_diff_token);
-      }
-    }
-    last_line = argb;
-    argb += argb_stride;
-  }
-  *nonpredicted_bits = VP8LHistogramEstimateBitsBulk(nonpredicted);
-  *predicted_bits = VP8LHistogramEstimateBitsBulk(predicted);
-  free(predicted);
-  return 1;
-}
-
-static int VP8LEncAnalyze(VP8LEncoder* const enc, WebPImageHint image_hint) {
-  const WebPPicture* const pic = enc->pic_;
-  assert(pic != NULL && pic->argb != NULL);
-
-  enc->use_palette_ =
-      AnalyzeAndCreatePalette(pic, enc->palette_, &enc->palette_size_);
-
-  if (image_hint == WEBP_HINT_GRAPH) {
-    if (enc->use_palette_ && enc->palette_size_ < MAX_COLORS_FOR_GRAPH) {
-      enc->use_palette_ = 0;
-    }
-  }
-
-  if (!enc->use_palette_) {
-    if (image_hint == WEBP_HINT_PHOTO) {
-      enc->use_predict_ = 1;
-      enc->use_cross_color_ = 1;
-    } else {
-      double non_pred_entropy, pred_entropy;
-      if (!AnalyzeEntropy(pic->argb, pic->width, pic->height, pic->argb_stride,
-                          &non_pred_entropy, &pred_entropy)) {
-        return 0;
-      }
-      if (pred_entropy < 0.95 * non_pred_entropy) {
-        enc->use_predict_ = 1;
-        // TODO(vikasa): Observed some correlation of cross_color transform with
-        // predict. Need to investigate this further and add separate heuristic
-        // for setting use_cross_color flag.
-        enc->use_cross_color_ = 1;
-      }
-    }
-  }
-
-  return 1;
-}
-
-static int GetHuffBitLengthsAndCodes(
-    const VP8LHistogramSet* const histogram_image,
-    HuffmanTreeCode* const huffman_codes) {
-  int i, k;
-  int ok = 1;
-  uint64_t total_length_size = 0;
-  uint8_t* mem_buf = NULL;
-  const int histogram_image_size = histogram_image->size;
-
-  // Iterate over all histograms and get the aggregate number of codes used.
-  for (i = 0; i < histogram_image_size; ++i) {
-    const VP8LHistogram* const histo = histogram_image->histograms[i];
-    HuffmanTreeCode* const codes = &huffman_codes[5 * i];
-    for (k = 0; k < 5; ++k) {
-      const int num_symbols = (k == 0) ? VP8LHistogramNumCodes(histo)
-                            : (k == 4) ? NUM_DISTANCE_CODES
-                            : 256;
-      codes[k].num_symbols = num_symbols;
-      total_length_size += num_symbols;
-    }
-  }
-
-  // Allocate and Set Huffman codes.
-  {
-    uint16_t* codes;
-    uint8_t* lengths;
-    mem_buf = (uint8_t*)WebPSafeCalloc(total_length_size,
-                                       sizeof(*lengths) + sizeof(*codes));
-    if (mem_buf == NULL) {
-      ok = 0;
-      goto End;
-    }
-    codes = (uint16_t*)mem_buf;
-    lengths = (uint8_t*)&codes[total_length_size];
-    for (i = 0; i < 5 * histogram_image_size; ++i) {
-      const int bit_length = huffman_codes[i].num_symbols;
-      huffman_codes[i].codes = codes;
-      huffman_codes[i].code_lengths = lengths;
-      codes += bit_length;
-      lengths += bit_length;
-    }
-  }
-
-  // Create Huffman trees.
-  for (i = 0; i < histogram_image_size; ++i) {
-    HuffmanTreeCode* const codes = &huffman_codes[5 * i];
-    VP8LHistogram* const histo = histogram_image->histograms[i];
-    ok = ok && VP8LCreateHuffmanTree(histo->literal_, 15, codes + 0);
-    ok = ok && VP8LCreateHuffmanTree(histo->red_, 15, codes + 1);
-    ok = ok && VP8LCreateHuffmanTree(histo->blue_, 15, codes + 2);
-    ok = ok && VP8LCreateHuffmanTree(histo->alpha_, 15, codes + 3);
-    ok = ok && VP8LCreateHuffmanTree(histo->distance_, 15, codes + 4);
-  }
-
- End:
-  if (!ok) free(mem_buf);
-  return ok;
-}
-
-static void StoreHuffmanTreeOfHuffmanTreeToBitMask(
-    VP8LBitWriter* const bw, const uint8_t* code_length_bitdepth) {
-  // RFC 1951 will calm you down if you are worried about this funny sequence.
-  // This sequence is tuned from that, but more weighted for lower symbol count,
-  // and more spiking histograms.
-  static const uint8_t kStorageOrder[CODE_LENGTH_CODES] = {
-    17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-  };
-  int i;
-  // Throw away trailing zeros:
-  int codes_to_store = CODE_LENGTH_CODES;
-  for (; codes_to_store > 4; --codes_to_store) {
-    if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) {
-      break;
-    }
-  }
-  VP8LWriteBits(bw, 4, codes_to_store - 4);
-  for (i = 0; i < codes_to_store; ++i) {
-    VP8LWriteBits(bw, 3, code_length_bitdepth[kStorageOrder[i]]);
-  }
-}
-
-static void ClearHuffmanTreeIfOnlyOneSymbol(
-    HuffmanTreeCode* const huffman_code) {
-  int k;
-  int count = 0;
-  for (k = 0; k < huffman_code->num_symbols; ++k) {
-    if (huffman_code->code_lengths[k] != 0) {
-      ++count;
-      if (count > 1) return;
-    }
-  }
-  for (k = 0; k < huffman_code->num_symbols; ++k) {
-    huffman_code->code_lengths[k] = 0;
-    huffman_code->codes[k] = 0;
-  }
-}
-
-static void StoreHuffmanTreeToBitMask(
-    VP8LBitWriter* const bw,
-    const HuffmanTreeToken* const tokens, const int num_tokens,
-    const HuffmanTreeCode* const huffman_code) {
-  int i;
-  for (i = 0; i < num_tokens; ++i) {
-    const int ix = tokens[i].code;
-    const int extra_bits = tokens[i].extra_bits;
-    VP8LWriteBits(bw, huffman_code->code_lengths[ix], huffman_code->codes[ix]);
-    switch (ix) {
-      case 16:
-        VP8LWriteBits(bw, 2, extra_bits);
-        break;
-      case 17:
-        VP8LWriteBits(bw, 3, extra_bits);
-        break;
-      case 18:
-        VP8LWriteBits(bw, 7, extra_bits);
-        break;
-    }
-  }
-}
-
-static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
-                                const HuffmanTreeCode* const tree) {
-  int ok = 0;
-  uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 };
-  uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 };
-  const int max_tokens = tree->num_symbols;
-  int num_tokens;
-  HuffmanTreeCode huffman_code;
-  HuffmanTreeToken* const tokens =
-      (HuffmanTreeToken*)WebPSafeMalloc((uint64_t)max_tokens, sizeof(*tokens));
-  if (tokens == NULL) return 0;
-
-  huffman_code.num_symbols = CODE_LENGTH_CODES;
-  huffman_code.code_lengths = code_length_bitdepth;
-  huffman_code.codes = code_length_bitdepth_symbols;
-
-  VP8LWriteBits(bw, 1, 0);
-  num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
-  {
-    int histogram[CODE_LENGTH_CODES] = { 0 };
-    int i;
-    for (i = 0; i < num_tokens; ++i) {
-      ++histogram[tokens[i].code];
-    }
-
-    if (!VP8LCreateHuffmanTree(histogram, 7, &huffman_code)) {
-      goto End;
-    }
-  }
-
-  StoreHuffmanTreeOfHuffmanTreeToBitMask(bw, code_length_bitdepth);
-  ClearHuffmanTreeIfOnlyOneSymbol(&huffman_code);
-  {
-    int trailing_zero_bits = 0;
-    int trimmed_length = num_tokens;
-    int write_trimmed_length;
-    int length;
-    int i = num_tokens;
-    while (i-- > 0) {
-      const int ix = tokens[i].code;
-      if (ix == 0 || ix == 17 || ix == 18) {
-        --trimmed_length;   // discount trailing zeros
-        trailing_zero_bits += code_length_bitdepth[ix];
-        if (ix == 17) {
-          trailing_zero_bits += 3;
-        } else if (ix == 18) {
-          trailing_zero_bits += 7;
-        }
-      } else {
-        break;
-      }
-    }
-    write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12);
-    length = write_trimmed_length ? trimmed_length : num_tokens;
-    VP8LWriteBits(bw, 1, write_trimmed_length);
-    if (write_trimmed_length) {
-      const int nbits = VP8LBitsLog2Ceiling(trimmed_length - 1);
-      const int nbitpairs = (nbits == 0) ? 1 : (nbits + 1) / 2;
-      VP8LWriteBits(bw, 3, nbitpairs - 1);
-      assert(trimmed_length >= 2);
-      VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2);
-    }
-    StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
-  }
-  ok = 1;
- End:
-  free(tokens);
-  return ok;
-}
-
-static int StoreHuffmanCode(VP8LBitWriter* const bw,
-                            const HuffmanTreeCode* const huffman_code) {
-  int i;
-  int count = 0;
-  int symbols[2] = { 0, 0 };
-  const int kMaxBits = 8;
-  const int kMaxSymbol = 1 << kMaxBits;
-
-  // Check whether it's a small tree.
-  for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) {
-    if (huffman_code->code_lengths[i] != 0) {
-      if (count < 2) symbols[count] = i;
-      ++count;
-    }
-  }
-
-  if (count == 0) {   // emit minimal tree for empty cases
-    // bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
-    VP8LWriteBits(bw, 4, 0x01);
-    return 1;
-  } else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) {
-    VP8LWriteBits(bw, 1, 1);  // Small tree marker to encode 1 or 2 symbols.
-    VP8LWriteBits(bw, 1, count - 1);
-    if (symbols[0] <= 1) {
-      VP8LWriteBits(bw, 1, 0);  // Code bit for small (1 bit) symbol value.
-      VP8LWriteBits(bw, 1, symbols[0]);
-    } else {
-      VP8LWriteBits(bw, 1, 1);
-      VP8LWriteBits(bw, 8, symbols[0]);
-    }
-    if (count == 2) {
-      VP8LWriteBits(bw, 8, symbols[1]);
-    }
-    return 1;
-  } else {
-    return StoreFullHuffmanCode(bw, huffman_code);
-  }
-}
-
-static void WriteHuffmanCode(VP8LBitWriter* const bw,
-                             const HuffmanTreeCode* const code, int index) {
-  const int depth = code->code_lengths[index];
-  const int symbol = code->codes[index];
-  VP8LWriteBits(bw, depth, symbol);
-}
-
-static void StoreImageToBitMask(
-    VP8LBitWriter* const bw, int width, int histo_bits,
-    const VP8LBackwardRefs* const refs,
-    const uint16_t* histogram_symbols,
-    const HuffmanTreeCode* const huffman_codes) {
-  // x and y trace the position in the image.
-  int x = 0;
-  int y = 0;
-  const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1;
-  int i;
-  for (i = 0; i < refs->size; ++i) {
-    const PixOrCopy* const v = &refs->refs[i];
-    const int histogram_ix = histogram_symbols[histo_bits ?
-                                               (y >> histo_bits) * histo_xsize +
-                                               (x >> histo_bits) : 0];
-    const HuffmanTreeCode* const codes = huffman_codes + 5 * histogram_ix;
-    if (PixOrCopyIsCacheIdx(v)) {
-      const int code = PixOrCopyCacheIdx(v);
-      const int literal_ix = 256 + NUM_LENGTH_CODES + code;
-      WriteHuffmanCode(bw, codes, literal_ix);
-    } else if (PixOrCopyIsLiteral(v)) {
-      static const int order[] = { 1, 2, 0, 3 };
-      int k;
-      for (k = 0; k < 4; ++k) {
-        const int code = PixOrCopyLiteral(v, order[k]);
-        WriteHuffmanCode(bw, codes + k, code);
-      }
-    } else {
-      int bits, n_bits;
-      int code, distance;
-
-      PrefixEncode(v->len, &code, &n_bits, &bits);
-      WriteHuffmanCode(bw, codes, 256 + code);
-      VP8LWriteBits(bw, n_bits, bits);
-
-      distance = PixOrCopyDistance(v);
-      PrefixEncode(distance, &code, &n_bits, &bits);
-      WriteHuffmanCode(bw, codes + 4, code);
-      VP8LWriteBits(bw, n_bits, bits);
-    }
-    x += PixOrCopyLength(v);
-    while (x >= width) {
-      x -= width;
-      ++y;
-    }
-  }
-}
-
-// Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
-static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
-                                const uint32_t* const argb,
-                                int width, int height, int quality) {
-  int i;
-  int ok = 0;
-  VP8LBackwardRefs refs;
-  HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
-  const uint16_t histogram_symbols[1] = { 0 };    // only one tree, one symbol
-  VP8LHistogramSet* const histogram_image = VP8LAllocateHistogramSet(1, 0);
-  if (histogram_image == NULL) return 0;
-
-  // Calculate backward references from ARGB image.
-  if (!VP8LGetBackwardReferences(width, height, argb, quality, 0, 1, &refs)) {
-    goto Error;
-  }
-  // Build histogram image and symbols from backward references.
-  VP8LHistogramStoreRefs(&refs, histogram_image->histograms[0]);
-
-  // Create Huffman bit lengths and codes for each histogram image.
-  assert(histogram_image->size == 1);
-  if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
-    goto Error;
-  }
-
-  // No color cache, no Huffman image.
-  VP8LWriteBits(bw, 1, 0);
-
-  // Store Huffman codes.
-  for (i = 0; i < 5; ++i) {
-    HuffmanTreeCode* const codes = &huffman_codes[i];
-    if (!StoreHuffmanCode(bw, codes)) {
-      goto Error;
-    }
-    ClearHuffmanTreeIfOnlyOneSymbol(codes);
-  }
-
-  // Store actual literals.
-  StoreImageToBitMask(bw, width, 0, &refs, histogram_symbols, huffman_codes);
-  ok = 1;
-
- Error:
-  free(histogram_image);
-  VP8LClearBackwardRefs(&refs);
-  free(huffman_codes[0].codes);
-  return ok;
-}
-
-static int EncodeImageInternal(VP8LBitWriter* const bw,
-                               const uint32_t* const argb,
-                               int width, int height, int quality,
-                               int cache_bits, int histogram_bits) {
-  int ok = 0;
-  const int use_2d_locality = 1;
-  const int use_color_cache = (cache_bits > 0);
-  const uint32_t histogram_image_xysize =
-      VP8LSubSampleSize(width, histogram_bits) *
-      VP8LSubSampleSize(height, histogram_bits);
-  VP8LHistogramSet* histogram_image =
-      VP8LAllocateHistogramSet(histogram_image_xysize, 0);
-  int histogram_image_size = 0;
-  size_t bit_array_size = 0;
-  HuffmanTreeCode* huffman_codes = NULL;
-  VP8LBackwardRefs refs;
-  uint16_t* const histogram_symbols =
-      (uint16_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
-                                sizeof(*histogram_symbols));
-  assert(histogram_bits >= MIN_HUFFMAN_BITS);
-  assert(histogram_bits <= MAX_HUFFMAN_BITS);
-  if (histogram_image == NULL || histogram_symbols == NULL) goto Error;
-
-  // Calculate backward references from ARGB image.
-  if (!VP8LGetBackwardReferences(width, height, argb, quality, cache_bits,
-                                 use_2d_locality, &refs)) {
-    goto Error;
-  }
-  // Build histogram image and symbols from backward references.
-  if (!VP8LGetHistoImageSymbols(width, height, &refs,
-                                quality, histogram_bits, cache_bits,
-                                histogram_image,
-                                histogram_symbols)) {
-    goto Error;
-  }
-  // Create Huffman bit lengths and codes for each histogram image.
-  histogram_image_size = histogram_image->size;
-  bit_array_size = 5 * histogram_image_size;
-  huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
-                                                   sizeof(*huffman_codes));
-  if (huffman_codes == NULL ||
-      !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
-    goto Error;
-  }
-
-  // Color Cache parameters.
-  VP8LWriteBits(bw, 1, use_color_cache);
-  if (use_color_cache) {
-    VP8LWriteBits(bw, 4, cache_bits);
-  }
-
-  // Huffman image + meta huffman.
-  {
-    const int write_histogram_image = (histogram_image_size > 1);
-    VP8LWriteBits(bw, 1, write_histogram_image);
-    if (write_histogram_image) {
-      uint32_t* const histogram_argb =
-          (uint32_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
-                                    sizeof(*histogram_argb));
-      int max_index = 0;
-      uint32_t i;
-      if (histogram_argb == NULL) goto Error;
-      for (i = 0; i < histogram_image_xysize; ++i) {
-        const int index = histogram_symbols[i] & 0xffff;
-        histogram_argb[i] = 0xff000000 | (index << 8);
-        if (index >= max_index) {
-          max_index = index + 1;
-        }
-      }
-      histogram_image_size = max_index;
-
-      VP8LWriteBits(bw, 3, histogram_bits - 2);
-      ok = EncodeImageNoHuffman(bw, histogram_argb,
-                                VP8LSubSampleSize(width, histogram_bits),
-                                VP8LSubSampleSize(height, histogram_bits),
-                                quality);
-      free(histogram_argb);
-      if (!ok) goto Error;
-    }
-  }
-
-  // Store Huffman codes.
-  {
-    int i;
-    for (i = 0; i < 5 * histogram_image_size; ++i) {
-      HuffmanTreeCode* const codes = &huffman_codes[i];
-      if (!StoreHuffmanCode(bw, codes)) goto Error;
-      ClearHuffmanTreeIfOnlyOneSymbol(codes);
-    }
-  }
-  // Free combined histograms.
-  free(histogram_image);
-  histogram_image = NULL;
-
-  // Store actual literals.
-  StoreImageToBitMask(bw, width, histogram_bits, &refs,
-                      histogram_symbols, huffman_codes);
-  ok = 1;
-
- Error:
-  if (!ok) free(histogram_image);
-
-  VP8LClearBackwardRefs(&refs);
-  if (huffman_codes != NULL) {
-    free(huffman_codes->codes);
-    free(huffman_codes);
-  }
-  free(histogram_symbols);
-  return ok;
-}
-
-// -----------------------------------------------------------------------------
-// Transforms
-
-// Check if it would be a good idea to subtract green from red and blue. We
-// only impact entropy in red/blue components, don't bother to look at others.
-static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
-                                     int width, int height,
-                                     VP8LBitWriter* const bw) {
-  if (!enc->use_palette_) {
-    int i;
-    const uint32_t* const argb = enc->argb_;
-    double bit_cost_before, bit_cost_after;
-    VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo));
-    if (histo == NULL) return 0;
-
-    VP8LHistogramInit(histo, 1);
-    for (i = 0; i < width * height; ++i) {
-      const uint32_t c = argb[i];
-      ++histo->red_[(c >> 16) & 0xff];
-      ++histo->blue_[(c >> 0) & 0xff];
-    }
-    bit_cost_before = VP8LHistogramEstimateBits(histo);
-
-    VP8LHistogramInit(histo, 1);
-    for (i = 0; i < width * height; ++i) {
-      const uint32_t c = argb[i];
-      const int green = (c >> 8) & 0xff;
-      ++histo->red_[((c >> 16) - green) & 0xff];
-      ++histo->blue_[((c >> 0) - green) & 0xff];
-    }
-    bit_cost_after = VP8LHistogramEstimateBits(histo);
-    free(histo);
-
-    // Check if subtracting green yields low entropy.
-    enc->use_subtract_green_ = (bit_cost_after < bit_cost_before);
-    if (enc->use_subtract_green_) {
-      VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
-      VP8LWriteBits(bw, 2, SUBTRACT_GREEN);
-      VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
-    }
-  }
-  return 1;
-}
-
-static int ApplyPredictFilter(const VP8LEncoder* const enc,
-                              int width, int height, int quality,
-                              VP8LBitWriter* const bw) {
-  const int pred_bits = enc->transform_bits_;
-  const int transform_width = VP8LSubSampleSize(width, pred_bits);
-  const int transform_height = VP8LSubSampleSize(height, pred_bits);
-
-  VP8LResidualImage(width, height, pred_bits, enc->argb_, enc->argb_scratch_,
-                    enc->transform_data_);
-  VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
-  VP8LWriteBits(bw, 2, PREDICTOR_TRANSFORM);
-  assert(pred_bits >= 2);
-  VP8LWriteBits(bw, 3, pred_bits - 2);
-  if (!EncodeImageNoHuffman(bw, enc->transform_data_,
-                            transform_width, transform_height, quality)) {
-    return 0;
-  }
-  return 1;
-}
-
-static int ApplyCrossColorFilter(const VP8LEncoder* const enc,
-                                 int width, int height, int quality,
-                                 VP8LBitWriter* const bw) {
-  const int ccolor_transform_bits = enc->transform_bits_;
-  const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
-  const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits);
-  const int step = (quality == 0) ? 32 : 8;
-
-  VP8LColorSpaceTransform(width, height, ccolor_transform_bits, step,
-                          enc->argb_, enc->transform_data_);
-  VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
-  VP8LWriteBits(bw, 2, CROSS_COLOR_TRANSFORM);
-  assert(ccolor_transform_bits >= 2);
-  VP8LWriteBits(bw, 3, ccolor_transform_bits - 2);
-  if (!EncodeImageNoHuffman(bw, enc->transform_data_,
-                            transform_width, transform_height, quality)) {
-    return 0;
-  }
-  return 1;
-}
-
-// -----------------------------------------------------------------------------
-
-static void PutLE32(uint8_t* const data, uint32_t val) {
-  data[0] = (val >>  0) & 0xff;
-  data[1] = (val >>  8) & 0xff;
-  data[2] = (val >> 16) & 0xff;
-  data[3] = (val >> 24) & 0xff;
-}
-
-static WebPEncodingError WriteRiffHeader(const WebPPicture* const pic,
-                                         size_t riff_size, size_t vp8l_size) {
-  uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = {
-    'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P',
-    'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE,
-  };
-  PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
-  PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size);
-  if (!pic->writer(riff, sizeof(riff), pic)) {
-    return VP8_ENC_ERROR_BAD_WRITE;
-  }
-  return VP8_ENC_OK;
-}
-
-static int WriteImageSize(const WebPPicture* const pic,
-                          VP8LBitWriter* const bw) {
-  const int width = pic->width - 1;
-  const int height = pic->height - 1;
-  assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION);
-
-  VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, width);
-  VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, height);
-  return !bw->error_;
-}
-
-static int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) {
-  VP8LWriteBits(bw, 1, has_alpha);
-  VP8LWriteBits(bw, VP8L_VERSION_BITS, VP8L_VERSION);
-  return !bw->error_;
-}
-
-static WebPEncodingError WriteImage(const WebPPicture* const pic,
-                                    VP8LBitWriter* const bw,
-                                    size_t* const coded_size) {
-  WebPEncodingError err = VP8_ENC_OK;
-  const uint8_t* const webpll_data = VP8LBitWriterFinish(bw);
-  const size_t webpll_size = VP8LBitWriterNumBytes(bw);
-  const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size;
-  const size_t pad = vp8l_size & 1;
-  const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad;
-
-  err = WriteRiffHeader(pic, riff_size, vp8l_size);
-  if (err != VP8_ENC_OK) goto Error;
-
-  if (!pic->writer(webpll_data, webpll_size, pic)) {
-    err = VP8_ENC_ERROR_BAD_WRITE;
-    goto Error;
-  }
-
-  if (pad) {
-    const uint8_t pad_byte[1] = { 0 };
-    if (!pic->writer(pad_byte, 1, pic)) {
-      err = VP8_ENC_ERROR_BAD_WRITE;
-      goto Error;
-    }
-  }
-  *coded_size = CHUNK_HEADER_SIZE + riff_size;
-  return VP8_ENC_OK;
-
- Error:
-  return err;
-}
-
-// -----------------------------------------------------------------------------
-
-// Allocates the memory for argb (W x H) buffer, 2 rows of context for
-// prediction and transform data.
-static WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc,
-                                                 int width, int height) {
-  WebPEncodingError err = VP8_ENC_OK;
-  const int tile_size = 1 << enc->transform_bits_;
-  const uint64_t image_size = width * height;
-  const uint64_t argb_scratch_size = tile_size * width + width;
-  const uint64_t transform_data_size =
-      (uint64_t)VP8LSubSampleSize(width, enc->transform_bits_) *
-      (uint64_t)VP8LSubSampleSize(height, enc->transform_bits_);
-  const uint64_t total_size =
-      image_size + argb_scratch_size + transform_data_size;
-  uint32_t* mem = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*mem));
-  if (mem == NULL) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-  enc->argb_ = mem;
-  mem += image_size;
-  enc->argb_scratch_ = mem;
-  mem += argb_scratch_size;
-  enc->transform_data_ = mem;
-  enc->current_width_ = width;
-
- Error:
-  return err;
-}
-
-// Bundles multiple (2, 4 or 8) pixels into a single pixel.
-// Returns the new xsize.
-static void BundleColorMap(const WebPPicture* const pic,
-                           int xbits, uint32_t* bundled_argb, int xs) {
-  int y;
-  const int bit_depth = 1 << (3 - xbits);
-  uint32_t code = 0;
-  const uint32_t* argb = pic->argb;
-  const int width = pic->width;
-  const int height = pic->height;
-
-  for (y = 0; y < height; ++y) {
-    int x;
-    for (x = 0; x < width; ++x) {
-      const int mask = (1 << xbits) - 1;
-      const int xsub = x & mask;
-      if (xsub == 0) {
-        code = 0;
-      }
-      // TODO(vikasa): simplify the bundling logic.
-      code |= (argb[x] & 0xff00) << (bit_depth * xsub);
-      bundled_argb[y * xs + (x >> xbits)] = 0xff000000 | code;
-    }
-    argb += pic->argb_stride;
-  }
-}
-
-// Note: Expects "enc->palette_" to be set properly.
-// Also, "enc->palette_" will be modified after this call and should not be used
-// later.
-static WebPEncodingError ApplyPalette(VP8LBitWriter* const bw,
-                                      VP8LEncoder* const enc, int quality) {
-  WebPEncodingError err = VP8_ENC_OK;
-  int i, x, y;
-  const WebPPicture* const pic = enc->pic_;
-  uint32_t* argb = pic->argb;
-  const int width = pic->width;
-  const int height = pic->height;
-  uint32_t* const palette = enc->palette_;
-  const int palette_size = enc->palette_size_;
-
-  // Replace each input pixel by corresponding palette index.
-  for (y = 0; y < height; ++y) {
-    for (x = 0; x < width; ++x) {
-      const uint32_t pix = argb[x];
-      for (i = 0; i < palette_size; ++i) {
-        if (pix == palette[i]) {
-          argb[x] = 0xff000000u | (i << 8);
-          break;
-        }
-      }
-    }
-    argb += pic->argb_stride;
-  }
-
-  // Save palette to bitstream.
-  VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
-  VP8LWriteBits(bw, 2, COLOR_INDEXING_TRANSFORM);
-  assert(palette_size >= 1);
-  VP8LWriteBits(bw, 8, palette_size - 1);
-  for (i = palette_size - 1; i >= 1; --i) {
-    palette[i] = VP8LSubPixels(palette[i], palette[i - 1]);
-  }
-  if (!EncodeImageNoHuffman(bw, palette, palette_size, 1, quality)) {
-    err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
-    goto Error;
-  }
-
-  if (palette_size <= 16) {
-    // Image can be packed (multiple pixels per uint32_t).
-    int xbits = 1;
-    if (palette_size <= 2) {
-      xbits = 3;
-    } else if (palette_size <= 4) {
-      xbits = 2;
-    }
-    err = AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height);
-    if (err != VP8_ENC_OK) goto Error;
-    BundleColorMap(pic, xbits, enc->argb_, enc->current_width_);
-  }
-
- Error:
-  return err;
-}
-
-// -----------------------------------------------------------------------------
-
-static int GetHistoBits(const WebPConfig* const config,
-                        const WebPPicture* const pic) {
-  const int width = pic->width;
-  const int height = pic->height;
-  const size_t hist_size = sizeof(VP8LHistogram);
-  // Make tile size a function of encoding method (Range: 0 to 6).
-  int histo_bits = 7 - config->method;
-  while (1) {
-    const size_t huff_image_size = VP8LSubSampleSize(width, histo_bits) *
-                                   VP8LSubSampleSize(height, histo_bits) *
-                                   hist_size;
-    if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
-    ++histo_bits;
-  }
-  return (histo_bits < MIN_HUFFMAN_BITS) ? MIN_HUFFMAN_BITS :
-         (histo_bits > MAX_HUFFMAN_BITS) ? MAX_HUFFMAN_BITS : histo_bits;
-}
-
-static void InitEncParams(VP8LEncoder* const enc) {
-  const WebPConfig* const config = enc->config_;
-  const WebPPicture* const picture = enc->pic_;
-  const int method = config->method;
-  const float quality = config->quality;
-  enc->transform_bits_ = (method < 4) ? 5 : (method > 4) ? 3 : 4;
-  enc->histo_bits_ = GetHistoBits(config, picture);
-  enc->cache_bits_ = (quality <= 25.f) ? 0 : 7;
-}
-
-// -----------------------------------------------------------------------------
-// VP8LEncoder
-
-static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
-                                   const WebPPicture* const picture) {
-  VP8LEncoder* const enc = (VP8LEncoder*)calloc(1, sizeof(*enc));
-  if (enc == NULL) {
-    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
-    return NULL;
-  }
-  enc->config_ = config;
-  enc->pic_ = picture;
-  return enc;
-}
-
-static void VP8LEncoderDelete(VP8LEncoder* enc) {
-  free(enc->argb_);
-  free(enc);
-}
-
-// -----------------------------------------------------------------------------
-// Main call
-
-WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
-                                   const WebPPicture* const picture,
-                                   VP8LBitWriter* const bw) {
-  WebPEncodingError err = VP8_ENC_OK;
-  const int quality = (int)config->quality;
-  const int width = picture->width;
-  const int height = picture->height;
-  VP8LEncoder* const enc = VP8LEncoderNew(config, picture);
-  const size_t byte_position = VP8LBitWriterNumBytes(bw);
-
-  if (enc == NULL) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  InitEncParams(enc);
-
-  // ---------------------------------------------------------------------------
-  // Analyze image (entropy, num_palettes etc)
-
-  if (!VP8LEncAnalyze(enc, config->image_hint)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  if (enc->use_palette_) {
-    err = ApplyPalette(bw, enc, quality);
-    if (err != VP8_ENC_OK) goto Error;
-    // Color cache is disabled for palette.
-    enc->cache_bits_ = 0;
-  }
-
-  // In case image is not packed.
-  if (enc->argb_ == NULL) {
-    int y;
-    err = AllocateTransformBuffer(enc, width, height);
-    if (err != VP8_ENC_OK) goto Error;
-    for (y = 0; y < height; ++y) {
-      memcpy(enc->argb_ + y * width,
-             picture->argb + y * picture->argb_stride,
-             width * sizeof(*enc->argb_));
-    }
-    enc->current_width_ = width;
-  }
-
-  // ---------------------------------------------------------------------------
-  // Apply transforms and write transform data.
-
-  if (!EvalAndApplySubtractGreen(enc, enc->current_width_, height, bw)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  if (enc->use_predict_) {
-    if (!ApplyPredictFilter(enc, enc->current_width_, height, quality, bw)) {
-      err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
-      goto Error;
-    }
-  }
-
-  if (enc->use_cross_color_) {
-    if (!ApplyCrossColorFilter(enc, enc->current_width_, height, quality, bw)) {
-      err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
-      goto Error;
-    }
-  }
-
-  VP8LWriteBits(bw, 1, !TRANSFORM_PRESENT);  // No more transforms.
-
-  // ---------------------------------------------------------------------------
-  // Estimate the color cache size.
-
-  if (enc->cache_bits_ > 0) {
-    if (!VP8LCalculateEstimateForCacheSize(enc->argb_, enc->current_width_,
-                                           height, &enc->cache_bits_)) {
-      err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
-      goto Error;
-    }
-  }
-
-  // ---------------------------------------------------------------------------
-  // Encode and write the transformed image.
-
-  if (!EncodeImageInternal(bw, enc->argb_, enc->current_width_, height,
-                           quality, enc->cache_bits_, enc->histo_bits_)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  if (picture->stats != NULL) {
-    WebPAuxStats* const stats = picture->stats;
-    stats->lossless_features = 0;
-    if (enc->use_predict_) stats->lossless_features |= 1;
-    if (enc->use_cross_color_) stats->lossless_features |= 2;
-    if (enc->use_subtract_green_) stats->lossless_features |= 4;
-    if (enc->use_palette_) stats->lossless_features |= 8;
-    stats->histogram_bits = enc->histo_bits_;
-    stats->transform_bits = enc->transform_bits_;
-    stats->cache_bits = enc->cache_bits_;
-    stats->palette_size = enc->palette_size_;
-    stats->lossless_size = (int)(VP8LBitWriterNumBytes(bw) - byte_position);
-  }
-
- Error:
-  VP8LEncoderDelete(enc);
-  return err;
-}
-
-int VP8LEncodeImage(const WebPConfig* const config,
-                    const WebPPicture* const picture) {
-  int width, height;
-  int has_alpha;
-  size_t coded_size;
-  int percent = 0;
-  WebPEncodingError err = VP8_ENC_OK;
-  VP8LBitWriter bw;
-
-  if (picture == NULL) return 0;
-
-  if (config == NULL || picture->argb == NULL) {
-    err = VP8_ENC_ERROR_NULL_PARAMETER;
-    WebPEncodingSetError(picture, err);
-    return 0;
-  }
-
-  width = picture->width;
-  height = picture->height;
-  if (!VP8LBitWriterInit(&bw, (width * height) >> 1)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  if (!WebPReportProgress(picture, 1, &percent)) {
- UserAbort:
-    err = VP8_ENC_ERROR_USER_ABORT;
-    goto Error;
-  }
-  // Reset stats (for pure lossless coding)
-  if (picture->stats != NULL) {
-    WebPAuxStats* const stats = picture->stats;
-    memset(stats, 0, sizeof(*stats));
-    stats->PSNR[0] = 99.f;
-    stats->PSNR[1] = 99.f;
-    stats->PSNR[2] = 99.f;
-    stats->PSNR[3] = 99.f;
-    stats->PSNR[4] = 99.f;
-  }
-
-  // Write image size.
-  if (!WriteImageSize(picture, &bw)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  has_alpha = WebPPictureHasTransparency(picture);
-  // Write the non-trivial Alpha flag and lossless version.
-  if (!WriteRealAlphaAndVersion(&bw, has_alpha)) {
-    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-    goto Error;
-  }
-
-  if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
-
-  // Encode main image stream.
-  err = VP8LEncodeStream(config, picture, &bw);
-  if (err != VP8_ENC_OK) goto Error;
-
-  // TODO(skal): have a fine-grained progress report in VP8LEncodeStream().
-  if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
-
-  // Finish the RIFF chunk.
-  err = WriteImage(picture, &bw, &coded_size);
-  if (err != VP8_ENC_OK) goto Error;
-
-  if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
-
-  // Save size.
-  if (picture->stats != NULL) {
-    picture->stats->coded_size += (int)coded_size;
-    picture->stats->lossless_size = (int)coded_size;
-  }
-
-  if (picture->extra_info != NULL) {
-    const int mb_w = (width + 15) >> 4;
-    const int mb_h = (height + 15) >> 4;
-    memset(picture->extra_info, 0, mb_w * mb_h * sizeof(*picture->extra_info));
-  }
-
- Error:
-  if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
-  VP8LBitWriterDestroy(&bw);
-  if (err != VP8_ENC_OK) {
-    WebPEncodingSetError(picture, err);
-    return 0;
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 68
drivers/webpold/enc/vp8li.h

@@ -1,68 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Lossless encoder: internal header.
-//
-// Author: Vikas Arora ([email protected])
-
-#ifndef WEBP_ENC_VP8LI_H_
-#define WEBP_ENC_VP8LI_H_
-
-#include "./histogram.h"
-#include "../utils/bit_writer.h"
-#include "../encode.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-typedef struct {
-  const WebPConfig* config_;    // user configuration and parameters
-  const WebPPicture* pic_;      // input picture.
-
-  uint32_t* argb_;              // Transformed argb image data.
-  uint32_t* argb_scratch_;      // Scratch memory for argb rows
-                                // (used for prediction).
-  uint32_t* transform_data_;    // Scratch memory for transform data.
-  int       current_width_;     // Corresponds to packed image width.
-
-  // Encoding parameters derived from quality parameter.
-  int histo_bits_;
-  int transform_bits_;
-  int cache_bits_;        // If equal to 0, don't use color cache.
-
-  // Encoding parameters derived from image characteristics.
-  int use_cross_color_;
-  int use_subtract_green_;
-  int use_predict_;
-  int use_palette_;
-  int palette_size_;
-  uint32_t palette_[MAX_PALETTE_SIZE];
-} VP8LEncoder;
-
-//------------------------------------------------------------------------------
-// internal functions. Not public.
-
-// Encodes the picture.
-// Returns 0 if config or picture is NULL or picture doesn't have valid argb
-// input.
-int VP8LEncodeImage(const WebPConfig* const config,
-                    const WebPPicture* const picture);
-
-// Encodes the main image stream using the supplied bit writer.
-WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
-                                   const WebPPicture* const picture,
-                                   VP8LBitWriter* const bw);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_ENC_VP8LI_H_ */

+ 0 - 389
drivers/webpold/enc/webpenc.c

@@ -1,389 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// WebP encoder: main entry point
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "./vp8enci.h"
-#include "./vp8li.h"
-#include "../utils/utils.h"
-
-// #define PRINT_MEMORY_INFO
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#ifdef PRINT_MEMORY_INFO
-#include <stdio.h>
-#endif
-
-//------------------------------------------------------------------------------
-
-int WebPGetEncoderVersion(void) {
-  return (ENC_MAJ_VERSION << 16) | (ENC_MIN_VERSION << 8) | ENC_REV_VERSION;
-}
-
-//------------------------------------------------------------------------------
-// WebPPicture
-//------------------------------------------------------------------------------
-
-static int DummyWriter(const uint8_t* data, size_t data_size,
-                       const WebPPicture* const picture) {
-  // The following are to prevent 'unused variable' error message.
-  (void)data;
-  (void)data_size;
-  (void)picture;
-  return 1;
-}
-
-int WebPPictureInitInternal(WebPPicture* picture, int version) {
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_ENCODER_ABI_VERSION)) {
-    return 0;   // caller/system version mismatch!
-  }
-  if (picture != NULL) {
-    memset(picture, 0, sizeof(*picture));
-    picture->writer = DummyWriter;
-    WebPEncodingSetError(picture, VP8_ENC_OK);
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// VP8Encoder
-//------------------------------------------------------------------------------
-
-static void ResetSegmentHeader(VP8Encoder* const enc) {
-  VP8SegmentHeader* const hdr = &enc->segment_hdr_;
-  hdr->num_segments_ = enc->config_->segments;
-  hdr->update_map_  = (hdr->num_segments_ > 1);
-  hdr->size_ = 0;
-}
-
-static void ResetFilterHeader(VP8Encoder* const enc) {
-  VP8FilterHeader* const hdr = &enc->filter_hdr_;
-  hdr->simple_ = 1;
-  hdr->level_ = 0;
-  hdr->sharpness_ = 0;
-  hdr->i4x4_lf_delta_ = 0;
-}
-
-static void ResetBoundaryPredictions(VP8Encoder* const enc) {
-  // init boundary values once for all
-  // Note: actually, initializing the preds_[] is only needed for intra4.
-  int i;
-  uint8_t* const top = enc->preds_ - enc->preds_w_;
-  uint8_t* const left = enc->preds_ - 1;
-  for (i = -1; i < 4 * enc->mb_w_; ++i) {
-    top[i] = B_DC_PRED;
-  }
-  for (i = 0; i < 4 * enc->mb_h_; ++i) {
-    left[i * enc->preds_w_] = B_DC_PRED;
-  }
-  enc->nz_[-1] = 0;   // constant
-}
-
-// Map configured quality level to coding tools used.
-//-------------+---+---+---+---+---+---+
-//   Quality   | 0 | 1 | 2 | 3 | 4 | 5 +
-//-------------+---+---+---+---+---+---+
-// dynamic prob| ~ | x | x | x | x | x |
-//-------------+---+---+---+---+---+---+
-// rd-opt modes|   |   | x | x | x | x |
-//-------------+---+---+---+---+---+---+
-// fast i4/i16 | x | x |   |   |   |   |
-//-------------+---+---+---+---+---+---+
-// rd-opt i4/16|   |   | x | x | x | x |
-//-------------+---+---+---+---+---+---+
-// Trellis     |   | x |   |   | x | x |
-//-------------+---+---+---+---+---+---+
-// full-SNS    |   |   |   |   |   | x |
-//-------------+---+---+---+---+---+---+
-
-static void MapConfigToTools(VP8Encoder* const enc) {
-  const int method = enc->config_->method;
-  const int limit = 100 - enc->config_->partition_limit;
-  enc->method_ = method;
-  enc->rd_opt_level_ = (method >= 6) ? 3
-                     : (method >= 5) ? 2
-                     : (method >= 3) ? 1
-                     : 0;
-  enc->max_i4_header_bits_ =
-      256 * 16 * 16 *                 // upper bound: up to 16bit per 4x4 block
-      (limit * limit) / (100 * 100);  // ... modulated with a quadratic curve.
-}
-
-// Memory scaling with dimensions:
-//  memory (bytes) ~= 2.25 * w + 0.0625 * w * h
-//
-// Typical memory footprint (768x510 picture)
-// Memory used:
-//              encoder: 33919
-//          block cache: 2880
-//                 info: 3072
-//                preds: 24897
-//          top samples: 1623
-//             non-zero: 196
-//             lf-stats: 2048
-//                total: 68635
-// Transcient object sizes:
-//       VP8EncIterator: 352
-//         VP8ModeScore: 912
-//       VP8SegmentInfo: 532
-//             VP8Proba: 31032
-//              LFStats: 2048
-// Picture size (yuv): 589824
-
-static VP8Encoder* InitVP8Encoder(const WebPConfig* const config,
-                                  WebPPicture* const picture) {
-  const int use_filter =
-      (config->filter_strength > 0) || (config->autofilter > 0);
-  const int mb_w = (picture->width + 15) >> 4;
-  const int mb_h = (picture->height + 15) >> 4;
-  const int preds_w = 4 * mb_w + 1;
-  const int preds_h = 4 * mb_h + 1;
-  const size_t preds_size = preds_w * preds_h * sizeof(uint8_t);
-  const int top_stride = mb_w * 16;
-  const size_t nz_size = (mb_w + 1) * sizeof(uint32_t);
-  const size_t cache_size = (3 * YUV_SIZE + PRED_SIZE) * sizeof(uint8_t);
-  const size_t info_size = mb_w * mb_h * sizeof(VP8MBInfo);
-  const size_t samples_size = (2 * top_stride +         // top-luma/u/v
-                               16 + 16 + 16 + 8 + 1 +   // left y/u/v
-                               2 * ALIGN_CST)           // align all
-                               * sizeof(uint8_t);
-  const size_t lf_stats_size =
-      config->autofilter ? sizeof(LFStats) + ALIGN_CST : 0;
-  VP8Encoder* enc;
-  uint8_t* mem;
-  const uint64_t size = (uint64_t)sizeof(VP8Encoder)   // main struct
-                      + ALIGN_CST                      // cache alignment
-                      + cache_size                     // working caches
-                      + info_size                      // modes info
-                      + preds_size                     // prediction modes
-                      + samples_size                   // top/left samples
-                      + nz_size                        // coeff context bits
-                      + lf_stats_size;                 // autofilter stats
-
-#ifdef PRINT_MEMORY_INFO
-  printf("===================================\n");
-  printf("Memory used:\n"
-         "             encoder: %ld\n"
-         "         block cache: %ld\n"
-         "                info: %ld\n"
-         "               preds: %ld\n"
-         "         top samples: %ld\n"
-         "            non-zero: %ld\n"
-         "            lf-stats: %ld\n"
-         "               total: %ld\n",
-         sizeof(VP8Encoder) + ALIGN_CST, cache_size, info_size,
-         preds_size, samples_size, nz_size, lf_stats_size, size);
-  printf("Transcient object sizes:\n"
-         "      VP8EncIterator: %ld\n"
-         "        VP8ModeScore: %ld\n"
-         "      VP8SegmentInfo: %ld\n"
-         "            VP8Proba: %ld\n"
-         "             LFStats: %ld\n",
-         sizeof(VP8EncIterator), sizeof(VP8ModeScore),
-         sizeof(VP8SegmentInfo), sizeof(VP8Proba),
-         sizeof(LFStats));
-  printf("Picture size (yuv): %ld\n",
-         mb_w * mb_h * 384 * sizeof(uint8_t));
-  printf("===================================\n");
-#endif
-  mem = (uint8_t*)WebPSafeMalloc(size, sizeof(*mem));
-  if (mem == NULL) {
-    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
-    return NULL;
-  }
-  enc = (VP8Encoder*)mem;
-  mem = (uint8_t*)DO_ALIGN(mem + sizeof(*enc));
-  memset(enc, 0, sizeof(*enc));
-  enc->num_parts_ = 1 << config->partitions;
-  enc->mb_w_ = mb_w;
-  enc->mb_h_ = mb_h;
-  enc->preds_w_ = preds_w;
-  enc->yuv_in_ = (uint8_t*)mem;
-  mem += YUV_SIZE;
-  enc->yuv_out_ = (uint8_t*)mem;
-  mem += YUV_SIZE;
-  enc->yuv_out2_ = (uint8_t*)mem;
-  mem += YUV_SIZE;
-  enc->yuv_p_ = (uint8_t*)mem;
-  mem += PRED_SIZE;
-  enc->mb_info_ = (VP8MBInfo*)mem;
-  mem += info_size;
-  enc->preds_ = ((uint8_t*)mem) + 1 + enc->preds_w_;
-  mem += preds_w * preds_h * sizeof(uint8_t);
-  enc->nz_ = 1 + (uint32_t*)mem;
-  mem += nz_size;
-  enc->lf_stats_ = lf_stats_size ? (LFStats*)DO_ALIGN(mem) : NULL;
-  mem += lf_stats_size;
-
-  // top samples (all 16-aligned)
-  mem = (uint8_t*)DO_ALIGN(mem);
-  enc->y_top_ = (uint8_t*)mem;
-  enc->uv_top_ = enc->y_top_ + top_stride;
-  mem += 2 * top_stride;
-  mem = (uint8_t*)DO_ALIGN(mem + 1);
-  enc->y_left_ = (uint8_t*)mem;
-  mem += 16 + 16;
-  enc->u_left_ = (uint8_t*)mem;
-  mem += 16;
-  enc->v_left_ = (uint8_t*)mem;
-  mem += 8;
-
-  enc->config_ = config;
-  enc->profile_ = use_filter ? ((config->filter_type == 1) ? 0 : 1) : 2;
-  enc->pic_ = picture;
-  enc->percent_ = 0;
-
-  MapConfigToTools(enc);
-  VP8EncDspInit();
-  VP8DefaultProbas(enc);
-  ResetSegmentHeader(enc);
-  ResetFilterHeader(enc);
-  ResetBoundaryPredictions(enc);
-
-  VP8EncInitAlpha(enc);
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-  VP8EncInitLayer(enc);
-#endif
-
-  return enc;
-}
-
-static void DeleteVP8Encoder(VP8Encoder* enc) {
-  if (enc != NULL) {
-    VP8EncDeleteAlpha(enc);
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-    VP8EncDeleteLayer(enc);
-#endif
-    free(enc);
-  }
-}
-
-//------------------------------------------------------------------------------
-
-static double GetPSNR(uint64_t err, uint64_t size) {
-  return err ? 10. * log10(255. * 255. * size / err) : 99.;
-}
-
-static void FinalizePSNR(const VP8Encoder* const enc) {
-  WebPAuxStats* stats = enc->pic_->stats;
-  const uint64_t size = enc->sse_count_;
-  const uint64_t* const sse = enc->sse_;
-  stats->PSNR[0] = (float)GetPSNR(sse[0], size);
-  stats->PSNR[1] = (float)GetPSNR(sse[1], size / 4);
-  stats->PSNR[2] = (float)GetPSNR(sse[2], size / 4);
-  stats->PSNR[3] = (float)GetPSNR(sse[0] + sse[1] + sse[2], size * 3 / 2);
-  stats->PSNR[4] = (float)GetPSNR(sse[3], size);
-}
-
-static void StoreStats(VP8Encoder* const enc) {
-  WebPAuxStats* const stats = enc->pic_->stats;
-  if (stats != NULL) {
-    int i, s;
-    for (i = 0; i < NUM_MB_SEGMENTS; ++i) {
-      stats->segment_level[i] = enc->dqm_[i].fstrength_;
-      stats->segment_quant[i] = enc->dqm_[i].quant_;
-      for (s = 0; s <= 2; ++s) {
-        stats->residual_bytes[s][i] = enc->residual_bytes_[s][i];
-      }
-    }
-    FinalizePSNR(enc);
-    stats->coded_size = enc->coded_size_;
-    for (i = 0; i < 3; ++i) {
-      stats->block_count[i] = enc->block_count_[i];
-    }
-  }
-  WebPReportProgress(enc->pic_, 100, &enc->percent_);  // done!
-}
-
-int WebPEncodingSetError(const WebPPicture* const pic,
-                         WebPEncodingError error) {
-  assert((int)error < VP8_ENC_ERROR_LAST);
-  assert((int)error >= VP8_ENC_OK);
-  ((WebPPicture*)pic)->error_code = error;
-  return 0;
-}
-
-int WebPReportProgress(const WebPPicture* const pic,
-                       int percent, int* const percent_store) {
-  if (percent_store != NULL && percent != *percent_store) {
-    *percent_store = percent;
-    if (pic->progress_hook && !pic->progress_hook(percent, pic)) {
-      // user abort requested
-      WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT);
-      return 0;
-    }
-  }
-  return 1;  // ok
-}
-//------------------------------------------------------------------------------
-
-int WebPEncode(const WebPConfig* config, WebPPicture* pic) {
-  int ok;
-
-  if (pic == NULL)
-    return 0;
-  WebPEncodingSetError(pic, VP8_ENC_OK);  // all ok so far
-  if (config == NULL)  // bad params
-    return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER);
-  if (!WebPValidateConfig(config))
-    return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION);
-  if (pic->width <= 0 || pic->height <= 0)
-    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION);
-  if (pic->width > WEBP_MAX_DIMENSION || pic->height > WEBP_MAX_DIMENSION)
-    return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION);
-
-  if (pic->stats != NULL) memset(pic->stats, 0, sizeof(*pic->stats));
-
-  if (!config->lossless) {
-    VP8Encoder* enc = NULL;
-    if (pic->y == NULL || pic->u == NULL || pic->v == NULL) {
-      if (pic->argb != NULL) {
-        if (!WebPPictureARGBToYUVA(pic, WEBP_YUV420)) return 0;
-      } else {
-        return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER);
-      }
-    }
-
-    enc = InitVP8Encoder(config, pic);
-    if (enc == NULL) return 0;  // pic->error is already set.
-    // Note: each of the tasks below account for 20% in the progress report.
-    ok = VP8EncAnalyze(enc)
-      && VP8StatLoop(enc)
-      && VP8EncLoop(enc)
-      && VP8EncFinishAlpha(enc)
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-      && VP8EncFinishLayer(enc)
-#endif
-      && VP8EncWrite(enc);
-    StoreStats(enc);
-    if (!ok) {
-      VP8EncFreeBitWriters(enc);
-    }
-    DeleteVP8Encoder(enc);
-  } else {
-    if (pic->argb == NULL)
-      return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER);
-
-    ok = VP8LEncodeImage(config, pic);  // Sets pic->error in case of problem.
-  }
-
-  return ok;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 463
drivers/webpold/encode.h

@@ -1,463 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//   WebP encoder: main interface
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_WEBP_ENCODE_H_
-#define WEBP_WEBP_ENCODE_H_
-
-#include "./types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define WEBP_ENCODER_ABI_VERSION 0x0200    // MAJOR(8b) + MINOR(8b)
-
-// Return the encoder's version number, packed in hexadecimal using 8bits for
-// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
-WEBP_EXTERN(int) WebPGetEncoderVersion(void);
-
-//------------------------------------------------------------------------------
-// One-stop-shop call! No questions asked:
-
-// Returns the size of the compressed data (pointed to by *output), or 0 if
-// an error occurred. The compressed data must be released by the caller
-// using the call 'free(*output)'.
-// These functions compress using the lossy format, and the quality_factor
-// can go from 0 (smaller output, lower quality) to 100 (best quality,
-// larger output).
-WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb,
-                                  int width, int height, int stride,
-                                  float quality_factor, uint8_t** output);
-WEBP_EXTERN(size_t) WebPEncodeBGR(const uint8_t* bgr,
-                                  int width, int height, int stride,
-                                  float quality_factor, uint8_t** output);
-WEBP_EXTERN(size_t) WebPEncodeRGBA(const uint8_t* rgba,
-                                   int width, int height, int stride,
-                                   float quality_factor, uint8_t** output);
-WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra,
-                                   int width, int height, int stride,
-                                   float quality_factor, uint8_t** output);
-
-// These functions are the equivalent of the above, but compressing in a
-// lossless manner. Files are usually larger than lossy format, but will
-// not suffer any compression loss.
-WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb,
-                                          int width, int height, int stride,
-                                          uint8_t** output);
-WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr,
-                                          int width, int height, int stride,
-                                          uint8_t** output);
-WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba,
-                                           int width, int height, int stride,
-                                           uint8_t** output);
-WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra,
-                                           int width, int height, int stride,
-                                           uint8_t** output);
-
-//------------------------------------------------------------------------------
-// Coding parameters
-
-// Image characteristics hint for the underlying encoder.
-typedef enum {
-  WEBP_HINT_DEFAULT = 0,  // default preset.
-  WEBP_HINT_PICTURE,      // digital picture, like portrait, inner shot
-  WEBP_HINT_PHOTO,        // outdoor photograph, with natural lighting
-  WEBP_HINT_GRAPH,        // Discrete tone image (graph, map-tile etc).
-  WEBP_HINT_LAST
-} WebPImageHint;
-
-typedef struct {
-  int lossless;           // Lossless encoding (0=lossy(default), 1=lossless).
-  float quality;          // between 0 (smallest file) and 100 (biggest)
-  int method;             // quality/speed trade-off (0=fast, 6=slower-better)
-
-  WebPImageHint image_hint;  // Hint for image type (lossless only for now).
-
-  // Parameters related to lossy compression only:
-  int target_size;        // if non-zero, set the desired target size in bytes.
-                          // Takes precedence over the 'compression' parameter.
-  float target_PSNR;      // if non-zero, specifies the minimal distortion to
-                          // try to achieve. Takes precedence over target_size.
-  int segments;           // maximum number of segments to use, in [1..4]
-  int sns_strength;       // Spatial Noise Shaping. 0=off, 100=maximum.
-  int filter_strength;    // range: [0 = off .. 100 = strongest]
-  int filter_sharpness;   // range: [0 = off .. 7 = least sharp]
-  int filter_type;        // filtering type: 0 = simple, 1 = strong (only used
-                          // if filter_strength > 0 or autofilter > 0)
-  int autofilter;         // Auto adjust filter's strength [0 = off, 1 = on]
-  int alpha_compression;  // Algorithm for encoding the alpha plane (0 = none,
-                          // 1 = compressed with WebP lossless). Default is 1.
-  int alpha_filtering;    // Predictive filtering method for alpha plane.
-                          //  0: none, 1: fast, 2: best. Default if 1.
-  int alpha_quality;      // Between 0 (smallest size) and 100 (lossless).
-                          // Default is 100.
-  int pass;               // number of entropy-analysis passes (in [1..10]).
-
-  int show_compressed;    // if true, export the compressed picture back.
-                          // In-loop filtering is not applied.
-  int preprocessing;      // preprocessing filter (0=none, 1=segment-smooth)
-  int partitions;         // log2(number of token partitions) in [0..3]. Default
-                          // is set to 0 for easier progressive decoding.
-  int partition_limit;    // quality degradation allowed to fit the 512k limit
-                          // on prediction modes coding (0: no degradation,
-                          // 100: maximum possible degradation).
-
-  uint32_t pad[8];        // padding for later use
-} WebPConfig;
-
-// Enumerate some predefined settings for WebPConfig, depending on the type
-// of source picture. These presets are used when calling WebPConfigPreset().
-typedef enum {
-  WEBP_PRESET_DEFAULT = 0,  // default preset.
-  WEBP_PRESET_PICTURE,      // digital picture, like portrait, inner shot
-  WEBP_PRESET_PHOTO,        // outdoor photograph, with natural lighting
-  WEBP_PRESET_DRAWING,      // hand or line drawing, with high-contrast details
-  WEBP_PRESET_ICON,         // small-sized colorful images
-  WEBP_PRESET_TEXT          // text-like
-} WebPPreset;
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(int) WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
-
-// Should always be called, to initialize a fresh WebPConfig structure before
-// modification. Returns false in case of version mismatch. WebPConfigInit()
-// must have succeeded before using the 'config' object.
-// Note that the default values are lossless=0 and quality=75.
-static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
-  return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
-                                WEBP_ENCODER_ABI_VERSION);
-}
-
-// This function will initialize the configuration according to a predefined
-// set of parameters (referred to by 'preset') and a given quality factor.
-// This function can be called as a replacement to WebPConfigInit(). Will
-// return false in case of error.
-static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
-                                        WebPPreset preset, float quality) {
-  return WebPConfigInitInternal(config, preset, quality,
-                                WEBP_ENCODER_ABI_VERSION);
-}
-
-// Returns true if 'config' is non-NULL and all configuration parameters are
-// within their valid ranges.
-WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config);
-
-//------------------------------------------------------------------------------
-// Input / Output
-
-typedef struct WebPPicture WebPPicture;   // main structure for I/O
-
-// Structure for storing auxiliary statistics (mostly for lossy encoding).
-typedef struct {
-  int coded_size;         // final size
-
-  float PSNR[5];          // peak-signal-to-noise ratio for Y/U/V/All/Alpha
-  int block_count[3];     // number of intra4/intra16/skipped macroblocks
-  int header_bytes[2];    // approximate number of bytes spent for header
-                          // and mode-partition #0
-  int residual_bytes[3][4];  // approximate number of bytes spent for
-                             // DC/AC/uv coefficients for each (0..3) segments.
-  int segment_size[4];    // number of macroblocks in each segments
-  int segment_quant[4];   // quantizer values for each segments
-  int segment_level[4];   // filtering strength for each segments [0..63]
-
-  int alpha_data_size;    // size of the transparency data
-  int layer_data_size;    // size of the enhancement layer data
-
-  // lossless encoder statistics
-  uint32_t lossless_features;  // bit0:predictor bit1:cross-color transform
-                               // bit2:subtract-green bit3:color indexing
-  int histogram_bits;          // number of precision bits of histogram
-  int transform_bits;          // precision bits for transform
-  int cache_bits;              // number of bits for color cache lookup
-  int palette_size;            // number of color in palette, if used
-  int lossless_size;           // final lossless size
-
-  uint32_t pad[4];        // padding for later use
-} WebPAuxStats;
-
-// Signature for output function. Should return true if writing was successful.
-// data/data_size is the segment of data to write, and 'picture' is for
-// reference (and so one can make use of picture->custom_ptr).
-typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
-                                  const WebPPicture* picture);
-
-// WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
-// the following WebPMemoryWriter object (to be set as a custom_ptr).
-typedef struct {
-  uint8_t* mem;       // final buffer (of size 'max_size', larger than 'size').
-  size_t   size;      // final size
-  size_t   max_size;  // total capacity
-  uint32_t pad[1];    // padding for later use
-} WebPMemoryWriter;
-
-// The following must be called first before any use.
-WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer);
-
-// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
-// completion, writer.mem and writer.size will hold the coded data.
-WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
-                                 const WebPPicture* picture);
-
-// Progress hook, called from time to time to report progress. It can return
-// false to request an abort of the encoding process, or true otherwise if
-// everything is OK.
-typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
-
-typedef enum {
-  // chroma sampling
-  WEBP_YUV420 = 0,   // 4:2:0
-  WEBP_YUV422 = 1,   // 4:2:2
-  WEBP_YUV444 = 2,   // 4:4:4
-  WEBP_YUV400 = 3,   // grayscale
-  WEBP_CSP_UV_MASK = 3,   // bit-mask to get the UV sampling factors
-  // alpha channel variants
-  WEBP_YUV420A = 4,
-  WEBP_YUV422A = 5,
-  WEBP_YUV444A = 6,
-  WEBP_YUV400A = 7,   // grayscale + alpha
-  WEBP_CSP_ALPHA_BIT = 4   // bit that is set if alpha is present
-} WebPEncCSP;
-
-// Encoding error conditions.
-typedef enum {
-  VP8_ENC_OK = 0,
-  VP8_ENC_ERROR_OUT_OF_MEMORY,            // memory error allocating objects
-  VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY,  // memory error while flushing bits
-  VP8_ENC_ERROR_NULL_PARAMETER,           // a pointer parameter is NULL
-  VP8_ENC_ERROR_INVALID_CONFIGURATION,    // configuration is invalid
-  VP8_ENC_ERROR_BAD_DIMENSION,            // picture has invalid width/height
-  VP8_ENC_ERROR_PARTITION0_OVERFLOW,      // partition is bigger than 512k
-  VP8_ENC_ERROR_PARTITION_OVERFLOW,       // partition is bigger than 16M
-  VP8_ENC_ERROR_BAD_WRITE,                // error while flushing bytes
-  VP8_ENC_ERROR_FILE_TOO_BIG,             // file is bigger than 4G
-  VP8_ENC_ERROR_USER_ABORT,               // abort request by user
-  VP8_ENC_ERROR_LAST                      // list terminator. always last.
-} WebPEncodingError;
-
-// maximum width/height allowed (inclusive), in pixels
-#define WEBP_MAX_DIMENSION 16383
-
-// Main exchange structure (input samples, output bytes, statistics)
-struct WebPPicture {
-
-  //   INPUT
-  //////////////
-  // Main flag for encoder selecting between ARGB or YUV input.
-  // It is recommended to use ARGB input (*argb, argb_stride) for lossless
-  // compression, and YUV input (*y, *u, *v, etc.) for lossy compression
-  // since these are the respective native colorspace for these formats.
-  int use_argb;
-
-  // YUV input (mostly used for input to lossy compression)
-  WebPEncCSP colorspace;     // colorspace: should be YUV420 for now (=Y'CbCr).
-  int width, height;         // dimensions (less or equal to WEBP_MAX_DIMENSION)
-  uint8_t *y, *u, *v;        // pointers to luma/chroma planes.
-  int y_stride, uv_stride;   // luma/chroma strides.
-  uint8_t* a;                // pointer to the alpha plane
-  int a_stride;              // stride of the alpha plane
-  uint32_t pad1[2];          // padding for later use
-
-  // ARGB input (mostly used for input to lossless compression)
-  uint32_t* argb;            // Pointer to argb (32 bit) plane.
-  int argb_stride;           // This is stride in pixels units, not bytes.
-  uint32_t pad2[3];          // padding for later use
-
-  //   OUTPUT
-  ///////////////
-  // Byte-emission hook, to store compressed bytes as they are ready.
-  WebPWriterFunction writer;  // can be NULL
-  void* custom_ptr;           // can be used by the writer.
-
-  // map for extra information (only for lossy compression mode)
-  int extra_info_type;    // 1: intra type, 2: segment, 3: quant
-                          // 4: intra-16 prediction mode,
-                          // 5: chroma prediction mode,
-                          // 6: bit cost, 7: distortion
-  uint8_t* extra_info;    // if not NULL, points to an array of size
-                          // ((width + 15) / 16) * ((height + 15) / 16) that
-                          // will be filled with a macroblock map, depending
-                          // on extra_info_type.
-
-  //   STATS AND REPORTS
-  ///////////////////////////
-  // Pointer to side statistics (updated only if not NULL)
-  WebPAuxStats* stats;
-
-  // Error code for the latest error encountered during encoding
-  WebPEncodingError error_code;
-
-  // If not NULL, report progress during encoding.
-  WebPProgressHook progress_hook;
-
-  void* user_data;        // this field is free to be set to any value and
-                          // used during callbacks (like progress-report e.g.).
-
-  uint32_t pad3[3];       // padding for later use
-
-  // Unused for now: original samples (for non-YUV420 modes)
-  uint8_t *u0, *v0;
-  int uv0_stride;
-
-  uint32_t pad4[7];       // padding for later use
-
-  // PRIVATE FIELDS
-  ////////////////////
-  void* memory_;          // row chunk of memory for yuva planes
-  void* memory_argb_;     // and for argb too.
-  void* pad5[2];          // padding for later use
-};
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture*, int);
-
-// Should always be called, to initialize the structure. Returns false in case
-// of version mismatch. WebPPictureInit() must have succeeded before using the
-// 'picture' object.
-// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
-static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
-  return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
-}
-
-//------------------------------------------------------------------------------
-// WebPPicture utils
-
-// Convenience allocation / deallocation based on picture->width/height:
-// Allocate y/u/v buffers as per colorspace/width/height specification.
-// Note! This function will free the previous buffer if needed.
-// Returns false in case of memory error.
-WEBP_EXTERN(int) WebPPictureAlloc(WebPPicture* picture);
-
-// Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
-// Note that this function does _not_ free the memory used by the 'picture'
-// object itself.
-// Besides memory (which is reclaimed) all other fields of 'picture' are
-// preserved.
-WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture);
-
-// Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return,
-// *dst will fully own the copied pixels (this is not a view).
-// Returns false in case of memory allocation error.
-WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
-
-// Compute PSNR or SSIM distortion between two pictures.
-// Result is in dB, stores in result[] in the Y/U/V/Alpha/All order.
-// Returns false in case of error (pic1 and pic2 don't have same dimension, ...)
-// Warning: this function is rather CPU-intensive.
-WEBP_EXTERN(int) WebPPictureDistortion(
-    const WebPPicture* pic1, const WebPPicture* pic2,
-    int metric_type,           // 0 = PSNR, 1 = SSIM
-    float result[5]);
-
-// self-crops a picture to the rectangle defined by top/left/width/height.
-// Returns false in case of memory allocation error, or if the rectangle is
-// outside of the source picture.
-// The rectangle for the view is defined by the top-left corner pixel
-// coordinates (left, top) as well as its width and height. This rectangle
-// must be fully be comprised inside the 'src' source picture. If the source
-// picture uses the YUV420 colorspace, the top and left coordinates will be
-// snapped to even values.
-WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* picture,
-                                 int left, int top, int width, int height);
-
-// Extracts a view from 'src' picture into 'dst'. The rectangle for the view
-// is defined by the top-left corner pixel coordinates (left, top) as well
-// as its width and height. This rectangle must be fully be comprised inside
-// the 'src' source picture. If the source picture uses the YUV420 colorspace,
-// the top and left coordinates will be snapped to even values.
-// Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed
-// ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
-// the original dimension will be lost).
-// Returns false in case of memory allocation error or invalid parameters.
-WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src,
-                                 int left, int top, int width, int height,
-                                 WebPPicture* dst);
-
-// Returns true if the 'picture' is actually a view and therefore does
-// not own the memory for pixels.
-WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture);
-
-// Rescale a picture to new dimension width x height.
-// Now gamma correction is applied.
-// Returns false in case of error (invalid parameter or insufficient memory).
-WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height);
-
-// Colorspace conversion function to import RGB samples.
-// Previous buffer will be free'd, if any.
-// *rgb buffer should have a size of at least height * rgb_stride.
-// Returns false in case of memory error.
-WEBP_EXTERN(int) WebPPictureImportRGB(
-    WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
-// Same, but for RGBA buffer.
-WEBP_EXTERN(int) WebPPictureImportRGBA(
-    WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
-// Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
-// input buffer ignoring the alpha channel. Avoids needing to copy the data
-// to a temporary 24-bit RGB buffer to import the RGB only.
-WEBP_EXTERN(int) WebPPictureImportRGBX(
-    WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
-
-// Variants of the above, but taking BGR(A|X) input.
-WEBP_EXTERN(int) WebPPictureImportBGR(
-    WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
-WEBP_EXTERN(int) WebPPictureImportBGRA(
-    WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
-WEBP_EXTERN(int) WebPPictureImportBGRX(
-    WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
-
-// Converts picture->argb data to the YUVA format specified by 'colorspace'.
-// Upon return, picture->use_argb is set to false. The presence of real
-// non-opaque transparent values is detected, and 'colorspace' will be
-// adjusted accordingly. Note that this method is lossy.
-// Returns false in case of error.
-WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture,
-                                       WebPEncCSP colorspace);
-
-// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
-// The input format must be YUV_420 or YUV_420A.
-// Note that the use of this method is discouraged if one has access to the
-// raw ARGB samples, since using YUV420 is comparatively lossy. Also, the
-// conversion from YUV420 to ARGB incurs a small loss too.
-// Returns false in case of error.
-WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture);
-
-// Helper function: given a width x height plane of YUV(A) samples
-// (with stride 'stride'), clean-up the YUV samples under fully transparent
-// area, to help compressibility (no guarantee, though).
-WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture);
-
-// Scan the picture 'picture' for the presence of non fully opaque alpha values.
-// Returns true in such case. Otherwise returns false (indicating that the
-// alpha plane can be ignored altogether e.g.).
-WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture);
-
-//------------------------------------------------------------------------------
-// Main call
-
-// Main encoding call, after config and picture have been initialized.
-// 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION),
-// and the 'config' object must be a valid one.
-// Returns false in case of error, true otherwise.
-// In case of error, picture->error_code is updated accordingly.
-// 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
-// on the value of 'picture->use_argb'. It is highly recommended to use
-// the former for lossy encoding, and the latter for lossless encoding
-// (when config.lossless is true). Automatic conversion from one format to
-// another is provided but they both incur some loss.
-WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_WEBP_ENCODE_H_ */

+ 0 - 90
drivers/webpold/format_constants.h

@@ -1,90 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//  Internal header for constants related to WebP file format.
-//
-// Author: Urvang ([email protected])
-
-#ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_
-#define WEBP_WEBP_FORMAT_CONSTANTS_H_
-
-// VP8 related constants.
-#define VP8_SIGNATURE 0x9d012a              // Signature in VP8 data.
-#define VP8_MAX_PARTITION0_SIZE (1 << 19)   // max size of mode partition
-#define VP8_MAX_PARTITION_SIZE  (1 << 24)   // max size for token partition
-#define VP8_FRAME_HEADER_SIZE 10  // Size of the frame header within VP8 data.
-
-// VP8L related constants.
-#define VP8L_SIGNATURE_SIZE          1      // VP8L signature size.
-#define VP8L_MAGIC_BYTE              0x2f   // VP8L signature byte.
-#define VP8L_IMAGE_SIZE_BITS         14     // Number of bits used to store
-                                            // width and height.
-#define VP8L_VERSION_BITS            3      // 3 bits reserved for version.
-#define VP8L_VERSION                 0      // version 0
-#define VP8L_FRAME_HEADER_SIZE       5      // Size of the VP8L frame header.
-
-#define MAX_PALETTE_SIZE             256
-#define MAX_CACHE_BITS               11
-#define HUFFMAN_CODES_PER_META_CODE  5
-#define ARGB_BLACK                   0xff000000
-
-#define DEFAULT_CODE_LENGTH          8
-#define MAX_ALLOWED_CODE_LENGTH      15
-
-#define NUM_LITERAL_CODES            256
-#define NUM_LENGTH_CODES             24
-#define NUM_DISTANCE_CODES           40
-#define CODE_LENGTH_CODES            19
-
-#define MIN_HUFFMAN_BITS             2  // min number of Huffman bits
-#define MAX_HUFFMAN_BITS             9  // max number of Huffman bits
-
-#define TRANSFORM_PRESENT            1  // The bit to be written when next data
-                                        // to be read is a transform.
-#define NUM_TRANSFORMS               4  // Maximum number of allowed transform
-                                        // in a bitstream.
-typedef enum {
-  PREDICTOR_TRANSFORM      = 0,
-  CROSS_COLOR_TRANSFORM    = 1,
-  SUBTRACT_GREEN           = 2,
-  COLOR_INDEXING_TRANSFORM = 3
-} VP8LImageTransformType;
-
-// Alpha related constants.
-#define ALPHA_HEADER_LEN            1
-#define ALPHA_NO_COMPRESSION        0
-#define ALPHA_LOSSLESS_COMPRESSION  1
-#define ALPHA_PREPROCESSED_LEVELS   1
-
-// Mux related constants.
-#define TAG_SIZE           4     // Size of a chunk tag (e.g. "VP8L").
-#define CHUNK_SIZE_BYTES   4     // Size needed to store chunk's size.
-#define CHUNK_HEADER_SIZE  8     // Size of a chunk header.
-#define RIFF_HEADER_SIZE   12    // Size of the RIFF header ("RIFFnnnnWEBP").
-#define FRAME_CHUNK_SIZE   15    // Size of a FRM chunk.
-#define LOOP_CHUNK_SIZE    2     // Size of a LOOP chunk.
-#define TILE_CHUNK_SIZE    6     // Size of a TILE chunk.
-#define VP8X_CHUNK_SIZE    10    // Size of a VP8X chunk.
-
-#define TILING_FLAG_BIT    0x01  // Set if tiles are possibly used.
-#define ANIMATION_FLAG_BIT 0x02  // Set if some animation is expected
-#define ICC_FLAG_BIT       0x04  // Whether ICC is present or not.
-#define METADATA_FLAG_BIT  0x08  // Set if some META chunk is possibly present.
-#define ALPHA_FLAG_BIT     0x10  // Should be same as the ALPHA_FLAG in mux.h
-#define ROTATION_FLAG_BITS 0xe0  // all 3 bits for rotation + symmetry
-
-#define MAX_CANVAS_SIZE     (1 << 24)    // 24-bit max for VP8X width/height.
-#define MAX_IMAGE_AREA      (1ULL << 32) // 32-bit max for width x height.
-#define MAX_LOOP_COUNT      (1 << 16)    // maximum value for loop-count
-#define MAX_DURATION        (1 << 24)    // maximum duration
-#define MAX_POSITION_OFFSET (1 << 24)    // maximum frame/tile x/y offset
-
-// Maximum chunk payload is such that adding the header and padding won't
-// overflow a uint32_t.
-#define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1)
-
-#endif  /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */

+ 0 - 182
drivers/webpold/image_loader_webp.cpp

@@ -1,182 +0,0 @@
-/*************************************************************************/
-/*  image_loader_webp.cpp                                                */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "image_loader_webp.h"
-
-#include "print_string.h"
-#include "os/os.h"
-#include "drivers/webp/decode.h"
-#include "drivers/webp/encode.h"
-#include "io/marshalls.h"
-#include <stdlib.h>
-
-static DVector<uint8_t> _webp_lossy_pack(const Image& p_image,float p_quality) {
-
-	ERR_FAIL_COND_V(p_image.empty(),DVector<uint8_t>());
-
-	Image img=p_image;
-	if (img.detect_alpha())
-		img.convert(Image::FORMAT_RGBA);
-	else
-		img.convert(Image::FORMAT_RGB);
-
-	Size2 s(img.get_width(),img.get_height());
-	DVector<uint8_t> data = img.get_data();
-	DVector<uint8_t>::Read r = data.read();
-
-	uint8_t *dst_buff=NULL;
-	size_t dst_size=0;
-	if (img.get_format()==Image::FORMAT_RGB) {
-
-		dst_size = WebPEncodeRGB(r.ptr(),s.width,s.height,3*s.width,CLAMP(p_quality*100.0,0,100.0),&dst_buff);
-	} else {
-		dst_size = WebPEncodeRGBA(r.ptr(),s.width,s.height,4*s.width,CLAMP(p_quality*100.0,0,100.0),&dst_buff);
-	}
-
-	ERR_FAIL_COND_V(dst_size==0,DVector<uint8_t>());
-	DVector<uint8_t> dst;
-	dst.resize(4+dst_size);
-	DVector<uint8_t>::Write w = dst.write();
-	w[0]='W';
-	w[1]='E';
-	w[2]='B';
-	w[3]='P';
-	copymem(&w[4],dst_buff,dst_size);
-	free(dst_buff);
-	w=DVector<uint8_t>::Write();
-	return dst;
-}
-
-static Image _webp_lossy_unpack(const DVector<uint8_t>& p_buffer) {
-
-	int size = p_buffer.size()-4;
-	ERR_FAIL_COND_V(size<=0,Image());
-	DVector<uint8_t>::Read r = p_buffer.read();
-
-	ERR_FAIL_COND_V(r[0]!='W' || r[1]!='E' || r[2]!='B' || r[3]!='P',Image());
-	WebPBitstreamFeatures features;
-	if (WebPGetFeatures(&r[4],size,&features)!=VP8_STATUS_OK) {
-		ERR_EXPLAIN("Error unpacking WEBP image:");
-		ERR_FAIL_V(Image());
-	}
-
-	//print_line("width: "+itos(features.width));
-	//print_line("height: "+itos(features.height));
-	//print_line("alpha: "+itos(features.has_alpha));
-
-	DVector<uint8_t> dst_image;
-	int datasize = features.width*features.height*(features.has_alpha?4:3);
-	dst_image.resize(datasize);
-
-	DVector<uint8_t>::Write dst_w = dst_image.write();
-
-	bool errdec=false;
-	if (features.has_alpha)	 {
-		errdec = WebPDecodeRGBAInto(&r[4],size,dst_w.ptr(),datasize,4*features.width)==NULL;
-	} else {
-		errdec = WebPDecodeRGBInto(&r[4],size,dst_w.ptr(),datasize,3*features.width)==NULL;
-
-	}
-
-	//ERR_EXPLAIN("Error decoding webp! - "+p_file);
-	ERR_FAIL_COND_V(errdec,Image());
-
-	dst_w = DVector<uint8_t>::Write();
-
-	return Image(features.width,features.height,0,features.has_alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB,dst_image);
-
-}
-
-
-Error ImageLoaderWEBP::load_image(Image *p_image,FileAccess *f) {
-
-
-	uint32_t size = f->get_len();
-	DVector<uint8_t> src_image;
-	src_image.resize(size);
-
-	WebPBitstreamFeatures features;
-
-	DVector<uint8_t>::Write src_w = src_image.write();
-	f->get_buffer(src_w.ptr(),size);
-	ERR_FAIL_COND_V(f->eof_reached(), ERR_FILE_EOF);
-
-	if (WebPGetFeatures(src_w.ptr(),size,&features)!=VP8_STATUS_OK) {
-		f->close();
-		//ERR_EXPLAIN("Error decoding WEBP image: "+p_file);
-		ERR_FAIL_V(ERR_FILE_CORRUPT);
-	}
-
-	print_line("width: "+itos(features.width));
-	print_line("height: "+itos(features.height));
-	print_line("alpha: "+itos(features.has_alpha));
-
-	src_w = DVector<uint8_t>::Write();
-
-	DVector<uint8_t> dst_image;
-	int datasize = features.width*features.height*(features.has_alpha?4:3);
-	dst_image.resize(datasize);
-
-	DVector<uint8_t>::Read src_r = src_image.read();
-	DVector<uint8_t>::Write dst_w = dst_image.write();
-
-
-	bool errdec=false;
-	if (features.has_alpha)	 {
-		errdec = WebPDecodeRGBAInto(src_r.ptr(),size,dst_w.ptr(),datasize,4*features.width)==NULL;
-	} else {
-		errdec = WebPDecodeRGBInto(src_r.ptr(),size,dst_w.ptr(),datasize,3*features.width)==NULL;
-
-	}
-
-	//ERR_EXPLAIN("Error decoding webp! - "+p_file);
-	ERR_FAIL_COND_V(errdec,ERR_FILE_CORRUPT);
-
-	src_r = DVector<uint8_t>::Read();
-	dst_w = DVector<uint8_t>::Write();
-
-	*p_image = Image(features.width,features.height,0,features.has_alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB,dst_image);
-
-
-	return OK;
-
-}
-
-void ImageLoaderWEBP::get_recognized_extensions(List<String> *p_extensions) const {
-	
-	p_extensions->push_back("webp");
-}
-
-
-ImageLoaderWEBP::ImageLoaderWEBP() {
-
-	Image::lossy_packer=_webp_lossy_pack;
-	Image::lossy_unpacker=_webp_lossy_unpack;
-}
-
-

+ 0 - 49
drivers/webpold/image_loader_webp.h

@@ -1,49 +0,0 @@
-/*************************************************************************/
-/*  image_loader_webp.h                                                  */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#ifndef IMAGE_LOADER_WEBP_H
-#define IMAGE_LOADER_WEBP_H
-
-#include "io/image_loader.h"
-
-/**
-	@author Juan Linietsky <[email protected]>
-*/
-class ImageLoaderWEBP : public ImageFormatLoader {
-
-
-public:
-
-	virtual Error load_image(Image *p_image,FileAccess *f);
-	virtual void get_recognized_extensions(List<String> *p_extensions) const;	
-	ImageLoaderWEBP();
-};
-
-
-
-#endif

+ 0 - 604
drivers/webpold/mux.h

@@ -1,604 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//  RIFF container manipulation for WEBP images.
-//
-// Authors: Urvang ([email protected])
-//          Vikas ([email protected])
-
-// This API allows manipulation of WebP container images containing features
-// like Color profile, XMP metadata, Animation and Tiling.
-//
-// Code Example#1: Creating a MUX with image data, color profile and XMP
-// metadata.
-//
-//   int copy_data = 0;
-//   WebPMux* mux = WebPMuxNew();
-//   // ... (Prepare image data).
-//   WebPMuxSetImage(mux, &image, copy_data);
-//   // ... (Prepare ICCP color profile data).
-//   WebPMuxSetColorProfile(mux, &icc_profile, copy_data);
-//   // ... (Prepare XMP metadata).
-//   WebPMuxSetMetadata(mux, &xmp, copy_data);
-//   // Get data from mux in WebP RIFF format.
-//   WebPMuxAssemble(mux, &output_data);
-//   WebPMuxDelete(mux);
-//   // ... (Consume output_data; e.g. write output_data.bytes_ to file).
-//   WebPDataClear(&output_data);
-//
-// Code Example#2: Get image and color profile data from a WebP file.
-//
-//   int copy_data = 0;
-//   // ... (Read data from file).
-//   WebPMux* mux = WebPMuxCreate(&data, copy_data);
-//   WebPMuxGetImage(mux, &image);
-//   // ... (Consume image; e.g. call WebPDecode() to decode the data).
-//   WebPMuxGetColorProfile(mux, &icc_profile);
-//   // ... (Consume icc_data).
-//   WebPMuxDelete(mux);
-//   free(data);
-
-#ifndef WEBP_WEBP_MUX_H_
-#define WEBP_WEBP_MUX_H_
-
-#include "./types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define WEBP_MUX_ABI_VERSION 0x0100        // MAJOR(8b) + MINOR(8b)
-
-// Error codes
-typedef enum {
-  WEBP_MUX_OK                 =  1,
-  WEBP_MUX_NOT_FOUND          =  0,
-  WEBP_MUX_INVALID_ARGUMENT   = -1,
-  WEBP_MUX_BAD_DATA           = -2,
-  WEBP_MUX_MEMORY_ERROR       = -3,
-  WEBP_MUX_NOT_ENOUGH_DATA    = -4
-} WebPMuxError;
-
-// Flag values for different features used in VP8X chunk.
-typedef enum {
-  TILE_FLAG       = 0x00000001,
-  ANIMATION_FLAG  = 0x00000002,
-  ICCP_FLAG       = 0x00000004,
-  META_FLAG       = 0x00000008,
-  ALPHA_FLAG      = 0x00000010
-} WebPFeatureFlags;
-
-// IDs for different types of chunks.
-typedef enum {
-  WEBP_CHUNK_VP8X,     // VP8X
-  WEBP_CHUNK_ICCP,     // ICCP
-  WEBP_CHUNK_LOOP,     // LOOP
-  WEBP_CHUNK_FRAME,    // FRM
-  WEBP_CHUNK_TILE,     // TILE
-  WEBP_CHUNK_ALPHA,    // ALPH
-  WEBP_CHUNK_IMAGE,    // VP8/VP8L
-  WEBP_CHUNK_META,     // META
-  WEBP_CHUNK_UNKNOWN,  // Other chunks.
-  WEBP_CHUNK_NIL
-} WebPChunkId;
-
-typedef struct WebPMux WebPMux;   // main opaque object.
-
-// Data type used to describe 'raw' data, e.g., chunk data
-// (ICC profile, metadata) and WebP compressed image data.
-typedef struct {
-  const uint8_t* bytes_;
-  size_t size_;
-} WebPData;
-
-//------------------------------------------------------------------------------
-// Manipulation of a WebPData object.
-
-// Initializes the contents of the 'webp_data' object with default values.
-WEBP_EXTERN(void) WebPDataInit(WebPData* webp_data);
-
-// Clears the contents of the 'webp_data' object by calling free(). Does not
-// deallocate the object itself.
-WEBP_EXTERN(void) WebPDataClear(WebPData* webp_data);
-
-// Allocates necessary storage for 'dst' and copies the contents of 'src'.
-// Returns true on success.
-WEBP_EXTERN(int) WebPDataCopy(const WebPData* src, WebPData* dst);
-
-//------------------------------------------------------------------------------
-// Life of a Mux object
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(WebPMux*) WebPNewInternal(int);
-
-// Creates an empty mux object.
-// Returns:
-//   A pointer to the newly created empty mux object.
-static WEBP_INLINE WebPMux* WebPMuxNew(void) {
-  return WebPNewInternal(WEBP_MUX_ABI_VERSION);
-}
-
-// Deletes the mux object.
-// Parameters:
-//   mux - (in/out) object to be deleted
-WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux);
-
-//------------------------------------------------------------------------------
-// Mux creation.
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int);
-
-// Creates a mux object from raw data given in WebP RIFF format.
-// Parameters:
-//   bitstream - (in) the bitstream data in WebP RIFF format
-//   copy_data - (in) value 1 indicates given data WILL copied to the mux, and
-//               value 0 indicates data will NOT be copied.
-// Returns:
-//   A pointer to the mux object created from given data - on success.
-//   NULL - In case of invalid data or memory error.
-static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
-                                          int copy_data) {
-  return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
-}
-
-//------------------------------------------------------------------------------
-// Single Image.
-
-// Sets the image in the mux object. Any existing images (including frame/tile)
-// will be removed.
-// Parameters:
-//   mux - (in/out) object in which the image is to be set
-//   bitstream - (in) can either be a raw VP8/VP8L bitstream or a single-image
-//               WebP file (non-animated and non-tiled)
-//   copy_data - (in) value 1 indicates given data WILL copied to the mux, and
-//               value 0 indicates data will NOT be copied.
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL.
-//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(WebPMux* mux,
-                                          const WebPData* bitstream,
-                                          int copy_data);
-
-// Gets image data from the mux object.
-// The content of 'bitstream' is allocated using malloc(), and NOT
-// owned by the 'mux' object. It MUST be deallocated by the caller by calling
-// WebPDataClear().
-// Parameters:
-//   mux - (in) object from which the image is to be fetched
-//   bitstream - (out) the image data
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if either mux or bitstream is NULL
-//                               OR mux contains animation/tiling.
-//   WEBP_MUX_NOT_FOUND - if image is not present in mux object.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxGetImage(const WebPMux* mux,
-                                          WebPData* bitstream);
-
-// Deletes the image in the mux object.
-// Parameters:
-//   mux - (in/out) object from which the image is to be deleted
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
-//                               OR if mux contains animation/tiling.
-//   WEBP_MUX_NOT_FOUND - if image is not present in mux object.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxDeleteImage(WebPMux* mux);
-
-//------------------------------------------------------------------------------
-// XMP Metadata.
-
-// Sets the XMP metadata in the mux object. Any existing metadata chunk(s) will
-// be removed.
-// Parameters:
-//   mux - (in/out) object to which the XMP metadata is to be added
-//   metadata - (in) the XMP metadata data to be added
-//   copy_data - (in) value 1 indicates given data WILL copied to the mux, and
-//               value 0 indicates data will NOT be copied.
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux or metadata is NULL.
-//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxSetMetadata(WebPMux* mux,
-                                             const WebPData* metadata,
-                                             int copy_data);
-
-// Gets a reference to the XMP metadata in the mux object.
-// The caller should NOT free the returned data.
-// Parameters:
-//   mux - (in) object from which the XMP metadata is to be fetched
-//   metadata - (out) XMP metadata
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if either mux or metadata is NULL.
-//   WEBP_MUX_NOT_FOUND - if metadata is not present in mux object.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxGetMetadata(const WebPMux* mux,
-                                             WebPData* metadata);
-
-// Deletes the XMP metadata in the mux object.
-// Parameters:
-//   mux - (in/out) object from which XMP metadata is to be deleted
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
-//   WEBP_MUX_NOT_FOUND - If mux does not contain metadata.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxDeleteMetadata(WebPMux* mux);
-
-//------------------------------------------------------------------------------
-// ICC Color Profile.
-
-// Sets the color profile in the mux object. Any existing color profile chunk(s)
-// will be removed.
-// Parameters:
-//   mux - (in/out) object to which the color profile is to be added
-//   color_profile - (in) the color profile data to be added
-//   copy_data - (in) value 1 indicates given data WILL copied to the mux, and
-//               value 0 indicates data will NOT be copied.
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux or color_profile is NULL
-//   WEBP_MUX_MEMORY_ERROR - on memory allocation error
-//   WEBP_MUX_OK - on success
-WEBP_EXTERN(WebPMuxError) WebPMuxSetColorProfile(WebPMux* mux,
-                                                 const WebPData* color_profile,
-                                                 int copy_data);
-
-// Gets a reference to the color profile in the mux object.
-// The caller should NOT free the returned data.
-// Parameters:
-//   mux - (in) object from which the color profile data is to be fetched
-//   color_profile - (out) color profile data
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if either mux or color_profile is NULL.
-//   WEBP_MUX_NOT_FOUND - if color profile is not present in mux object.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxGetColorProfile(const WebPMux* mux,
-                                                 WebPData* color_profile);
-
-// Deletes the color profile in the mux object.
-// Parameters:
-//   mux - (in/out) object from which color profile is to be deleted
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
-//   WEBP_MUX_NOT_FOUND - If mux does not contain color profile.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* mux);
-
-//------------------------------------------------------------------------------
-// Animation.
-
-// Adds an animation frame at the end of the mux object.
-// Note: as WebP only supports even offsets, any odd offset will be snapped to
-// an even location using: offset &= ~1
-// Parameters:
-//   mux - (in/out) object to which an animation frame is to be added
-//   bitstream - (in) the image data corresponding to the frame. It can either
-//               be a raw VP8/VP8L bitstream or a single-image WebP file
-//               (non-animated and non-tiled)
-//   x_offset - (in) x-offset of the frame to be added
-//   y_offset - (in) y-offset of the frame to be added
-//   duration - (in) duration of the frame to be added (in milliseconds)
-//   copy_data - (in) value 1 indicates given data WILL copied to the mux, and
-//               value 0 indicates data will NOT be copied.
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL
-//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame(
-    WebPMux* mux, const WebPData* bitstream,
-    int x_offset, int y_offset, int duration, int copy_data);
-
-// TODO(urvang): Create a struct as follows to reduce argument list size:
-// typedef struct {
-//  WebPData bitstream;
-//  int x_offset, y_offset;
-//  int duration;
-// } FrameInfo;
-
-// Gets the nth animation frame from the mux object.
-// The content of 'bitstream' is allocated using malloc(), and NOT
-// owned by the 'mux' object. It MUST be deallocated by the caller by calling
-// WebPDataClear().
-// nth=0 has a special meaning - last position.
-// Parameters:
-//   mux - (in) object from which the info is to be fetched
-//   nth - (in) index of the frame in the mux object
-//   bitstream - (out) the image data
-//   x_offset - (out) x-offset of the returned frame
-//   y_offset - (out) y-offset of the returned frame
-//   duration - (out) duration of the returned frame (in milliseconds)
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if either mux, bitstream, x_offset,
-//                               y_offset, or duration is NULL
-//   WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object.
-//   WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(
-    const WebPMux* mux, uint32_t nth, WebPData* bitstream,
-    int* x_offset, int* y_offset, int* duration);
-
-// Deletes an animation frame from the mux object.
-// nth=0 has a special meaning - last position.
-// Parameters:
-//   mux - (in/out) object from which a frame is to be deleted
-//   nth - (in) The position from which the frame is to be deleted
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
-//   WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object
-//                        before deletion.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth);
-
-// Sets the animation loop count in the mux object. Any existing loop count
-// value(s) will be removed.
-// Parameters:
-//   mux - (in/out) object in which loop chunk is to be set/added
-//   loop_count - (in) animation loop count value.
-//                Note that loop_count of zero denotes infinite loop.
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
-//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxSetLoopCount(WebPMux* mux, int loop_count);
-
-// Gets the animation loop count from the mux object.
-// Parameters:
-//   mux - (in) object from which the loop count is to be fetched
-//   loop_count - (out) the loop_count value present in the LOOP chunk
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if either of mux or loop_count is NULL
-//   WEBP_MUX_NOT_FOUND - if loop chunk is not present in mux object.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* mux,
-                                              int* loop_count);
-
-//------------------------------------------------------------------------------
-// Tiling.
-
-// Adds a tile at the end of the mux object.
-// Note: as WebP only supports even offsets, any odd offset will be snapped to
-// an even location using: offset &= ~1
-// Parameters:
-//   mux - (in/out) object to which a tile is to be added.
-//   bitstream - (in) the image data corresponding to the frame. It can either
-//               be a raw VP8/VP8L bitstream or a single-image WebP file
-//               (non-animated and non-tiled)
-//   x_offset - (in) x-offset of the tile to be added
-//   y_offset - (in) y-offset of the tile to be added
-//   copy_data - (in) value 1 indicates given data WILL copied to the mux, and
-//               value 0 indicates data will NOT be copied.
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL
-//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxPushTile(
-    WebPMux* mux, const WebPData* bitstream,
-    int x_offset, int y_offset, int copy_data);
-
-// Gets the nth tile from the mux object.
-// The content of 'bitstream' is allocated using malloc(), and NOT
-// owned by the 'mux' object. It MUST be deallocated by the caller by calling
-// WebPDataClear().
-// nth=0 has a special meaning - last position.
-// Parameters:
-//   mux - (in) object from which the info is to be fetched
-//   nth - (in) index of the tile in the mux object
-//   bitstream - (out) the image data
-//   x_offset - (out) x-offset of the returned tile
-//   y_offset - (out) y-offset of the returned tile
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if either mux, bitstream, x_offset or
-//                               y_offset is NULL
-//   WEBP_MUX_NOT_FOUND - if there are less than nth tiles in the mux object.
-//   WEBP_MUX_BAD_DATA - if nth tile chunk in mux is invalid.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxGetTile(
-    const WebPMux* mux, uint32_t nth, WebPData* bitstream,
-    int* x_offset, int* y_offset);
-
-// Deletes a tile from the mux object.
-// nth=0 has a special meaning - last position
-// Parameters:
-//   mux - (in/out) object from which a tile is to be deleted
-//   nth - (in) The position from which the tile is to be deleted
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
-//   WEBP_MUX_NOT_FOUND - If there are less than nth tiles in the mux object
-//                        before deletion.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* mux, uint32_t nth);
-
-//------------------------------------------------------------------------------
-// Misc Utilities.
-
-// Gets the feature flags from the mux object.
-// Parameters:
-//   mux - (in) object from which the features are to be fetched
-//   flags - (out) the flags specifying which features are present in the
-//           mux object. This will be an OR of various flag values.
-//           Enum 'WebPFeatureFlags' can be used to test individual flag values.
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL
-//   WEBP_MUX_NOT_FOUND - if VP8X chunk is not present in mux object.
-//   WEBP_MUX_BAD_DATA - if VP8X chunk in mux is invalid.
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux,
-                                             uint32_t* flags);
-
-// Gets number of chunks having tag value tag in the mux object.
-// Parameters:
-//   mux - (in) object from which the info is to be fetched
-//   id - (in) chunk id specifying the type of chunk
-//   num_elements - (out) number of chunks with the given chunk id
-// Returns:
-//   WEBP_MUX_INVALID_ARGUMENT - if either mux, or num_elements is NULL
-//   WEBP_MUX_OK - on success.
-WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux,
-                                           WebPChunkId id, int* num_elements);
-
-// Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
-// This function also validates the mux object.
-// Note: The content of 'assembled_data' will be ignored and overwritten.
-// Also, the content of 'assembled_data' is allocated using malloc(), and NOT
-// owned by the 'mux' object. It MUST be deallocated by the caller by calling
-// WebPDataClear().
-// Parameters:
-//   mux - (in/out) object whose chunks are to be assembled
-//   assembled_data - (out) assembled WebP data
-// Returns:
-//   WEBP_MUX_BAD_DATA - if mux object is invalid.
-//   WEBP_MUX_INVALID_ARGUMENT - if either mux, output_data or output_size is
-//                               NULL.
-//   WEBP_MUX_MEMORY_ERROR - on memory allocation error.
-//   WEBP_MUX_OK - on success
-WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux,
-                                          WebPData* assembled_data);
-
-//------------------------------------------------------------------------------
-// Demux API.
-// Enables extraction of image and extended format data from WebP files.
-
-#define WEBP_DEMUX_ABI_VERSION 0x0100    // MAJOR(8b) + MINOR(8b)
-
-typedef struct WebPDemuxer WebPDemuxer;
-
-typedef enum {
-  WEBP_DEMUX_PARSING_HEADER,  // Not enough data to parse full header.
-  WEBP_DEMUX_PARSED_HEADER,   // Header parsing complete, data may be available.
-  WEBP_DEMUX_DONE             // Entire file has been parsed.
-} WebPDemuxState;
-
-//------------------------------------------------------------------------------
-// Life of a Demux object
-
-// Internal, version-checked, entry point
-WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal(
-    const WebPData*, int, WebPDemuxState*, int);
-
-// Parses the WebP file given by 'data'.
-// A complete WebP file must be present in 'data' for the function to succeed.
-// Returns a WebPDemuxer object on successful parse, NULL otherwise.
-static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
-  return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
-}
-
-// Parses the WebP file given by 'data'.
-// If 'state' is non-NULL it will be set to indicate the status of the demuxer.
-// Returns a WebPDemuxer object on successful parse, NULL otherwise.
-static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
-    const WebPData* data, WebPDemuxState* state) {
-  return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
-}
-
-// Frees memory associated with 'dmux'.
-WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux);
-
-//------------------------------------------------------------------------------
-// Data/information extraction.
-
-typedef enum {
-  WEBP_FF_FORMAT_FLAGS,  // Extended format flags present in the 'VP8X' chunk.
-  WEBP_FF_CANVAS_WIDTH,
-  WEBP_FF_CANVAS_HEIGHT,
-  WEBP_FF_LOOP_COUNT
-} WebPFormatFeature;
-
-// Get the 'feature' value from the 'dmux'.
-// NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()
-// returned a state > WEBP_DEMUX_PARSING_HEADER.
-WEBP_EXTERN(uint32_t) WebPDemuxGetI(
-    const WebPDemuxer* dmux, WebPFormatFeature feature);
-
-//------------------------------------------------------------------------------
-// Frame iteration.
-
-typedef struct {
-  int frame_num_;
-  int num_frames_;
-  int tile_num_;
-  int num_tiles_;
-  int x_offset_, y_offset_;  // offset relative to the canvas.
-  int width_, height_;       // dimensions of this frame or tile.
-  int duration_;   // display duration in milliseconds.
-  int complete_;   // true if 'tile_' contains a full frame. partial images may
-                   // still be decoded with the WebP incremental decoder.
-  WebPData tile_;  // The frame or tile given by 'frame_num_' and 'tile_num_'.
-
-  uint32_t pad[4];           // padding for later use
-  void* private_;
-} WebPIterator;
-
-// Retrieves frame 'frame_number' from 'dmux'.
-// 'iter->tile_' points to the first tile on return from this function.
-// Individual tiles may be extracted using WebPDemuxSetTile().
-// Setting 'frame_number' equal to 0 will return the last frame of the image.
-// Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
-// Call WebPDemuxReleaseIterator() when use of the iterator is complete.
-// NOTE: 'dmux' must persist for the lifetime of 'iter'.
-WEBP_EXTERN(int) WebPDemuxGetFrame(
-    const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
-
-// Sets 'iter->tile_' to point to the next ('iter->frame_num_' + 1) or previous
-// ('iter->frame_num_' - 1) frame. These functions do not loop.
-// Returns true on success, false otherwise.
-WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter);
-WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter);
-
-// Sets 'iter->tile_' to reflect tile number 'tile_number'.
-// Returns true if tile 'tile_number' is present, false otherwise.
-WEBP_EXTERN(int) WebPDemuxSelectTile(WebPIterator* iter, int tile_number);
-
-// Releases any memory associated with 'iter'.
-// Must be called before destroying the associated WebPDemuxer with
-// WebPDemuxDelete().
-WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter);
-
-//------------------------------------------------------------------------------
-// Chunk iteration.
-
-typedef struct {
-  // The current and total number of chunks with the fourcc given to
-  // WebPDemuxGetChunk().
-  int chunk_num_;
-  int num_chunks_;
-  WebPData chunk_;    // The payload of the chunk.
-
-  uint32_t pad[6];    // padding for later use
-  void* private_;
-} WebPChunkIterator;
-
-// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
-// 'dmux'.
-// 'fourcc' is a character array containing the fourcc of the chunk to return,
-// e.g., "ICCP", "META", "EXIF", etc.
-// Setting 'chunk_number' equal to 0 will return the last chunk in a set.
-// Returns true if the chunk is found, false otherwise. Image related chunk
-// payloads are accessed through WebPDemuxGetFrame() and related functions.
-// Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.
-// NOTE: 'dmux' must persist for the lifetime of the iterator.
-WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux,
-                                   const char fourcc[4], int chunk_number,
-                                   WebPChunkIterator* iter);
-
-// Sets 'iter->chunk_' to point to the next ('iter->chunk_num_' + 1) or previous
-// ('iter->chunk_num_' - 1) chunk. These functions do not loop.
-// Returns true on success, false otherwise.
-WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter);
-WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter);
-
-// Releases any memory associated with 'iter'.
-// Must be called before destroying the associated WebPDemuxer with
-// WebPDemuxDelete().
-WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_WEBP_MUX_H_ */

+ 0 - 902
drivers/webpold/mux/demux.c

@@ -1,902 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//  WebP container demux.
-//
-
-#include "../mux.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "../decode.h"  // WebPGetInfo
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define MKFOURCC(a, b, c, d) ((uint32_t)(a) | (b) << 8 | (c) << 16 | (d) << 24)
-
-typedef struct {
-  size_t start_;        // start location of the data
-  size_t end_;          // end location
-  size_t riff_end_;     // riff chunk end location, can be > end_.
-  size_t buf_size_;     // size of the buffer
-  const uint8_t* buf_;
-} MemBuffer;
-
-typedef struct {
-  size_t offset_;
-  size_t size_;
-} ChunkData;
-
-typedef struct Frame {
-  int x_offset_, y_offset_;
-  int width_, height_;
-  int duration_;
-  int is_tile_;    // this is an image fragment from a 'TILE'.
-  int frame_num_;  // the referent frame number for use in assembling tiles.
-  int complete_;   // img_components_ contains a full image.
-  ChunkData img_components_[2];  // 0=VP8{,L} 1=ALPH
-  struct Frame* next_;
-} Frame;
-
-typedef struct Chunk {
-  ChunkData data_;
-  struct Chunk* next_;
-} Chunk;
-
-struct WebPDemuxer {
-  MemBuffer mem_;
-  WebPDemuxState state_;
-  int is_ext_format_;
-  uint32_t feature_flags_;
-  int canvas_width_, canvas_height_;
-  int loop_count_;
-  int num_frames_;
-  Frame* frames_;
-  Chunk* chunks_;  // non-image chunks
-};
-
-typedef enum {
-  PARSE_OK,
-  PARSE_NEED_MORE_DATA,
-  PARSE_ERROR
-} ParseStatus;
-
-typedef struct ChunkParser {
-  uint8_t id[4];
-  ParseStatus (*parse)(WebPDemuxer* const dmux);
-  int (*valid)(const WebPDemuxer* const dmux);
-} ChunkParser;
-
-static ParseStatus ParseSingleImage(WebPDemuxer* const dmux);
-static ParseStatus ParseVP8X(WebPDemuxer* const dmux);
-static int IsValidSimpleFormat(const WebPDemuxer* const dmux);
-static int IsValidExtendedFormat(const WebPDemuxer* const dmux);
-
-static const ChunkParser kMasterChunks[] = {
-  { { 'V', 'P', '8', ' ' }, ParseSingleImage, IsValidSimpleFormat },
-  { { 'V', 'P', '8', 'L' }, ParseSingleImage, IsValidSimpleFormat },
-  { { 'V', 'P', '8', 'X' }, ParseVP8X,        IsValidExtendedFormat },
-  { { '0', '0', '0', '0' }, NULL,             NULL },
-};
-
-// -----------------------------------------------------------------------------
-// MemBuffer
-
-static int RemapMemBuffer(MemBuffer* const mem,
-                          const uint8_t* data, size_t size) {
-  if (size < mem->buf_size_) return 0;  // can't remap to a shorter buffer!
-
-  mem->buf_ = data;
-  mem->end_ = mem->buf_size_ = size;
-  return 1;
-}
-
-static int InitMemBuffer(MemBuffer* const mem,
-                         const uint8_t* data, size_t size) {
-  memset(mem, 0, sizeof(*mem));
-  return RemapMemBuffer(mem, data, size);
-}
-
-// Return the remaining data size available in 'mem'.
-static WEBP_INLINE size_t MemDataSize(const MemBuffer* const mem) {
-  return (mem->end_ - mem->start_);
-}
-
-// Return true if 'size' exceeds the end of the RIFF chunk.
-static WEBP_INLINE int SizeIsInvalid(const MemBuffer* const mem, size_t size) {
-  return (size > mem->riff_end_ - mem->start_);
-}
-
-static WEBP_INLINE void Skip(MemBuffer* const mem, size_t size) {
-  mem->start_ += size;
-}
-
-static WEBP_INLINE void Rewind(MemBuffer* const mem, size_t size) {
-  mem->start_ -= size;
-}
-
-static WEBP_INLINE const uint8_t* GetBuffer(MemBuffer* const mem) {
-  return mem->buf_ + mem->start_;
-}
-
-static WEBP_INLINE uint8_t GetByte(MemBuffer* const mem) {
-  const uint8_t byte = mem->buf_[mem->start_];
-  Skip(mem, 1);
-  return byte;
-}
-
-// Read 16, 24 or 32 bits stored in little-endian order.
-static WEBP_INLINE int ReadLE16s(const uint8_t* const data) {
-  return (int)(data[0] << 0) | (data[1] << 8);
-}
-
-static WEBP_INLINE int ReadLE24s(const uint8_t* const data) {
-  return ReadLE16s(data) | (data[2] << 16);
-}
-
-static WEBP_INLINE uint32_t ReadLE32(const uint8_t* const data) {
-  return (uint32_t)ReadLE24s(data) | (data[3] << 24);
-}
-
-// In addition to reading, skip the read bytes.
-static WEBP_INLINE int GetLE16s(MemBuffer* const mem) {
-  const uint8_t* const data = mem->buf_ + mem->start_;
-  const int val = ReadLE16s(data);
-  Skip(mem, 2);
-  return val;
-}
-
-static WEBP_INLINE int GetLE24s(MemBuffer* const mem) {
-  const uint8_t* const data = mem->buf_ + mem->start_;
-  const int val = ReadLE24s(data);
-  Skip(mem, 3);
-  return val;
-}
-
-static WEBP_INLINE uint32_t GetLE32(MemBuffer* const mem) {
-  const uint8_t* const data = mem->buf_ + mem->start_;
-  const uint32_t val = ReadLE32(data);
-  Skip(mem, 4);
-  return val;
-}
-
-// -----------------------------------------------------------------------------
-// Secondary chunk parsing
-
-static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) {
-  Chunk** c = &dmux->chunks_;
-  while (*c != NULL) c = &(*c)->next_;
-  *c = chunk;
-  chunk->next_ = NULL;
-}
-
-// Add a frame to the end of the list, ensuring the last frame is complete.
-// Returns true on success, false otherwise.
-static int AddFrame(WebPDemuxer* const dmux, Frame* const frame) {
-  const Frame* last_frame = NULL;
-  Frame** f = &dmux->frames_;
-  while (*f != NULL) {
-    last_frame = *f;
-    f = &(*f)->next_;
-  }
-  if (last_frame != NULL && !last_frame->complete_) return 0;
-  *f = frame;
-  frame->next_ = NULL;
-  return 1;
-}
-
-// Store image bearing chunks to 'frame'.
-static ParseStatus StoreFrame(int frame_num, MemBuffer* const mem,
-                              Frame* const frame) {
-  int alpha_chunks = 0;
-  int image_chunks = 0;
-  int done = (MemDataSize(mem) < CHUNK_HEADER_SIZE);
-  ParseStatus status = PARSE_OK;
-
-  if (done) return PARSE_NEED_MORE_DATA;
-
-  do {
-    const size_t chunk_start_offset = mem->start_;
-    const uint32_t fourcc = GetLE32(mem);
-    const uint32_t payload_size = GetLE32(mem);
-    const uint32_t payload_size_padded = payload_size + (payload_size & 1);
-    const size_t payload_available = (payload_size_padded > MemDataSize(mem))
-                                   ? MemDataSize(mem) : payload_size_padded;
-    const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available;
-
-    if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
-    if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR;
-    if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA;
-
-    switch (fourcc) {
-      case MKFOURCC('A', 'L', 'P', 'H'):
-        if (alpha_chunks == 0) {
-          ++alpha_chunks;
-          frame->img_components_[1].offset_ = chunk_start_offset;
-          frame->img_components_[1].size_ = chunk_size;
-          frame->frame_num_ = frame_num;
-          Skip(mem, payload_available);
-        } else {
-          goto Done;
-        }
-        break;
-      case MKFOURCC('V', 'P', '8', ' '):
-      case MKFOURCC('V', 'P', '8', 'L'):
-        if (image_chunks == 0) {
-          int width = 0, height = 0;
-          ++image_chunks;
-          frame->img_components_[0].offset_ = chunk_start_offset;
-          frame->img_components_[0].size_ = chunk_size;
-          // Extract the width and height from the bitstream, tolerating
-          // failures when the data is incomplete.
-          if (!WebPGetInfo(mem->buf_ + frame->img_components_[0].offset_,
-                           frame->img_components_[0].size_, &width, &height) &&
-              status != PARSE_NEED_MORE_DATA) {
-            return PARSE_ERROR;
-          }
-
-          frame->width_ = width;
-          frame->height_ = height;
-          frame->frame_num_ = frame_num;
-          frame->complete_ = (status == PARSE_OK);
-          Skip(mem, payload_available);
-        } else {
-          goto Done;
-        }
-        break;
- Done:
-      default:
-        // Restore fourcc/size when moving up one level in parsing.
-        Rewind(mem, CHUNK_HEADER_SIZE);
-        done = 1;
-        break;
-    }
-
-    if (mem->start_ == mem->riff_end_) {
-      done = 1;
-    } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) {
-      status = PARSE_NEED_MORE_DATA;
-    }
-  } while (!done && status == PARSE_OK);
-
-  return status;
-}
-
-// Creates a new Frame if 'actual_size' is within bounds and 'mem' contains
-// enough data ('min_size') to parse the payload.
-// Returns PARSE_OK on success with *frame pointing to the new Frame.
-// Returns PARSE_NEED_MORE_DATA with insufficient data, PARSE_ERROR otherwise.
-static ParseStatus NewFrame(const MemBuffer* const mem,
-                            uint32_t min_size, uint32_t expected_size,
-                            uint32_t actual_size, Frame** frame) {
-  if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
-  if (actual_size < expected_size) return PARSE_ERROR;
-  if (MemDataSize(mem) < min_size)  return PARSE_NEED_MORE_DATA;
-
-  *frame = (Frame*)calloc(1, sizeof(**frame));
-  return (*frame == NULL) ? PARSE_ERROR : PARSE_OK;
-}
-
-// Parse a 'FRM ' chunk and any image bearing chunks that immediately follow.
-// 'frame_chunk_size' is the previously validated, padded chunk size.
-static ParseStatus ParseFrame(
-    WebPDemuxer* const dmux, uint32_t frame_chunk_size) {
-  const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG);
-  const uint32_t min_size = frame_chunk_size + CHUNK_HEADER_SIZE;
-  int added_frame = 0;
-  MemBuffer* const mem = &dmux->mem_;
-  Frame* frame;
-  ParseStatus status =
-      NewFrame(mem, min_size, FRAME_CHUNK_SIZE, frame_chunk_size, &frame);
-  if (status != PARSE_OK) return status;
-
-  frame->x_offset_ = 2 * GetLE24s(mem);
-  frame->y_offset_ = 2 * GetLE24s(mem);
-  frame->width_    = 1 + GetLE24s(mem);
-  frame->height_   = 1 + GetLE24s(mem);
-  frame->duration_ = 1 + GetLE24s(mem);
-  Skip(mem, frame_chunk_size - FRAME_CHUNK_SIZE);  // skip any trailing data.
-  if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) {
-    return PARSE_ERROR;
-  }
-
-  // Store a (potentially partial) frame only if the animation flag is set
-  // and there is some data in 'frame'.
-  status = StoreFrame(dmux->num_frames_ + 1, mem, frame);
-  if (status != PARSE_ERROR && has_frames && frame->frame_num_ > 0) {
-    added_frame = AddFrame(dmux, frame);
-    if (added_frame) {
-      ++dmux->num_frames_;
-    } else {
-      status = PARSE_ERROR;
-    }
-  }
-
-  if (!added_frame) free(frame);
-  return status;
-}
-
-// Parse a 'TILE' chunk and any image bearing chunks that immediately follow.
-// 'tile_chunk_size' is the previously validated, padded chunk size.
-static ParseStatus ParseTile(WebPDemuxer* const dmux,
-                             uint32_t tile_chunk_size) {
-  const int has_tiles = !!(dmux->feature_flags_ & TILE_FLAG);
-  const uint32_t min_size = tile_chunk_size + CHUNK_HEADER_SIZE;
-  int added_tile = 0;
-  MemBuffer* const mem = &dmux->mem_;
-  Frame* frame;
-  ParseStatus status =
-      NewFrame(mem, min_size, TILE_CHUNK_SIZE, tile_chunk_size, &frame);
-  if (status != PARSE_OK) return status;
-
-  frame->is_tile_  = 1;
-  frame->x_offset_ = 2 * GetLE24s(mem);
-  frame->y_offset_ = 2 * GetLE24s(mem);
-  Skip(mem, tile_chunk_size - TILE_CHUNK_SIZE);  // skip any trailing data.
-
-  // Store a (potentially partial) tile only if the tile flag is set
-  // and the tile contains some data.
-  status = StoreFrame(dmux->num_frames_, mem, frame);
-  if (status != PARSE_ERROR && has_tiles && frame->frame_num_ > 0) {
-    // Note num_frames_ is incremented only when all tiles have been consumed.
-    added_tile = AddFrame(dmux, frame);
-    if (!added_tile) status = PARSE_ERROR;
-  }
-
-  if (!added_tile) free(frame);
-  return status;
-}
-
-// General chunk storage starting with the header at 'start_offset' allowing
-// the user to request the payload via a fourcc string. 'size' includes the
-// header and the unpadded payload size.
-// Returns true on success, false otherwise.
-static int StoreChunk(WebPDemuxer* const dmux,
-                      size_t start_offset, uint32_t size) {
-  Chunk* const chunk = (Chunk*)calloc(1, sizeof(*chunk));
-  if (chunk == NULL) return 0;
-
-  chunk->data_.offset_ = start_offset;
-  chunk->data_.size_ = size;
-  AddChunk(dmux, chunk);
-  return 1;
-}
-
-// -----------------------------------------------------------------------------
-// Primary chunk parsing
-
-static int ReadHeader(MemBuffer* const mem) {
-  const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE;
-  uint32_t riff_size;
-
-  // Basic file level validation.
-  if (MemDataSize(mem) < min_size) return 0;
-  if (memcmp(GetBuffer(mem), "RIFF", CHUNK_SIZE_BYTES) ||
-      memcmp(GetBuffer(mem) + CHUNK_HEADER_SIZE, "WEBP", CHUNK_SIZE_BYTES)) {
-    return 0;
-  }
-
-  riff_size = ReadLE32(GetBuffer(mem) + TAG_SIZE);
-  if (riff_size < CHUNK_HEADER_SIZE) return 0;
-  if (riff_size > MAX_CHUNK_PAYLOAD) return 0;
-
-  // There's no point in reading past the end of the RIFF chunk
-  mem->riff_end_ = riff_size + CHUNK_HEADER_SIZE;
-  if (mem->buf_size_ > mem->riff_end_) {
-    mem->buf_size_ = mem->end_ = mem->riff_end_;
-  }
-
-  Skip(mem, RIFF_HEADER_SIZE);
-  return 1;
-}
-
-static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
-  const size_t min_size = CHUNK_HEADER_SIZE;
-  MemBuffer* const mem = &dmux->mem_;
-  Frame* frame;
-  ParseStatus status;
-
-  if (dmux->frames_ != NULL) return PARSE_ERROR;
-  if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
-  if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
-
-  frame = (Frame*)calloc(1, sizeof(*frame));
-  if (frame == NULL) return PARSE_ERROR;
-
-  status = StoreFrame(1, &dmux->mem_, frame);
-  if (status != PARSE_ERROR) {
-    const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG);
-    // Clear any alpha when the alpha flag is missing.
-    if (!has_alpha && frame->img_components_[1].size_ > 0) {
-      frame->img_components_[1].offset_ = 0;
-      frame->img_components_[1].size_ = 0;
-    }
-
-    // Use the frame width/height as the canvas values for non-vp8x files.
-    if (!dmux->is_ext_format_ && frame->width_ > 0 && frame->height_ > 0) {
-      dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
-      dmux->canvas_width_ = frame->width_;
-      dmux->canvas_height_ = frame->height_;
-    }
-    AddFrame(dmux, frame);
-    dmux->num_frames_ = 1;
-  } else {
-    free(frame);
-  }
-
-  return status;
-}
-
-static ParseStatus ParseVP8X(WebPDemuxer* const dmux) {
-  MemBuffer* const mem = &dmux->mem_;
-  int loop_chunks = 0;
-  uint32_t vp8x_size;
-  ParseStatus status = PARSE_OK;
-
-  if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
-
-  dmux->is_ext_format_ = 1;
-  Skip(mem, TAG_SIZE);  // VP8X
-  vp8x_size = GetLE32(mem);
-  if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
-  if (vp8x_size < VP8X_CHUNK_SIZE) return PARSE_ERROR;
-  vp8x_size += vp8x_size & 1;
-  if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR;
-  if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA;
-
-  dmux->feature_flags_ = GetByte(mem);
-  Skip(mem, 3);  // Reserved.
-  dmux->canvas_width_  = 1 + GetLE24s(mem);
-  dmux->canvas_height_ = 1 + GetLE24s(mem);
-  if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) {
-    return PARSE_ERROR;  // image final dimension is too large
-  }
-  Skip(mem, vp8x_size - VP8X_CHUNK_SIZE);  // skip any trailing data.
-  dmux->state_ = WEBP_DEMUX_PARSED_HEADER;
-
-  if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR;
-  if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA;
-
-  do {
-    int store_chunk = 1;
-    const size_t chunk_start_offset = mem->start_;
-    const uint32_t fourcc = GetLE32(mem);
-    const uint32_t chunk_size = GetLE32(mem);
-    const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1);
-
-    if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
-    if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR;
-
-    switch (fourcc) {
-      case MKFOURCC('V', 'P', '8', 'X'): {
-        return PARSE_ERROR;
-      }
-      case MKFOURCC('A', 'L', 'P', 'H'):
-      case MKFOURCC('V', 'P', '8', ' '):
-      case MKFOURCC('V', 'P', '8', 'L'): {
-        Rewind(mem, CHUNK_HEADER_SIZE);
-        status = ParseSingleImage(dmux);
-        break;
-      }
-      case MKFOURCC('L', 'O', 'O', 'P'): {
-        if (chunk_size_padded < LOOP_CHUNK_SIZE) return PARSE_ERROR;
-
-        if (MemDataSize(mem) < chunk_size_padded) {
-          status = PARSE_NEED_MORE_DATA;
-        } else if (loop_chunks == 0) {
-          ++loop_chunks;
-          dmux->loop_count_ = GetLE16s(mem);
-          Skip(mem, chunk_size_padded - LOOP_CHUNK_SIZE);
-        } else {
-          store_chunk = 0;
-          goto Skip;
-        }
-        break;
-      }
-      case MKFOURCC('F', 'R', 'M', ' '): {
-        status = ParseFrame(dmux, chunk_size_padded);
-        break;
-      }
-      case MKFOURCC('T', 'I', 'L', 'E'): {
-        if (dmux->num_frames_ == 0) dmux->num_frames_ = 1;
-        status = ParseTile(dmux, chunk_size_padded);
-        break;
-      }
-      case MKFOURCC('I', 'C', 'C', 'P'): {
-        store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG);
-        goto Skip;
-      }
-      case MKFOURCC('M', 'E', 'T', 'A'): {
-        store_chunk = !!(dmux->feature_flags_ & META_FLAG);
-        goto Skip;
-      }
- Skip:
-      default: {
-        if (chunk_size_padded <= MemDataSize(mem)) {
-          if (store_chunk) {
-            // Store only the chunk header and unpadded size as only the payload
-            // will be returned to the user.
-            if (!StoreChunk(dmux, chunk_start_offset,
-                            CHUNK_HEADER_SIZE + chunk_size)) {
-              return PARSE_ERROR;
-            }
-          }
-          Skip(mem, chunk_size_padded);
-        } else {
-          status = PARSE_NEED_MORE_DATA;
-        }
-      }
-    }
-
-    if (mem->start_ == mem->riff_end_) {
-      break;
-    } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) {
-      status = PARSE_NEED_MORE_DATA;
-    }
-  } while (status == PARSE_OK);
-
-  return status;
-}
-
-// -----------------------------------------------------------------------------
-// Format validation
-
-static int IsValidSimpleFormat(const WebPDemuxer* const dmux) {
-  const Frame* const frame = dmux->frames_;
-  if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1;
-
-  if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0;
-  if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0;
-
-  if (frame->width_ <= 0 || frame->height_ <= 0) return 0;
-  return 1;
-}
-
-static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
-  const int has_tiles = !!(dmux->feature_flags_ & TILE_FLAG);
-  const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG);
-  const Frame* f;
-
-  if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1;
-
-  if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0;
-  if (dmux->loop_count_ < 0) return 0;
-  if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0;
-
-  for (f = dmux->frames_; f != NULL; f = f->next_) {
-    const int cur_frame_set = f->frame_num_;
-    int frame_count = 0, tile_count = 0;
-
-    // Check frame properties and if the image is composed of tiles that each
-    // fragment came from a 'TILE'.
-    for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
-      const ChunkData* const image = f->img_components_;
-      const ChunkData* const alpha = f->img_components_ + 1;
-
-      if (!has_tiles && f->is_tile_) return 0;
-      if (!has_frames && f->frame_num_ > 1) return 0;
-      if (f->x_offset_ < 0 || f->y_offset_ < 0) return 0;
-      if (f->complete_) {
-        if (alpha->size_ == 0 && image->size_ == 0) return 0;
-        // Ensure alpha precedes image bitstream.
-        if (alpha->size_ > 0 && alpha->offset_ > image->offset_) {
-          return 0;
-        }
-
-        if (f->width_ <= 0 || f->height_ <= 0) return 0;
-      } else {
-        // Ensure alpha precedes image bitstream.
-        if (alpha->size_ > 0 && image->size_ > 0 &&
-            alpha->offset_ > image->offset_) {
-          return 0;
-        }
-        // There shouldn't be any frames after an incomplete one.
-        if (f->next_ != NULL) return 0;
-      }
-
-      tile_count += f->is_tile_;
-      ++frame_count;
-    }
-    if (!has_tiles && frame_count > 1) return 0;
-    if (tile_count > 0 && frame_count != tile_count) return 0;
-    if (f == NULL) break;
-  }
-  return 1;
-}
-
-// -----------------------------------------------------------------------------
-// WebPDemuxer object
-
-static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) {
-  dmux->state_ = WEBP_DEMUX_PARSING_HEADER;
-  dmux->loop_count_ = 1;
-  dmux->canvas_width_ = -1;
-  dmux->canvas_height_ = -1;
-  dmux->mem_ = *mem;
-}
-
-WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial,
-                               WebPDemuxState* state, int version) {
-  const ChunkParser* parser;
-  int partial;
-  ParseStatus status = PARSE_ERROR;
-  MemBuffer mem;
-  WebPDemuxer* dmux;
-
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DEMUX_ABI_VERSION)) return NULL;
-  if (data == NULL || data->bytes_ == NULL || data->size_ == 0) return NULL;
-
-  if (!InitMemBuffer(&mem, data->bytes_, data->size_)) return NULL;
-  if (!ReadHeader(&mem)) return NULL;
-
-  partial = (mem.buf_size_ < mem.riff_end_);
-  if (!allow_partial && partial) return NULL;
-
-  dmux = (WebPDemuxer*)calloc(1, sizeof(*dmux));
-  if (dmux == NULL) return NULL;
-  InitDemux(dmux, &mem);
-
-  for (parser = kMasterChunks; parser->parse != NULL; ++parser) {
-    if (!memcmp(parser->id, GetBuffer(&dmux->mem_), TAG_SIZE)) {
-      status = parser->parse(dmux);
-      if (status == PARSE_OK) dmux->state_ = WEBP_DEMUX_DONE;
-      if (status != PARSE_ERROR && !parser->valid(dmux)) status = PARSE_ERROR;
-      break;
-    }
-  }
-  if (state) *state = dmux->state_;
-
-  if (status == PARSE_ERROR) {
-    WebPDemuxDelete(dmux);
-    return NULL;
-  }
-  return dmux;
-}
-
-void WebPDemuxDelete(WebPDemuxer* dmux) {
-  Chunk* c;
-  Frame* f;
-  if (dmux == NULL) return;
-
-  for (f = dmux->frames_; f != NULL;) {
-    Frame* const cur_frame = f;
-    f = f->next_;
-    free(cur_frame);
-  }
-  for (c = dmux->chunks_; c != NULL;) {
-    Chunk* const cur_chunk = c;
-    c = c->next_;
-    free(cur_chunk);
-  }
-  free(dmux);
-}
-
-// -----------------------------------------------------------------------------
-
-uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) {
-  if (dmux == NULL) return 0;
-
-  switch (feature) {
-    case WEBP_FF_FORMAT_FLAGS:  return dmux->feature_flags_;
-    case WEBP_FF_CANVAS_WIDTH:  return (uint32_t)dmux->canvas_width_;
-    case WEBP_FF_CANVAS_HEIGHT: return (uint32_t)dmux->canvas_height_;
-    case WEBP_FF_LOOP_COUNT:    return (uint32_t)dmux->loop_count_;
-  }
-  return 0;
-}
-
-// -----------------------------------------------------------------------------
-// Frame iteration
-
-// Find the first 'frame_num' frame. There may be multiple in a tiled frame.
-static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) {
-  const Frame* f;
-  for (f = dmux->frames_; f != NULL; f = f->next_) {
-    if (frame_num == f->frame_num_) break;
-  }
-  return f;
-}
-
-// Returns tile 'tile_num' and the total count.
-static const Frame* GetTile(
-    const Frame* const frame_set, int tile_num, int* const count) {
-  const int this_frame = frame_set->frame_num_;
-  const Frame* f = frame_set;
-  const Frame* tile = NULL;
-  int total;
-
-  for (total = 0; f != NULL && f->frame_num_ == this_frame; f = f->next_) {
-    if (++total == tile_num) tile = f;
-  }
-  *count = total;
-  return tile;
-}
-
-static const uint8_t* GetFramePayload(const uint8_t* const mem_buf,
-                                      const Frame* const frame,
-                                      size_t* const data_size) {
-  *data_size = 0;
-  if (frame != NULL) {
-    const ChunkData* const image = frame->img_components_;
-    const ChunkData* const alpha = frame->img_components_ + 1;
-    size_t start_offset = image->offset_;
-    *data_size = image->size_;
-
-    // if alpha exists it precedes image, update the size allowing for
-    // intervening chunks.
-    if (alpha->size_ > 0) {
-      const size_t inter_size = (image->offset_ > 0)
-                              ? image->offset_ - (alpha->offset_ + alpha->size_)
-                              : 0;
-      start_offset = alpha->offset_;
-      *data_size  += alpha->size_ + inter_size;
-    }
-    return mem_buf + start_offset;
-  }
-  return NULL;
-}
-
-// Create a whole 'frame' from VP8 (+ alpha) or lossless.
-static int SynthesizeFrame(const WebPDemuxer* const dmux,
-                           const Frame* const first_frame,
-                           int tile_num, WebPIterator* const iter) {
-  const uint8_t* const mem_buf = dmux->mem_.buf_;
-  int num_tiles;
-  size_t payload_size = 0;
-  const Frame* const tile = GetTile(first_frame, tile_num, &num_tiles);
-  const uint8_t* const payload = GetFramePayload(mem_buf, tile, &payload_size);
-  if (payload == NULL) return 0;
-
-  iter->frame_num_   = first_frame->frame_num_;
-  iter->num_frames_  = dmux->num_frames_;
-  iter->tile_num_    = tile_num;
-  iter->num_tiles_   = num_tiles;
-  iter->x_offset_    = tile->x_offset_;
-  iter->y_offset_    = tile->y_offset_;
-  iter->width_       = tile->width_;
-  iter->height_      = tile->height_;
-  iter->duration_    = tile->duration_;
-  iter->complete_    = tile->complete_;
-  iter->tile_.bytes_ = payload;
-  iter->tile_.size_  = payload_size;
-  // TODO(jzern): adjust offsets for 'TILE's embedded in 'FRM 's
-  return 1;
-}
-
-static int SetFrame(int frame_num, WebPIterator* const iter) {
-  const Frame* frame;
-  const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
-  if (dmux == NULL || frame_num < 0) return 0;
-  if (frame_num > dmux->num_frames_) return 0;
-  if (frame_num == 0) frame_num = dmux->num_frames_;
-
-  frame = GetFrame(dmux, frame_num);
-  return SynthesizeFrame(dmux, frame, 1, iter);
-}
-
-int WebPDemuxGetFrame(const WebPDemuxer* dmux, int frame, WebPIterator* iter) {
-  if (iter == NULL) return 0;
-
-  memset(iter, 0, sizeof(*iter));
-  iter->private_ = (void*)dmux;
-  return SetFrame(frame, iter);
-}
-
-int WebPDemuxNextFrame(WebPIterator* iter) {
-  if (iter == NULL) return 0;
-  return SetFrame(iter->frame_num_ + 1, iter);
-}
-
-int WebPDemuxPrevFrame(WebPIterator* iter) {
-  if (iter == NULL) return 0;
-  if (iter->frame_num_ <= 1) return 0;
-  return SetFrame(iter->frame_num_ - 1, iter);
-}
-
-int WebPDemuxSelectTile(WebPIterator* iter, int tile) {
-  if (iter != NULL && iter->private_ != NULL && tile > 0) {
-    const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
-    const Frame* const frame = GetFrame(dmux, iter->frame_num_);
-    if (frame == NULL) return 0;
-
-    return SynthesizeFrame(dmux, frame, tile, iter);
-  }
-  return 0;
-}
-
-void WebPDemuxReleaseIterator(WebPIterator* iter) {
-  (void)iter;
-}
-
-// -----------------------------------------------------------------------------
-// Chunk iteration
-
-static int ChunkCount(const WebPDemuxer* const dmux, const char fourcc[4]) {
-  const uint8_t* const mem_buf = dmux->mem_.buf_;
-  const Chunk* c;
-  int count = 0;
-  for (c = dmux->chunks_; c != NULL; c = c->next_) {
-    const uint8_t* const header = mem_buf + c->data_.offset_;
-    if (!memcmp(header, fourcc, TAG_SIZE)) ++count;
-  }
-  return count;
-}
-
-static const Chunk* GetChunk(const WebPDemuxer* const dmux,
-                             const char fourcc[4], int chunk_num) {
-  const uint8_t* const mem_buf = dmux->mem_.buf_;
-  const Chunk* c;
-  int count = 0;
-  for (c = dmux->chunks_; c != NULL; c = c->next_) {
-    const uint8_t* const header = mem_buf + c->data_.offset_;
-    if (!memcmp(header, fourcc, TAG_SIZE)) ++count;
-    if (count == chunk_num) break;
-  }
-  return c;
-}
-
-static int SetChunk(const char fourcc[4], int chunk_num,
-                    WebPChunkIterator* const iter) {
-  const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_;
-  int count;
-
-  if (dmux == NULL || fourcc == NULL || chunk_num < 0) return 0;
-  count = ChunkCount(dmux, fourcc);
-  if (count == 0) return 0;
-  if (chunk_num == 0) chunk_num = count;
-
-  if (chunk_num <= count) {
-    const uint8_t* const mem_buf = dmux->mem_.buf_;
-    const Chunk* const chunk = GetChunk(dmux, fourcc, chunk_num);
-    iter->chunk_.bytes_ = mem_buf + chunk->data_.offset_ + CHUNK_HEADER_SIZE;
-    iter->chunk_.size_  = chunk->data_.size_ - CHUNK_HEADER_SIZE;
-    iter->num_chunks_   = count;
-    iter->chunk_num_    = chunk_num;
-    return 1;
-  }
-  return 0;
-}
-
-int WebPDemuxGetChunk(const WebPDemuxer* dmux,
-                      const char fourcc[4], int chunk_num,
-                      WebPChunkIterator* iter) {
-  if (iter == NULL) return 0;
-
-  memset(iter, 0, sizeof(*iter));
-  iter->private_ = (void*)dmux;
-  return SetChunk(fourcc, chunk_num, iter);
-}
-
-int WebPDemuxNextChunk(WebPChunkIterator* iter) {
-  if (iter != NULL) {
-    const char* const fourcc =
-        (const char*)iter->chunk_.bytes_ - CHUNK_HEADER_SIZE;
-    return SetChunk(fourcc, iter->chunk_num_ + 1, iter);
-  }
-  return 0;
-}
-
-int WebPDemuxPrevChunk(WebPChunkIterator* iter) {
-  if (iter != NULL && iter->chunk_num_ > 1) {
-    const char* const fourcc =
-        (const char*)iter->chunk_.bytes_ - CHUNK_HEADER_SIZE;
-    return SetChunk(fourcc, iter->chunk_num_ - 1, iter);
-  }
-  return 0;
-}
-
-void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) {
-  (void)iter;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}  // extern "C"
-#endif

+ 0 - 712
drivers/webpold/mux/muxedit.c

@@ -1,712 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Set and delete APIs for mux.
-//
-// Authors: Urvang ([email protected])
-//          Vikas ([email protected])
-
-#include <assert.h>
-#include "./muxi.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Life of a mux object.
-
-static void MuxInit(WebPMux* const mux) {
-  if (mux == NULL) return;
-  memset(mux, 0, sizeof(*mux));
-}
-
-WebPMux* WebPNewInternal(int version) {
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
-    return NULL;
-  } else {
-    WebPMux* const mux = (WebPMux*)malloc(sizeof(WebPMux));
-    // If mux is NULL MuxInit is a noop.
-    MuxInit(mux);
-    return mux;
-  }
-}
-
-static void DeleteAllChunks(WebPChunk** const chunk_list) {
-  while (*chunk_list) {
-    *chunk_list = ChunkDelete(*chunk_list);
-  }
-}
-
-static void MuxRelease(WebPMux* const mux) {
-  if (mux == NULL) return;
-  MuxImageDeleteAll(&mux->images_);
-  DeleteAllChunks(&mux->vp8x_);
-  DeleteAllChunks(&mux->iccp_);
-  DeleteAllChunks(&mux->loop_);
-  DeleteAllChunks(&mux->meta_);
-  DeleteAllChunks(&mux->unknown_);
-}
-
-void WebPMuxDelete(WebPMux* mux) {
-  // If mux is NULL MuxRelease is a noop.
-  MuxRelease(mux);
-  free(mux);
-}
-
-//------------------------------------------------------------------------------
-// Helper method(s).
-
-// Handy MACRO, makes MuxSet() very symmetric to MuxGet().
-#define SWITCH_ID_LIST(INDEX, LIST)                                            \
-  if (idx == (INDEX)) {                                                        \
-    err = ChunkAssignData(&chunk, data, copy_data, kChunks[(INDEX)].tag);      \
-    if (err == WEBP_MUX_OK) {                                                  \
-      err = ChunkSetNth(&chunk, (LIST), nth);                                  \
-    }                                                                          \
-    return err;                                                                \
-  }
-
-static WebPMuxError MuxSet(WebPMux* const mux, CHUNK_INDEX idx, uint32_t nth,
-                           const WebPData* const data, int copy_data) {
-  WebPChunk chunk;
-  WebPMuxError err = WEBP_MUX_NOT_FOUND;
-  assert(mux != NULL);
-  assert(!IsWPI(kChunks[idx].id));
-
-  ChunkInit(&chunk);
-  SWITCH_ID_LIST(IDX_VP8X, &mux->vp8x_);
-  SWITCH_ID_LIST(IDX_ICCP, &mux->iccp_);
-  SWITCH_ID_LIST(IDX_LOOP, &mux->loop_);
-  SWITCH_ID_LIST(IDX_META, &mux->meta_);
-  if (idx == IDX_UNKNOWN && data->size_ > TAG_SIZE) {
-    // For raw-data unknown chunk, the first four bytes should be the tag to be
-    // used for the chunk.
-    const WebPData tmp = { data->bytes_ + TAG_SIZE, data->size_ - TAG_SIZE };
-    err = ChunkAssignData(&chunk, &tmp, copy_data, GetLE32(data->bytes_ + 0));
-    if (err == WEBP_MUX_OK)
-      err = ChunkSetNth(&chunk, &mux->unknown_, nth);
-  }
-  return err;
-}
-#undef SWITCH_ID_LIST
-
-static WebPMuxError MuxAddChunk(WebPMux* const mux, uint32_t nth, uint32_t tag,
-                                const uint8_t* data, size_t size,
-                                int copy_data) {
-  const CHUNK_INDEX idx = ChunkGetIndexFromTag(tag);
-  const WebPData chunk_data = { data, size };
-  assert(mux != NULL);
-  assert(size <= MAX_CHUNK_PAYLOAD);
-  assert(idx != IDX_NIL);
-  return MuxSet(mux, idx, nth, &chunk_data, copy_data);
-}
-
-// Create data for frame/tile given image data, offsets and duration.
-static WebPMuxError CreateFrameTileData(const WebPData* const image,
-                                        int x_offset, int y_offset,
-                                        int duration, int is_lossless,
-                                        int is_frame,
-                                        WebPData* const frame_tile) {
-  int width;
-  int height;
-  uint8_t* frame_tile_bytes;
-  const size_t frame_tile_size = kChunks[is_frame ? IDX_FRAME : IDX_TILE].size;
-
-  const int ok = is_lossless ?
-      VP8LGetInfo(image->bytes_, image->size_, &width, &height, NULL) :
-      VP8GetInfo(image->bytes_, image->size_, image->size_, &width, &height);
-  if (!ok) return WEBP_MUX_INVALID_ARGUMENT;
-
-  assert(width > 0 && height > 0 && duration > 0);
-  // Note: assertion on upper bounds is done in PutLE24().
-
-  frame_tile_bytes = (uint8_t*)malloc(frame_tile_size);
-  if (frame_tile_bytes == NULL) return WEBP_MUX_MEMORY_ERROR;
-
-  PutLE24(frame_tile_bytes + 0, x_offset / 2);
-  PutLE24(frame_tile_bytes + 3, y_offset / 2);
-
-  if (is_frame) {
-    PutLE24(frame_tile_bytes + 6, width - 1);
-    PutLE24(frame_tile_bytes + 9, height - 1);
-    PutLE24(frame_tile_bytes + 12, duration - 1);
-  }
-
-  frame_tile->bytes_ = frame_tile_bytes;
-  frame_tile->size_ = frame_tile_size;
-  return WEBP_MUX_OK;
-}
-
-// Outputs image data given a bitstream. The bitstream can either be a
-// single-image WebP file or raw VP8/VP8L data.
-// Also outputs 'is_lossless' to be true if the given bitstream is lossless.
-static WebPMuxError GetImageData(const WebPData* const bitstream,
-                                 WebPData* const image, WebPData* const alpha,
-                                 int* const is_lossless) {
-  WebPDataInit(alpha);  // Default: no alpha.
-  if (bitstream->size_ < TAG_SIZE ||
-      memcmp(bitstream->bytes_, "RIFF", TAG_SIZE)) {
-    // It is NOT webp file data. Return input data as is.
-    *image = *bitstream;
-  } else {
-    // It is webp file data. Extract image data from it.
-    const WebPMuxImage* wpi;
-    WebPMux* const mux = WebPMuxCreate(bitstream, 0);
-    if (mux == NULL) return WEBP_MUX_BAD_DATA;
-    wpi = mux->images_;
-    assert(wpi != NULL && wpi->img_ != NULL);
-    *image = wpi->img_->data_;
-    if (wpi->alpha_ != NULL) {
-      *alpha = wpi->alpha_->data_;
-    }
-    WebPMuxDelete(mux);
-  }
-  *is_lossless = VP8LCheckSignature(image->bytes_, image->size_);
-  return WEBP_MUX_OK;
-}
-
-static WebPMuxError DeleteChunks(WebPChunk** chunk_list, uint32_t tag) {
-  WebPMuxError err = WEBP_MUX_NOT_FOUND;
-  assert(chunk_list);
-  while (*chunk_list) {
-    WebPChunk* const chunk = *chunk_list;
-    if (chunk->tag_ == tag) {
-      *chunk_list = ChunkDelete(chunk);
-      err = WEBP_MUX_OK;
-    } else {
-      chunk_list = &chunk->next_;
-    }
-  }
-  return err;
-}
-
-static WebPMuxError MuxDeleteAllNamedData(WebPMux* const mux, CHUNK_INDEX idx) {
-  const WebPChunkId id = kChunks[idx].id;
-  WebPChunk** chunk_list;
-
-  if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-  if (IsWPI(id)) return WEBP_MUX_INVALID_ARGUMENT;
-
-  chunk_list = MuxGetChunkListFromId(mux, id);
-  if (chunk_list == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-
-  return DeleteChunks(chunk_list, kChunks[idx].tag);
-}
-
-static WebPMuxError DeleteLoopCount(WebPMux* const mux) {
-  return MuxDeleteAllNamedData(mux, IDX_LOOP);
-}
-
-//------------------------------------------------------------------------------
-// Set API(s).
-
-WebPMuxError WebPMuxSetImage(WebPMux* mux,
-                             const WebPData* bitstream, int copy_data) {
-  WebPMuxError err;
-  WebPChunk chunk;
-  WebPMuxImage wpi;
-  WebPData image;
-  WebPData alpha;
-  int is_lossless;
-  int image_tag;
-
-  if (mux == NULL || bitstream == NULL || bitstream->bytes_ == NULL ||
-      bitstream->size_ > MAX_CHUNK_PAYLOAD) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  // If given data is for a whole webp file,
-  // extract only the VP8/VP8L data from it.
-  err = GetImageData(bitstream, &image, &alpha, &is_lossless);
-  if (err != WEBP_MUX_OK) return err;
-  image_tag = is_lossless ? kChunks[IDX_VP8L].tag : kChunks[IDX_VP8].tag;
-
-  // Delete the existing images.
-  MuxImageDeleteAll(&mux->images_);
-
-  MuxImageInit(&wpi);
-
-  if (alpha.bytes_ != NULL) {  // Add alpha chunk.
-    ChunkInit(&chunk);
-    err = ChunkAssignData(&chunk, &alpha, copy_data, kChunks[IDX_ALPHA].tag);
-    if (err != WEBP_MUX_OK) goto Err;
-    err = ChunkSetNth(&chunk, &wpi.alpha_, 1);
-    if (err != WEBP_MUX_OK) goto Err;
-  }
-
-  // Add image chunk.
-  ChunkInit(&chunk);
-  err = ChunkAssignData(&chunk, &image, copy_data, image_tag);
-  if (err != WEBP_MUX_OK) goto Err;
-  err = ChunkSetNth(&chunk, &wpi.img_, 1);
-  if (err != WEBP_MUX_OK) goto Err;
-
-  // Add this image to mux.
-  err = MuxImagePush(&wpi, &mux->images_);
-  if (err != WEBP_MUX_OK) goto Err;
-
-  // All OK.
-  return WEBP_MUX_OK;
-
- Err:
-  // Something bad happened.
-  ChunkRelease(&chunk);
-  MuxImageRelease(&wpi);
-  return err;
-}
-
-WebPMuxError WebPMuxSetMetadata(WebPMux* mux, const WebPData* metadata,
-                                int copy_data) {
-  WebPMuxError err;
-
-  if (mux == NULL || metadata == NULL || metadata->bytes_ == NULL ||
-      metadata->size_ > MAX_CHUNK_PAYLOAD) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  // Delete the existing metadata chunk(s).
-  err = WebPMuxDeleteMetadata(mux);
-  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
-
-  // Add the given metadata chunk.
-  return MuxSet(mux, IDX_META, 1, metadata, copy_data);
-}
-
-WebPMuxError WebPMuxSetColorProfile(WebPMux* mux, const WebPData* color_profile,
-                                    int copy_data) {
-  WebPMuxError err;
-
-  if (mux == NULL || color_profile == NULL || color_profile->bytes_ == NULL ||
-      color_profile->size_ > MAX_CHUNK_PAYLOAD) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  // Delete the existing ICCP chunk(s).
-  err = WebPMuxDeleteColorProfile(mux);
-  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
-
-  // Add the given ICCP chunk.
-  return MuxSet(mux, IDX_ICCP, 1, color_profile, copy_data);
-}
-
-WebPMuxError WebPMuxSetLoopCount(WebPMux* mux, int loop_count) {
-  WebPMuxError err;
-  uint8_t* data = NULL;
-
-  if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-  if (loop_count >= MAX_LOOP_COUNT) return WEBP_MUX_INVALID_ARGUMENT;
-
-  // Delete the existing LOOP chunk(s).
-  err = DeleteLoopCount(mux);
-  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
-
-  // Add the given loop count.
-  data = (uint8_t*)malloc(kChunks[IDX_LOOP].size);
-  if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
-
-  PutLE16(data, loop_count);
-  err = MuxAddChunk(mux, 1, kChunks[IDX_LOOP].tag, data,
-                    kChunks[IDX_LOOP].size, 1);
-  free(data);
-  return err;
-}
-
-static WebPMuxError MuxPushFrameTileInternal(
-    WebPMux* const mux, const WebPData* const bitstream, int x_offset,
-    int y_offset, int duration, int copy_data, uint32_t tag) {
-  WebPChunk chunk;
-  WebPData image;
-  WebPData alpha;
-  WebPMuxImage wpi;
-  WebPMuxError err;
-  WebPData frame_tile;
-  const int is_frame = (tag == kChunks[IDX_FRAME].tag) ? 1 : 0;
-  int is_lossless;
-  int image_tag;
-
-  // Sanity checks.
-  if (mux == NULL || bitstream == NULL || bitstream->bytes_ == NULL ||
-      bitstream->size_ > MAX_CHUNK_PAYLOAD) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-  if (x_offset < 0 || x_offset >= MAX_POSITION_OFFSET ||
-      y_offset < 0 || y_offset >= MAX_POSITION_OFFSET ||
-      duration <= 0 || duration > MAX_DURATION) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  // Snap offsets to even positions.
-  x_offset &= ~1;
-  y_offset &= ~1;
-
-  // If given data is for a whole webp file,
-  // extract only the VP8/VP8L data from it.
-  err = GetImageData(bitstream, &image, &alpha, &is_lossless);
-  if (err != WEBP_MUX_OK) return err;
-  image_tag = is_lossless ? kChunks[IDX_VP8L].tag : kChunks[IDX_VP8].tag;
-
-  WebPDataInit(&frame_tile);
-  ChunkInit(&chunk);
-  MuxImageInit(&wpi);
-
-  if (alpha.bytes_ != NULL) {
-    // Add alpha chunk.
-    err = ChunkAssignData(&chunk, &alpha, copy_data, kChunks[IDX_ALPHA].tag);
-    if (err != WEBP_MUX_OK) goto Err;
-    err = ChunkSetNth(&chunk, &wpi.alpha_, 1);
-    if (err != WEBP_MUX_OK) goto Err;
-    ChunkInit(&chunk);  // chunk owned by wpi.alpha_ now.
-  }
-
-  // Add image chunk.
-  err = ChunkAssignData(&chunk, &image, copy_data, image_tag);
-  if (err != WEBP_MUX_OK) goto Err;
-  err = ChunkSetNth(&chunk, &wpi.img_, 1);
-  if (err != WEBP_MUX_OK) goto Err;
-  ChunkInit(&chunk);  // chunk owned by wpi.img_ now.
-
-  // Create frame/tile data.
-  err = CreateFrameTileData(&image, x_offset, y_offset, duration, is_lossless,
-                            is_frame, &frame_tile);
-  if (err != WEBP_MUX_OK) goto Err;
-
-  // Add frame/tile chunk (with copy_data = 1).
-  err = ChunkAssignData(&chunk, &frame_tile, 1, tag);
-  if (err != WEBP_MUX_OK) goto Err;
-  WebPDataClear(&frame_tile);
-  err = ChunkSetNth(&chunk, &wpi.header_, 1);
-  if (err != WEBP_MUX_OK) goto Err;
-  ChunkInit(&chunk);  // chunk owned by wpi.header_ now.
-
-  // Add this WebPMuxImage to mux.
-  err = MuxImagePush(&wpi, &mux->images_);
-  if (err != WEBP_MUX_OK) goto Err;
-
-  // All is well.
-  return WEBP_MUX_OK;
-
- Err:  // Something bad happened.
-  WebPDataClear(&frame_tile);
-  ChunkRelease(&chunk);
-  MuxImageRelease(&wpi);
-  return err;
-}
-
-WebPMuxError WebPMuxPushFrame(WebPMux* mux, const WebPData* bitstream,
-                              int x_offset, int y_offset,
-                              int duration, int copy_data) {
-  return MuxPushFrameTileInternal(mux, bitstream, x_offset, y_offset,
-                                  duration, copy_data, kChunks[IDX_FRAME].tag);
-}
-
-WebPMuxError WebPMuxPushTile(WebPMux* mux, const WebPData* bitstream,
-                             int x_offset, int y_offset,
-                             int copy_data) {
-  return MuxPushFrameTileInternal(mux, bitstream, x_offset, y_offset,
-                                  1 /* unused duration */, copy_data,
-                                  kChunks[IDX_TILE].tag);
-}
-
-//------------------------------------------------------------------------------
-// Delete API(s).
-
-WebPMuxError WebPMuxDeleteImage(WebPMux* mux) {
-  WebPMuxError err;
-
-  if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-
-  err = MuxValidateForImage(mux);
-  if (err != WEBP_MUX_OK) return err;
-
-  // All well, delete image.
-  MuxImageDeleteAll(&mux->images_);
-  return WEBP_MUX_OK;
-}
-
-WebPMuxError WebPMuxDeleteMetadata(WebPMux* mux) {
-  return MuxDeleteAllNamedData(mux, IDX_META);
-}
-
-WebPMuxError WebPMuxDeleteColorProfile(WebPMux* mux) {
-  return MuxDeleteAllNamedData(mux, IDX_ICCP);
-}
-
-static WebPMuxError DeleteFrameTileInternal(WebPMux* const mux, uint32_t nth,
-                                            CHUNK_INDEX idx) {
-  const WebPChunkId id = kChunks[idx].id;
-  if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-
-  assert(idx == IDX_FRAME || idx == IDX_TILE);
-  return MuxImageDeleteNth(&mux->images_, nth, id);
-}
-
-WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth) {
-  return DeleteFrameTileInternal(mux, nth, IDX_FRAME);
-}
-
-WebPMuxError WebPMuxDeleteTile(WebPMux* mux, uint32_t nth) {
-  return DeleteFrameTileInternal(mux, nth, IDX_TILE);
-}
-
-//------------------------------------------------------------------------------
-// Assembly of the WebP RIFF file.
-
-static WebPMuxError GetFrameTileInfo(const WebPChunk* const frame_tile_chunk,
-                                     int* const x_offset, int* const y_offset,
-                                     int* const duration) {
-  const uint32_t tag = frame_tile_chunk->tag_;
-  const int is_frame = (tag == kChunks[IDX_FRAME].tag);
-  const WebPData* const data = &frame_tile_chunk->data_;
-  const size_t expected_data_size =
-      is_frame ? FRAME_CHUNK_SIZE : TILE_CHUNK_SIZE;
-  assert(frame_tile_chunk != NULL);
-  assert(tag == kChunks[IDX_FRAME].tag || tag ==  kChunks[IDX_TILE].tag);
-  if (data->size_ != expected_data_size) return WEBP_MUX_INVALID_ARGUMENT;
-
-  *x_offset = 2 * GetLE24(data->bytes_ + 0);
-  *y_offset = 2 * GetLE24(data->bytes_ + 3);
-  if (is_frame) *duration = 1 + GetLE24(data->bytes_ + 12);
-  return WEBP_MUX_OK;
-}
-
-WebPMuxError MuxGetImageWidthHeight(const WebPChunk* const image_chunk,
-                                    int* const width, int* const height) {
-  const uint32_t tag = image_chunk->tag_;
-  const WebPData* const data = &image_chunk->data_;
-  int w, h;
-  int ok;
-  assert(image_chunk != NULL);
-  assert(tag == kChunks[IDX_VP8].tag || tag ==  kChunks[IDX_VP8L].tag);
-  ok = (tag == kChunks[IDX_VP8].tag) ?
-      VP8GetInfo(data->bytes_, data->size_, data->size_, &w, &h) :
-      VP8LGetInfo(data->bytes_, data->size_, &w, &h, NULL);
-  if (ok) {
-    *width = w;
-    *height = h;
-    return WEBP_MUX_OK;
-  } else {
-    return WEBP_MUX_BAD_DATA;
-  }
-}
-
-static WebPMuxError GetImageInfo(const WebPMuxImage* const wpi,
-                                 int* const x_offset, int* const y_offset,
-                                 int* const duration,
-                                 int* const width, int* const height) {
-  const WebPChunk* const image_chunk = wpi->img_;
-  const WebPChunk* const frame_tile_chunk = wpi->header_;
-
-  // Get offsets and duration from FRM/TILE chunk.
-  const WebPMuxError err =
-      GetFrameTileInfo(frame_tile_chunk, x_offset, y_offset, duration);
-  if (err != WEBP_MUX_OK) return err;
-
-  // Get width and height from VP8/VP8L chunk.
-  return MuxGetImageWidthHeight(image_chunk, width, height);
-}
-
-static WebPMuxError GetImageCanvasWidthHeight(
-    const WebPMux* const mux, uint32_t flags,
-    int* const width, int* const height) {
-  WebPMuxImage* wpi = NULL;
-  assert(mux != NULL);
-  assert(width != NULL && height != NULL);
-
-  wpi = mux->images_;
-  assert(wpi != NULL);
-  assert(wpi->img_ != NULL);
-
-  if (wpi->next_) {
-    int max_x = 0;
-    int max_y = 0;
-    int64_t image_area = 0;
-    // Aggregate the bounding box for animation frames & tiled images.
-    for (; wpi != NULL; wpi = wpi->next_) {
-      int x_offset, y_offset, duration, w, h;
-      const WebPMuxError err = GetImageInfo(wpi, &x_offset, &y_offset,
-                                            &duration, &w, &h);
-      const int max_x_pos = x_offset + w;
-      const int max_y_pos = y_offset + h;
-      if (err != WEBP_MUX_OK) return err;
-      assert(x_offset < MAX_POSITION_OFFSET);
-      assert(y_offset < MAX_POSITION_OFFSET);
-
-      if (max_x_pos > max_x) max_x = max_x_pos;
-      if (max_y_pos > max_y) max_y = max_y_pos;
-      image_area += w * h;
-    }
-    *width = max_x;
-    *height = max_y;
-    // Crude check to validate that there are no image overlaps/holes for tile
-    // images. Check that the aggregated image area for individual tiles exactly
-    // matches the image area of the constructed canvas. However, the area-match
-    // is necessary but not sufficient condition.
-    if ((flags & TILE_FLAG) && (image_area != (max_x * max_y))) {
-      *width = 0;
-      *height = 0;
-      return WEBP_MUX_INVALID_ARGUMENT;
-    }
-  } else {
-    // For a single image, extract the width & height from VP8/VP8L image-data.
-    int w, h;
-    const WebPChunk* const image_chunk = wpi->img_;
-    const WebPMuxError err = MuxGetImageWidthHeight(image_chunk, &w, &h);
-    if (err != WEBP_MUX_OK) return err;
-    *width = w;
-    *height = h;
-  }
-  return WEBP_MUX_OK;
-}
-
-// VP8X format:
-// Total Size : 10,
-// Flags  : 4 bytes,
-// Width  : 3 bytes,
-// Height : 3 bytes.
-static WebPMuxError CreateVP8XChunk(WebPMux* const mux) {
-  WebPMuxError err = WEBP_MUX_OK;
-  uint32_t flags = 0;
-  int width = 0;
-  int height = 0;
-  uint8_t data[VP8X_CHUNK_SIZE];
-  const size_t data_size = VP8X_CHUNK_SIZE;
-  const WebPMuxImage* images = NULL;
-
-  assert(mux != NULL);
-  images = mux->images_;  // First image.
-  if (images == NULL || images->img_ == NULL ||
-      images->img_->data_.bytes_ == NULL) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  // If VP8X chunk(s) is(are) already present, remove them (and later add new
-  // VP8X chunk with updated flags).
-  err = MuxDeleteAllNamedData(mux, IDX_VP8X);
-  if (err != WEBP_MUX_OK && err != WEBP_MUX_NOT_FOUND) return err;
-
-  // Set flags.
-  if (mux->iccp_ != NULL && mux->iccp_->data_.bytes_ != NULL) {
-    flags |= ICCP_FLAG;
-  }
-
-  if (mux->meta_ != NULL && mux->meta_->data_.bytes_ != NULL) {
-    flags |= META_FLAG;
-  }
-
-  if (images->header_ != NULL) {
-    if (images->header_->tag_ == kChunks[IDX_TILE].tag) {
-      // This is a tiled image.
-      flags |= TILE_FLAG;
-    } else if (images->header_->tag_ == kChunks[IDX_FRAME].tag) {
-      // This is an image with animation.
-      flags |= ANIMATION_FLAG;
-    }
-  }
-
-  if (MuxImageCount(images, WEBP_CHUNK_ALPHA) > 0) {
-    flags |= ALPHA_FLAG;  // Some images have an alpha channel.
-  }
-
-  if (flags == 0) {
-    // For Simple Image, VP8X chunk should not be added.
-    return WEBP_MUX_OK;
-  }
-
-  err = GetImageCanvasWidthHeight(mux, flags, &width, &height);
-  if (err != WEBP_MUX_OK) return err;
-
-  if (width <= 0 || height <= 0) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-  if (width > MAX_CANVAS_SIZE || height > MAX_CANVAS_SIZE) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  if (MuxHasLosslessImages(images)) {
-    // We have a file with a VP8X chunk having some lossless images.
-    // As lossless images implicitly contain alpha, force ALPHA_FLAG to be true.
-    // Note: This 'flags' update must NOT be done for a lossless image
-    // without a VP8X chunk!
-    flags |= ALPHA_FLAG;
-  }
-
-  PutLE32(data + 0, flags);   // VP8X chunk flags.
-  PutLE24(data + 4, width - 1);   // canvas width.
-  PutLE24(data + 7, height - 1);  // canvas height.
-
-  err = MuxAddChunk(mux, 1, kChunks[IDX_VP8X].tag, data, data_size, 1);
-  return err;
-}
-
-WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
-  size_t size = 0;
-  uint8_t* data = NULL;
-  uint8_t* dst = NULL;
-  int num_frames;
-  int num_loop_chunks;
-  WebPMuxError err;
-
-  if (mux == NULL || assembled_data == NULL) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  // Remove LOOP chunk if unnecessary.
-  err = WebPMuxNumChunks(mux, kChunks[IDX_LOOP].id, &num_loop_chunks);
-  if (err != WEBP_MUX_OK) return err;
-  if (num_loop_chunks >= 1) {
-    err = WebPMuxNumChunks(mux, kChunks[IDX_FRAME].id, &num_frames);
-    if (err != WEBP_MUX_OK) return err;
-    if (num_frames == 0) {
-      err = DeleteLoopCount(mux);
-      if (err != WEBP_MUX_OK) return err;
-    }
-  }
-
-  // Create VP8X chunk.
-  err = CreateVP8XChunk(mux);
-  if (err != WEBP_MUX_OK) return err;
-
-  // Allocate data.
-  size = ChunksListDiskSize(mux->vp8x_) + ChunksListDiskSize(mux->iccp_)
-       + ChunksListDiskSize(mux->loop_) + MuxImageListDiskSize(mux->images_)
-       + ChunksListDiskSize(mux->meta_) + ChunksListDiskSize(mux->unknown_)
-       + RIFF_HEADER_SIZE;
-
-  data = (uint8_t*)malloc(size);
-  if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
-
-  // Emit header & chunks.
-  dst = MuxEmitRiffHeader(data, size);
-  dst = ChunkListEmit(mux->vp8x_, dst);
-  dst = ChunkListEmit(mux->iccp_, dst);
-  dst = ChunkListEmit(mux->loop_, dst);
-  dst = MuxImageListEmit(mux->images_, dst);
-  dst = ChunkListEmit(mux->meta_, dst);
-  dst = ChunkListEmit(mux->unknown_, dst);
-  assert(dst == data + size);
-
-  // Validate mux.
-  err = MuxValidate(mux);
-  if (err != WEBP_MUX_OK) {
-    free(data);
-    data = NULL;
-    size = 0;
-  }
-
-  // Finalize.
-  assembled_data->bytes_ = data;
-  assembled_data->size_ = size;
-
-  return err;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 271
drivers/webpold/mux/muxi.h

@@ -1,271 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Internal header for mux library.
-//
-// Author: Urvang ([email protected])
-
-#ifndef WEBP_MUX_MUXI_H_
-#define WEBP_MUX_MUXI_H_
-
-#include <stdlib.h>
-#include "../dec/vp8i.h"
-#include "../dec/vp8li.h"
-#include "../format_constants.h"
-#include "../mux.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Defines and constants.
-
-// Chunk object.
-typedef struct WebPChunk WebPChunk;
-struct WebPChunk {
-  uint32_t        tag_;
-  int             owner_;  // True if *data_ memory is owned internally.
-                           // VP8X, Loop, and other internally created chunks
-                           // like frame/tile are always owned.
-  WebPData        data_;
-  WebPChunk*      next_;
-};
-
-// MuxImage object. Store a full webp image (including frame/tile chunk, alpha
-// chunk and VP8/VP8L chunk),
-typedef struct WebPMuxImage WebPMuxImage;
-struct WebPMuxImage {
-  WebPChunk*  header_;      // Corresponds to WEBP_CHUNK_FRAME/WEBP_CHUNK_TILE.
-  WebPChunk*  alpha_;       // Corresponds to WEBP_CHUNK_ALPHA.
-  WebPChunk*  img_;         // Corresponds to WEBP_CHUNK_IMAGE.
-  int         is_partial_;  // True if only some of the chunks are filled.
-  WebPMuxImage* next_;
-};
-
-// Main mux object. Stores data chunks.
-struct WebPMux {
-  WebPMuxImage*   images_;
-  WebPChunk*      iccp_;
-  WebPChunk*      meta_;
-  WebPChunk*      loop_;
-  WebPChunk*      vp8x_;
-
-  WebPChunk*  unknown_;
-};
-
-// CHUNK_INDEX enum: used for indexing within 'kChunks' (defined below) only.
-// Note: the reason for having two enums ('WebPChunkId' and 'CHUNK_INDEX') is to
-// allow two different chunks to have the same id (e.g. WebPChunkId
-// 'WEBP_CHUNK_IMAGE' can correspond to CHUNK_INDEX 'IDX_VP8' or 'IDX_VP8L').
-typedef enum {
-  IDX_VP8X = 0,
-  IDX_ICCP,
-  IDX_LOOP,
-  IDX_FRAME,
-  IDX_TILE,
-  IDX_ALPHA,
-  IDX_VP8,
-  IDX_VP8L,
-  IDX_META,
-  IDX_UNKNOWN,
-
-  IDX_NIL,
-  IDX_LAST_CHUNK
-} CHUNK_INDEX;
-
-#define NIL_TAG 0x00000000u  // To signal void chunk.
-
-#define MKFOURCC(a, b, c, d) ((uint32_t)(a) | (b) << 8 | (c) << 16 | (d) << 24)
-
-typedef struct {
-  uint32_t      tag;
-  WebPChunkId   id;
-  uint32_t      size;
-} ChunkInfo;
-
-extern const ChunkInfo kChunks[IDX_LAST_CHUNK];
-
-//------------------------------------------------------------------------------
-// Helper functions.
-
-// Read 16, 24 or 32 bits stored in little-endian order.
-static WEBP_INLINE int GetLE16(const uint8_t* const data) {
-  return (int)(data[0] << 0) | (data[1] << 8);
-}
-
-static WEBP_INLINE int GetLE24(const uint8_t* const data) {
-  return GetLE16(data) | (data[2] << 16);
-}
-
-static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) {
-  return (uint32_t)GetLE16(data) | (GetLE16(data + 2) << 16);
-}
-
-// Store 16, 24 or 32 bits in little-endian order.
-static WEBP_INLINE void PutLE16(uint8_t* const data, int val) {
-  assert(val < (1 << 16));
-  data[0] = (val >> 0);
-  data[1] = (val >> 8);
-}
-
-static WEBP_INLINE void PutLE24(uint8_t* const data, int val) {
-  assert(val < (1 << 24));
-  PutLE16(data, val & 0xffff);
-  data[2] = (val >> 16);
-}
-
-static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {
-  PutLE16(data, (int)(val & 0xffff));
-  PutLE16(data + 2, (int)(val >> 16));
-}
-
-static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) {
-  return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U);
-}
-
-//------------------------------------------------------------------------------
-// Chunk object management.
-
-// Initialize.
-void ChunkInit(WebPChunk* const chunk);
-
-// Get chunk index from chunk tag. Returns IDX_NIL if not found.
-CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag);
-
-// Get chunk id from chunk tag. Returns WEBP_CHUNK_NIL if not found.
-WebPChunkId ChunkGetIdFromTag(uint32_t tag);
-
-// Search for nth chunk with given 'tag' in the chunk list.
-// nth = 0 means "last of the list".
-WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag);
-
-// Fill the chunk with the given data.
-WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
-                             int copy_data, uint32_t tag);
-
-// Sets 'chunk' at nth position in the 'chunk_list'.
-// nth = 0 has the special meaning "last of the list".
-WebPMuxError ChunkSetNth(const WebPChunk* chunk, WebPChunk** chunk_list,
-                         uint32_t nth);
-
-// Releases chunk and returns chunk->next_.
-WebPChunk* ChunkRelease(WebPChunk* const chunk);
-
-// Deletes given chunk & returns chunk->next_.
-WebPChunk* ChunkDelete(WebPChunk* const chunk);
-
-// Size of a chunk including header and padding.
-static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) {
-  const size_t data_size = chunk->data_.size_;
-  assert(data_size < MAX_CHUNK_PAYLOAD);
-  return SizeWithPadding(data_size);
-}
-
-// Total size of a list of chunks.
-size_t ChunksListDiskSize(const WebPChunk* chunk_list);
-
-// Write out the given list of chunks into 'dst'.
-uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);
-
-// Get the width & height of image stored in 'image_chunk'.
-WebPMuxError MuxGetImageWidthHeight(const WebPChunk* const image_chunk,
-                                    int* const width, int* const height);
-
-//------------------------------------------------------------------------------
-// MuxImage object management.
-
-// Initialize.
-void MuxImageInit(WebPMuxImage* const wpi);
-
-// Releases image 'wpi' and returns wpi->next.
-WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi);
-
-// Delete image 'wpi' and return the next image in the list or NULL.
-// 'wpi' can be NULL.
-WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);
-
-// Delete all images in 'wpi_list'.
-void MuxImageDeleteAll(WebPMuxImage** const wpi_list);
-
-// Count number of images matching the given tag id in the 'wpi_list'.
-int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id);
-
-// Check if given ID corresponds to an image related chunk.
-static WEBP_INLINE int IsWPI(WebPChunkId id) {
-  switch (id) {
-    case WEBP_CHUNK_FRAME:
-    case WEBP_CHUNK_TILE:
-    case WEBP_CHUNK_ALPHA:
-    case WEBP_CHUNK_IMAGE:  return 1;
-    default:        return 0;
-  }
-}
-
-// Get a reference to appropriate chunk list within an image given chunk tag.
-static WEBP_INLINE WebPChunk** MuxImageGetListFromId(
-    const WebPMuxImage* const wpi, WebPChunkId id) {
-  assert(wpi != NULL);
-  switch (id) {
-    case WEBP_CHUNK_FRAME:
-    case WEBP_CHUNK_TILE:  return (WebPChunk**)&wpi->header_;
-    case WEBP_CHUNK_ALPHA: return (WebPChunk**)&wpi->alpha_;
-    case WEBP_CHUNK_IMAGE: return (WebPChunk**)&wpi->img_;
-    default: return NULL;
-  }
-}
-
-// Pushes 'wpi' at the end of 'wpi_list'.
-WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list);
-
-// Delete nth image in the image list with given tag id.
-WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth,
-                               WebPChunkId id);
-
-// Get nth image in the image list with given tag id.
-WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,
-                            WebPChunkId id, WebPMuxImage** wpi);
-
-// Total size of the given image.
-size_t MuxImageDiskSize(const WebPMuxImage* const wpi);
-
-// Total size of a list of images.
-size_t MuxImageListDiskSize(const WebPMuxImage* wpi_list);
-
-// Write out the given image into 'dst'.
-uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst);
-
-// Write out the given list of images into 'dst'.
-uint8_t* MuxImageListEmit(const WebPMuxImage* wpi_list, uint8_t* dst);
-
-//------------------------------------------------------------------------------
-// Helper methods for mux.
-
-// Checks if the given image list contains at least one lossless image.
-int MuxHasLosslessImages(const WebPMuxImage* images);
-
-// Write out RIFF header into 'data', given total data size 'size'.
-uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size);
-
-// Returns the list where chunk with given ID is to be inserted in mux.
-// Return value is NULL if this chunk should be inserted in mux->images_ list
-// or if 'id' is not known.
-WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id);
-
-// Validates that the given mux has a single image.
-WebPMuxError MuxValidateForImage(const WebPMux* const mux);
-
-// Validates the given mux object.
-WebPMuxError MuxValidate(const WebPMux* const mux);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_MUX_MUXI_H_ */

+ 0 - 576
drivers/webpold/mux/muxinternal.c

@@ -1,576 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Internal objects and utils for mux.
-//
-// Authors: Urvang ([email protected])
-//          Vikas ([email protected])
-
-#include <assert.h>
-#include "./muxi.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define UNDEFINED_CHUNK_SIZE (-1)
-
-const ChunkInfo kChunks[] = {
-  { MKFOURCC('V', 'P', '8', 'X'),  WEBP_CHUNK_VP8X,    VP8X_CHUNK_SIZE },
-  { MKFOURCC('I', 'C', 'C', 'P'),  WEBP_CHUNK_ICCP,    UNDEFINED_CHUNK_SIZE },
-  { MKFOURCC('L', 'O', 'O', 'P'),  WEBP_CHUNK_LOOP,    LOOP_CHUNK_SIZE },
-  { MKFOURCC('F', 'R', 'M', ' '),  WEBP_CHUNK_FRAME,   FRAME_CHUNK_SIZE },
-  { MKFOURCC('T', 'I', 'L', 'E'),  WEBP_CHUNK_TILE,    TILE_CHUNK_SIZE },
-  { MKFOURCC('A', 'L', 'P', 'H'),  WEBP_CHUNK_ALPHA,   UNDEFINED_CHUNK_SIZE },
-  { MKFOURCC('V', 'P', '8', ' '),  WEBP_CHUNK_IMAGE,   UNDEFINED_CHUNK_SIZE },
-  { MKFOURCC('V', 'P', '8', 'L'),  WEBP_CHUNK_IMAGE,   UNDEFINED_CHUNK_SIZE },
-  { MKFOURCC('M', 'E', 'T', 'A'),  WEBP_CHUNK_META,    UNDEFINED_CHUNK_SIZE },
-  { MKFOURCC('U', 'N', 'K', 'N'),  WEBP_CHUNK_UNKNOWN, UNDEFINED_CHUNK_SIZE },
-
-  { NIL_TAG,                    WEBP_CHUNK_NIL,     UNDEFINED_CHUNK_SIZE }
-};
-
-//------------------------------------------------------------------------------
-// Life of a chunk object.
-
-void ChunkInit(WebPChunk* const chunk) {
-  assert(chunk);
-  memset(chunk, 0, sizeof(*chunk));
-  chunk->tag_ = NIL_TAG;
-}
-
-WebPChunk* ChunkRelease(WebPChunk* const chunk) {
-  WebPChunk* next;
-  if (chunk == NULL) return NULL;
-  if (chunk->owner_) {
-    WebPDataClear(&chunk->data_);
-  }
-  next = chunk->next_;
-  ChunkInit(chunk);
-  return next;
-}
-
-//------------------------------------------------------------------------------
-// Chunk misc methods.
-
-CHUNK_INDEX ChunkGetIndexFromTag(uint32_t tag) {
-  int i;
-  for (i = 0; kChunks[i].tag != NIL_TAG; ++i) {
-    if (tag == kChunks[i].tag) return i;
-  }
-  return IDX_NIL;
-}
-
-WebPChunkId ChunkGetIdFromTag(uint32_t tag) {
-  int i;
-  for (i = 0; kChunks[i].tag != NIL_TAG; ++i) {
-    if (tag == kChunks[i].tag) return kChunks[i].id;
-  }
-  return WEBP_CHUNK_NIL;
-}
-
-//------------------------------------------------------------------------------
-// Chunk search methods.
-
-// Returns next chunk in the chunk list with the given tag.
-static WebPChunk* ChunkSearchNextInList(WebPChunk* chunk, uint32_t tag) {
-  while (chunk && chunk->tag_ != tag) {
-    chunk = chunk->next_;
-  }
-  return chunk;
-}
-
-WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag) {
-  uint32_t iter = nth;
-  first = ChunkSearchNextInList(first, tag);
-  if (!first) return NULL;
-
-  while (--iter != 0) {
-    WebPChunk* next_chunk = ChunkSearchNextInList(first->next_, tag);
-    if (next_chunk == NULL) break;
-    first = next_chunk;
-  }
-  return ((nth > 0) && (iter > 0)) ? NULL : first;
-}
-
-// Outputs a pointer to 'prev_chunk->next_',
-//   where 'prev_chunk' is the pointer to the chunk at position (nth - 1).
-// Returns 1 if nth chunk was found, 0 otherwise.
-static int ChunkSearchListToSet(WebPChunk** chunk_list, uint32_t nth,
-                                WebPChunk*** const location) {
-  uint32_t count = 0;
-  assert(chunk_list);
-  *location = chunk_list;
-
-  while (*chunk_list) {
-    WebPChunk* const cur_chunk = *chunk_list;
-    ++count;
-    if (count == nth) return 1;  // Found.
-    chunk_list = &cur_chunk->next_;
-    *location = chunk_list;
-  }
-
-  // *chunk_list is ok to be NULL if adding at last location.
-  return (nth == 0 || (count == nth - 1)) ? 1 : 0;
-}
-
-//------------------------------------------------------------------------------
-// Chunk writer methods.
-
-WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
-                             int copy_data, uint32_t tag) {
-  // For internally allocated chunks, always copy data & make it owner of data.
-  if (tag == kChunks[IDX_VP8X].tag || tag == kChunks[IDX_LOOP].tag) {
-    copy_data = 1;
-  }
-
-  ChunkRelease(chunk);
-
-  if (data != NULL) {
-    if (copy_data) {
-      // Copy data.
-      chunk->data_.bytes_ = (uint8_t*)malloc(data->size_);
-      if (chunk->data_.bytes_ == NULL) return WEBP_MUX_MEMORY_ERROR;
-      memcpy((uint8_t*)chunk->data_.bytes_, data->bytes_, data->size_);
-      chunk->data_.size_ = data->size_;
-
-      // Chunk is owner of data.
-      chunk->owner_ = 1;
-    } else {
-      // Don't copy data.
-      chunk->data_ = *data;
-    }
-  }
-
-  chunk->tag_ = tag;
-
-  return WEBP_MUX_OK;
-}
-
-WebPMuxError ChunkSetNth(const WebPChunk* chunk, WebPChunk** chunk_list,
-                         uint32_t nth) {
-  WebPChunk* new_chunk;
-
-  if (!ChunkSearchListToSet(chunk_list, nth, &chunk_list)) {
-    return WEBP_MUX_NOT_FOUND;
-  }
-
-  new_chunk = (WebPChunk*)malloc(sizeof(*new_chunk));
-  if (new_chunk == NULL) return WEBP_MUX_MEMORY_ERROR;
-  *new_chunk = *chunk;
-  new_chunk->next_ = *chunk_list;
-  *chunk_list = new_chunk;
-  return WEBP_MUX_OK;
-}
-
-//------------------------------------------------------------------------------
-// Chunk deletion method(s).
-
-WebPChunk* ChunkDelete(WebPChunk* const chunk) {
-  WebPChunk* const next = ChunkRelease(chunk);
-  free(chunk);
-  return next;
-}
-
-//------------------------------------------------------------------------------
-// Chunk serialization methods.
-
-size_t ChunksListDiskSize(const WebPChunk* chunk_list) {
-  size_t size = 0;
-  while (chunk_list) {
-    size += ChunkDiskSize(chunk_list);
-    chunk_list = chunk_list->next_;
-  }
-  return size;
-}
-
-static uint8_t* ChunkEmit(const WebPChunk* const chunk, uint8_t* dst) {
-  const size_t chunk_size = chunk->data_.size_;
-  assert(chunk);
-  assert(chunk->tag_ != NIL_TAG);
-  PutLE32(dst + 0, chunk->tag_);
-  PutLE32(dst + TAG_SIZE, (uint32_t)chunk_size);
-  assert(chunk_size == (uint32_t)chunk_size);
-  memcpy(dst + CHUNK_HEADER_SIZE, chunk->data_.bytes_, chunk_size);
-  if (chunk_size & 1)
-    dst[CHUNK_HEADER_SIZE + chunk_size] = 0;  // Add padding.
-  return dst + ChunkDiskSize(chunk);
-}
-
-uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) {
-  while (chunk_list) {
-    dst = ChunkEmit(chunk_list, dst);
-    chunk_list = chunk_list->next_;
-  }
-  return dst;
-}
-
-//------------------------------------------------------------------------------
-// Manipulation of a WebPData object.
-
-void WebPDataInit(WebPData* webp_data) {
-  if (webp_data != NULL) {
-    memset(webp_data, 0, sizeof(*webp_data));
-  }
-}
-
-void WebPDataClear(WebPData* webp_data) {
-  if (webp_data != NULL) {
-    free((void*)webp_data->bytes_);
-    WebPDataInit(webp_data);
-  }
-}
-
-int WebPDataCopy(const WebPData* src, WebPData* dst) {
-  if (src == NULL || dst == NULL) return 0;
-
-  WebPDataInit(dst);
-  if (src->bytes_ != NULL && src->size_ != 0) {
-    dst->bytes_ = (uint8_t*)malloc(src->size_);
-    if (dst->bytes_ == NULL) return 0;
-    memcpy((void*)dst->bytes_, src->bytes_, src->size_);
-    dst->size_ = src->size_;
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// Life of a MuxImage object.
-
-void MuxImageInit(WebPMuxImage* const wpi) {
-  assert(wpi);
-  memset(wpi, 0, sizeof(*wpi));
-}
-
-WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
-  WebPMuxImage* next;
-  if (wpi == NULL) return NULL;
-  ChunkDelete(wpi->header_);
-  ChunkDelete(wpi->alpha_);
-  ChunkDelete(wpi->img_);
-
-  next = wpi->next_;
-  MuxImageInit(wpi);
-  return next;
-}
-
-//------------------------------------------------------------------------------
-// MuxImage search methods.
-
-int MuxImageCount(const WebPMuxImage* wpi_list, WebPChunkId id) {
-  int count = 0;
-  const WebPMuxImage* current;
-  for (current = wpi_list; current != NULL; current = current->next_) {
-    const WebPChunk* const wpi_chunk = *MuxImageGetListFromId(current, id);
-    if (wpi_chunk != NULL) {
-      const WebPChunkId wpi_chunk_id = ChunkGetIdFromTag(wpi_chunk->tag_);
-      if (wpi_chunk_id == id) ++count;
-    }
-  }
-  return count;
-}
-
-// Outputs a pointer to 'prev_wpi->next_',
-//   where 'prev_wpi' is the pointer to the image at position (nth - 1).
-// Returns 1 if nth image with given id was found, 0 otherwise.
-static int SearchImageToGetOrDelete(WebPMuxImage** wpi_list, uint32_t nth,
-                                    WebPChunkId id,
-                                    WebPMuxImage*** const location) {
-  uint32_t count = 0;
-  assert(wpi_list);
-  *location = wpi_list;
-
-  // Search makes sense only for the following.
-  assert(id == WEBP_CHUNK_FRAME || id == WEBP_CHUNK_TILE ||
-         id == WEBP_CHUNK_IMAGE);
-  assert(id != WEBP_CHUNK_IMAGE || nth == 1);
-
-  if (nth == 0) {
-    nth = MuxImageCount(*wpi_list, id);
-    if (nth == 0) return 0;  // Not found.
-  }
-
-  while (*wpi_list) {
-    WebPMuxImage* const cur_wpi = *wpi_list;
-    const WebPChunk* const wpi_chunk = *MuxImageGetListFromId(cur_wpi, id);
-    if (wpi_chunk != NULL) {
-      const WebPChunkId wpi_chunk_id = ChunkGetIdFromTag(wpi_chunk->tag_);
-      if (wpi_chunk_id == id) {
-        ++count;
-        if (count == nth) return 1;  // Found.
-      }
-    }
-    wpi_list = &cur_wpi->next_;
-    *location = wpi_list;
-  }
-  return 0;  // Not found.
-}
-
-//------------------------------------------------------------------------------
-// MuxImage writer methods.
-
-WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list) {
-  WebPMuxImage* new_wpi;
-
-  while (*wpi_list != NULL) {
-    WebPMuxImage* const cur_wpi = *wpi_list;
-    if (cur_wpi->next_ == NULL) break;
-    wpi_list = &cur_wpi->next_;
-  }
-
-  new_wpi = (WebPMuxImage*)malloc(sizeof(*new_wpi));
-  if (new_wpi == NULL) return WEBP_MUX_MEMORY_ERROR;
-  *new_wpi = *wpi;
-  new_wpi->next_ = NULL;
-
-  if (*wpi_list != NULL) {
-    (*wpi_list)->next_ = new_wpi;
-  } else {
-    *wpi_list = new_wpi;
-  }
-  return WEBP_MUX_OK;
-}
-
-//------------------------------------------------------------------------------
-// MuxImage deletion methods.
-
-WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi) {
-  // Delete the components of wpi. If wpi is NULL this is a noop.
-  WebPMuxImage* const next = MuxImageRelease(wpi);
-  free(wpi);
-  return next;
-}
-
-void MuxImageDeleteAll(WebPMuxImage** const wpi_list) {
-  while (*wpi_list) {
-    *wpi_list = MuxImageDelete(*wpi_list);
-  }
-}
-
-WebPMuxError MuxImageDeleteNth(WebPMuxImage** wpi_list, uint32_t nth,
-                               WebPChunkId id) {
-  assert(wpi_list);
-  if (!SearchImageToGetOrDelete(wpi_list, nth, id, &wpi_list)) {
-    return WEBP_MUX_NOT_FOUND;
-  }
-  *wpi_list = MuxImageDelete(*wpi_list);
-  return WEBP_MUX_OK;
-}
-
-//------------------------------------------------------------------------------
-// MuxImage reader methods.
-
-WebPMuxError MuxImageGetNth(const WebPMuxImage** wpi_list, uint32_t nth,
-                            WebPChunkId id, WebPMuxImage** wpi) {
-  assert(wpi_list);
-  assert(wpi);
-  if (!SearchImageToGetOrDelete((WebPMuxImage**)wpi_list, nth, id,
-                                (WebPMuxImage***)&wpi_list)) {
-    return WEBP_MUX_NOT_FOUND;
-  }
-  *wpi = (WebPMuxImage*)*wpi_list;
-  return WEBP_MUX_OK;
-}
-
-//------------------------------------------------------------------------------
-// MuxImage serialization methods.
-
-// Size of an image.
-size_t MuxImageDiskSize(const WebPMuxImage* const wpi) {
-  size_t size = 0;
-  if (wpi->header_ != NULL) size += ChunkDiskSize(wpi->header_);
-  if (wpi->alpha_ != NULL) size += ChunkDiskSize(wpi->alpha_);
-  if (wpi->img_ != NULL) size += ChunkDiskSize(wpi->img_);
-  return size;
-}
-
-size_t MuxImageListDiskSize(const WebPMuxImage* wpi_list) {
-  size_t size = 0;
-  while (wpi_list) {
-    size += MuxImageDiskSize(wpi_list);
-    wpi_list = wpi_list->next_;
-  }
-  return size;
-}
-
-uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst) {
-  // Ordering of chunks to be emitted is strictly as follows:
-  // 1. Frame/Tile chunk (if present).
-  // 2. Alpha chunk (if present).
-  // 3. VP8/VP8L chunk.
-  assert(wpi);
-  if (wpi->header_ != NULL) dst = ChunkEmit(wpi->header_, dst);
-  if (wpi->alpha_ != NULL) dst = ChunkEmit(wpi->alpha_, dst);
-  if (wpi->img_ != NULL) dst = ChunkEmit(wpi->img_, dst);
-  return dst;
-}
-
-uint8_t* MuxImageListEmit(const WebPMuxImage* wpi_list, uint8_t* dst) {
-  while (wpi_list) {
-    dst = MuxImageEmit(wpi_list, dst);
-    wpi_list = wpi_list->next_;
-  }
-  return dst;
-}
-
-//------------------------------------------------------------------------------
-// Helper methods for mux.
-
-int MuxHasLosslessImages(const WebPMuxImage* images) {
-  while (images != NULL) {
-    assert(images->img_ != NULL);
-    if (images->img_->tag_ == kChunks[IDX_VP8L].tag) {
-      return 1;
-    }
-    images = images->next_;
-  }
-  return 0;
-}
-
-uint8_t* MuxEmitRiffHeader(uint8_t* const data, size_t size) {
-  PutLE32(data + 0, MKFOURCC('R', 'I', 'F', 'F'));
-  PutLE32(data + TAG_SIZE, (uint32_t)size - CHUNK_HEADER_SIZE);
-  assert(size == (uint32_t)size);
-  PutLE32(data + TAG_SIZE + CHUNK_SIZE_BYTES, MKFOURCC('W', 'E', 'B', 'P'));
-  return data + RIFF_HEADER_SIZE;
-}
-
-WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id) {
-  assert(mux != NULL);
-  switch(id) {
-    case WEBP_CHUNK_VP8X:    return (WebPChunk**)&mux->vp8x_;
-    case WEBP_CHUNK_ICCP:    return (WebPChunk**)&mux->iccp_;
-    case WEBP_CHUNK_LOOP:    return (WebPChunk**)&mux->loop_;
-    case WEBP_CHUNK_META:    return (WebPChunk**)&mux->meta_;
-    case WEBP_CHUNK_UNKNOWN: return (WebPChunk**)&mux->unknown_;
-    default: return NULL;
-  }
-}
-
-WebPMuxError MuxValidateForImage(const WebPMux* const mux) {
-  const int num_images = MuxImageCount(mux->images_, WEBP_CHUNK_IMAGE);
-  const int num_frames = MuxImageCount(mux->images_, WEBP_CHUNK_FRAME);
-  const int num_tiles  = MuxImageCount(mux->images_, WEBP_CHUNK_TILE);
-
-  if (num_images == 0) {
-    // No images in mux.
-    return WEBP_MUX_NOT_FOUND;
-  } else if (num_images == 1 && num_frames == 0 && num_tiles == 0) {
-    // Valid case (single image).
-    return WEBP_MUX_OK;
-  } else {
-    // Frame/Tile case OR an invalid mux.
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-}
-
-static int IsNotCompatible(int feature, int num_items) {
-  return (feature != 0) != (num_items > 0);
-}
-
-#define NO_FLAG 0
-
-// Test basic constraints:
-// retrieval, maximum number of chunks by index (use -1 to skip)
-// and feature incompatibility (use NO_FLAG to skip).
-// On success returns WEBP_MUX_OK and stores the chunk count in *num.
-static WebPMuxError ValidateChunk(const WebPMux* const mux, CHUNK_INDEX idx,
-                                  WebPFeatureFlags feature,
-                                  WebPFeatureFlags vp8x_flags,
-                                  int max, int* num) {
-  const WebPMuxError err =
-      WebPMuxNumChunks(mux, kChunks[idx].id, num);
-  if (err != WEBP_MUX_OK) return err;
-  if (max > -1 && *num > max) return WEBP_MUX_INVALID_ARGUMENT;
-  if (feature != NO_FLAG && IsNotCompatible(vp8x_flags & feature, *num)) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-  return WEBP_MUX_OK;
-}
-
-WebPMuxError MuxValidate(const WebPMux* const mux) {
-  int num_iccp;
-  int num_meta;
-  int num_loop_chunks;
-  int num_frames;
-  int num_tiles;
-  int num_vp8x;
-  int num_images;
-  int num_alpha;
-  uint32_t flags;
-  WebPMuxError err;
-
-  // Verify mux is not NULL.
-  if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-
-  // Verify mux has at least one image.
-  if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-
-  err = WebPMuxGetFeatures(mux, &flags);
-  if (err != WEBP_MUX_OK) return err;
-
-  // At most one color profile chunk.
-  err = ValidateChunk(mux, IDX_ICCP, ICCP_FLAG, flags, 1, &num_iccp);
-  if (err != WEBP_MUX_OK) return err;
-
-  // At most one XMP metadata.
-  err = ValidateChunk(mux, IDX_META, META_FLAG, flags, 1, &num_meta);
-  if (err != WEBP_MUX_OK) return err;
-
-  // Animation: ANIMATION_FLAG, loop chunk and frame chunk(s) are consistent.
-  // At most one loop chunk.
-  err = ValidateChunk(mux, IDX_LOOP, NO_FLAG, flags, 1, &num_loop_chunks);
-  if (err != WEBP_MUX_OK) return err;
-  err = ValidateChunk(mux, IDX_FRAME, NO_FLAG, flags, -1, &num_frames);
-  if (err != WEBP_MUX_OK) return err;
-
-  {
-    const int has_animation = !!(flags & ANIMATION_FLAG);
-    if (has_animation && (num_loop_chunks == 0 || num_frames == 0)) {
-      return WEBP_MUX_INVALID_ARGUMENT;
-    }
-    if (!has_animation && (num_loop_chunks == 1 || num_frames > 0)) {
-      return WEBP_MUX_INVALID_ARGUMENT;
-    }
-  }
-
-  // Tiling: TILE_FLAG and tile chunk(s) are consistent.
-  err = ValidateChunk(mux, IDX_TILE, TILE_FLAG, flags, -1, &num_tiles);
-  if (err != WEBP_MUX_OK) return err;
-
-  // Verify either VP8X chunk is present OR there is only one elem in
-  // mux->images_.
-  err = ValidateChunk(mux, IDX_VP8X, NO_FLAG, flags, 1, &num_vp8x);
-  if (err != WEBP_MUX_OK) return err;
-  err = ValidateChunk(mux, IDX_VP8, NO_FLAG, flags, -1, &num_images);
-  if (err != WEBP_MUX_OK) return err;
-  if (num_vp8x == 0 && num_images != 1) return WEBP_MUX_INVALID_ARGUMENT;
-
-  // ALPHA_FLAG & alpha chunk(s) are consistent.
-  if (num_vp8x > 0 && MuxHasLosslessImages(mux->images_)) {
-    // Special case: we have a VP8X chunk as well as some lossless images.
-    if (!(flags & ALPHA_FLAG)) return WEBP_MUX_INVALID_ARGUMENT;
-  } else {
-    err = ValidateChunk(mux, IDX_ALPHA, ALPHA_FLAG, flags, -1, &num_alpha);
-    if (err != WEBP_MUX_OK) return err;
-  }
-
-  // num_tiles & num_images are consistent.
-  if (num_tiles > 0 && num_images != num_tiles) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  return WEBP_MUX_OK;
-}
-
-#undef NO_FLAG
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 411
drivers/webpold/mux/muxread.c

@@ -1,411 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Read APIs for mux.
-//
-// Authors: Urvang ([email protected])
-//          Vikas ([email protected])
-
-#include <assert.h>
-#include "./muxi.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Helper method(s).
-
-// Handy MACRO.
-#define SWITCH_ID_LIST(INDEX, LIST)                                           \
-  if (idx == (INDEX)) {                                                       \
-    const WebPChunk* const chunk = ChunkSearchList((LIST), nth,               \
-                                                   kChunks[(INDEX)].tag);     \
-    if (chunk) {                                                              \
-      *data = chunk->data_;                                                   \
-      return WEBP_MUX_OK;                                                     \
-    } else {                                                                  \
-      return WEBP_MUX_NOT_FOUND;                                              \
-    }                                                                         \
-  }
-
-static WebPMuxError MuxGet(const WebPMux* const mux, CHUNK_INDEX idx,
-                           uint32_t nth, WebPData* const data) {
-  assert(mux != NULL);
-  assert(!IsWPI(kChunks[idx].id));
-  WebPDataInit(data);
-
-  SWITCH_ID_LIST(IDX_VP8X, mux->vp8x_);
-  SWITCH_ID_LIST(IDX_ICCP, mux->iccp_);
-  SWITCH_ID_LIST(IDX_LOOP, mux->loop_);
-  SWITCH_ID_LIST(IDX_META, mux->meta_);
-  SWITCH_ID_LIST(IDX_UNKNOWN, mux->unknown_);
-  return WEBP_MUX_NOT_FOUND;
-}
-#undef SWITCH_ID_LIST
-
-// Fill the chunk with the given data (includes chunk header bytes), after some
-// verifications.
-static WebPMuxError ChunkVerifyAndAssignData(WebPChunk* chunk,
-                                             const uint8_t* data,
-                                             size_t data_size, size_t riff_size,
-                                             int copy_data) {
-  uint32_t chunk_size;
-  WebPData chunk_data;
-
-  // Sanity checks.
-  if (data_size < TAG_SIZE) return WEBP_MUX_NOT_ENOUGH_DATA;
-  chunk_size = GetLE32(data + TAG_SIZE);
-
-  {
-    const size_t chunk_disk_size = SizeWithPadding(chunk_size);
-    if (chunk_disk_size > riff_size) return WEBP_MUX_BAD_DATA;
-    if (chunk_disk_size > data_size) return WEBP_MUX_NOT_ENOUGH_DATA;
-  }
-
-  // Data assignment.
-  chunk_data.bytes_ = data + CHUNK_HEADER_SIZE;
-  chunk_data.size_ = chunk_size;
-  return ChunkAssignData(chunk, &chunk_data, copy_data, GetLE32(data + 0));
-}
-
-//------------------------------------------------------------------------------
-// Create a mux object from WebP-RIFF data.
-
-WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
-                               int version) {
-  size_t riff_size;
-  uint32_t tag;
-  const uint8_t* end;
-  WebPMux* mux = NULL;
-  WebPMuxImage* wpi = NULL;
-  const uint8_t* data;
-  size_t size;
-  WebPChunk chunk;
-  ChunkInit(&chunk);
-
-  // Sanity checks.
-  if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
-    return NULL;  // version mismatch
-  }
-  if (bitstream == NULL) return NULL;
-
-  data = bitstream->bytes_;
-  size = bitstream->size_;
-
-  if (data == NULL) return NULL;
-  if (size < RIFF_HEADER_SIZE) return NULL;
-  if (GetLE32(data + 0) != MKFOURCC('R', 'I', 'F', 'F') ||
-      GetLE32(data + CHUNK_HEADER_SIZE) != MKFOURCC('W', 'E', 'B', 'P')) {
-    return NULL;
-  }
-
-  mux = WebPMuxNew();
-  if (mux == NULL) return NULL;
-
-  if (size < RIFF_HEADER_SIZE + TAG_SIZE) goto Err;
-
-  tag = GetLE32(data + RIFF_HEADER_SIZE);
-  if (tag != kChunks[IDX_VP8].tag &&
-      tag != kChunks[IDX_VP8L].tag &&
-      tag != kChunks[IDX_VP8X].tag) {
-    goto Err;  // First chunk should be VP8, VP8L or VP8X.
-  }
-
-  riff_size = SizeWithPadding(GetLE32(data + TAG_SIZE));
-  if (riff_size > MAX_CHUNK_PAYLOAD || riff_size > size) {
-    goto Err;
-  } else {
-    if (riff_size < size) {  // Redundant data after last chunk.
-      size = riff_size;  // To make sure we don't read any data beyond mux_size.
-    }
-  }
-
-  end = data + size;
-  data += RIFF_HEADER_SIZE;
-  size -= RIFF_HEADER_SIZE;
-
-  wpi = (WebPMuxImage*)malloc(sizeof(*wpi));
-  if (wpi == NULL) goto Err;
-  MuxImageInit(wpi);
-
-  // Loop over chunks.
-  while (data != end) {
-    WebPChunkId id;
-    WebPMuxError err;
-
-    err = ChunkVerifyAndAssignData(&chunk, data, size, riff_size, copy_data);
-    if (err != WEBP_MUX_OK) goto Err;
-
-    id = ChunkGetIdFromTag(chunk.tag_);
-
-    if (IsWPI(id)) {  // An image chunk (frame/tile/alpha/vp8).
-      WebPChunk** wpi_chunk_ptr =
-          MuxImageGetListFromId(wpi, id);  // Image chunk to set.
-      assert(wpi_chunk_ptr != NULL);
-      if (*wpi_chunk_ptr != NULL) goto Err;  // Consecutive alpha chunks or
-                                             // consecutive frame/tile chunks.
-      if (ChunkSetNth(&chunk, wpi_chunk_ptr, 1) != WEBP_MUX_OK) goto Err;
-      if (id == WEBP_CHUNK_IMAGE) {
-        wpi->is_partial_ = 0;  // wpi is completely filled.
-        // Add this to mux->images_ list.
-        if (MuxImagePush(wpi, &mux->images_) != WEBP_MUX_OK) goto Err;
-        MuxImageInit(wpi);  // Reset for reading next image.
-      } else {
-        wpi->is_partial_ = 1;  // wpi is only partially filled.
-      }
-    } else {  // A non-image chunk.
-      WebPChunk** chunk_list;
-      if (wpi->is_partial_) goto Err;  // Encountered a non-image chunk before
-                                       // getting all chunks of an image.
-      chunk_list = MuxGetChunkListFromId(mux, id);  // List to add this chunk.
-      if (chunk_list == NULL) chunk_list = &mux->unknown_;
-      if (ChunkSetNth(&chunk, chunk_list, 0) != WEBP_MUX_OK) goto Err;
-    }
-    {
-      const size_t data_size = ChunkDiskSize(&chunk);
-      data += data_size;
-      size -= data_size;
-    }
-    ChunkInit(&chunk);
-  }
-
-  // Validate mux if complete.
-  if (MuxValidate(mux) != WEBP_MUX_OK) goto Err;
-
-  MuxImageDelete(wpi);
-  return mux;  // All OK;
-
- Err:  // Something bad happened.
-  ChunkRelease(&chunk);
-  MuxImageDelete(wpi);
-  WebPMuxDelete(mux);
-  return NULL;
-}
-
-//------------------------------------------------------------------------------
-// Get API(s).
-
-WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags) {
-  WebPData data;
-  WebPMuxError err;
-
-  if (mux == NULL || flags == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-  *flags = 0;
-
-  // Check if VP8X chunk is present.
-  err = MuxGet(mux, IDX_VP8X, 1, &data);
-  if (err == WEBP_MUX_NOT_FOUND) {
-    // Check if VP8/VP8L chunk is present.
-    err = WebPMuxGetImage(mux, &data);
-    WebPDataClear(&data);
-    return err;
-  } else if (err != WEBP_MUX_OK) {
-    return err;
-  }
-
-  if (data.size_ < CHUNK_SIZE_BYTES) return WEBP_MUX_BAD_DATA;
-
-  // All OK. Fill up flags.
-  *flags = GetLE32(data.bytes_);
-  return WEBP_MUX_OK;
-}
-
-static uint8_t* EmitVP8XChunk(uint8_t* const dst, int width,
-                              int height, uint32_t flags) {
-  const size_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE;
-  assert(width >= 1 && height >= 1);
-  assert(width <= MAX_CANVAS_SIZE && height <= MAX_CANVAS_SIZE);
-  assert(width * (uint64_t)height < MAX_IMAGE_AREA);
-  PutLE32(dst, MKFOURCC('V', 'P', '8', 'X'));
-  PutLE32(dst + TAG_SIZE, VP8X_CHUNK_SIZE);
-  PutLE32(dst + CHUNK_HEADER_SIZE, flags);
-  PutLE24(dst + CHUNK_HEADER_SIZE + 4, width - 1);
-  PutLE24(dst + CHUNK_HEADER_SIZE + 7, height - 1);
-  return dst + vp8x_size;
-}
-
-// Assemble a single image WebP bitstream from 'wpi'.
-static WebPMuxError SynthesizeBitstream(WebPMuxImage* const wpi,
-                                        WebPData* const bitstream) {
-  uint8_t* dst;
-
-  // Allocate data.
-  const int need_vp8x = (wpi->alpha_ != NULL);
-  const size_t vp8x_size = need_vp8x ? CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE : 0;
-  const size_t alpha_size = need_vp8x ? ChunkDiskSize(wpi->alpha_) : 0;
-  // Note: No need to output FRM/TILE chunk for a single image.
-  const size_t size = RIFF_HEADER_SIZE + vp8x_size + alpha_size +
-                      ChunkDiskSize(wpi->img_);
-  uint8_t* const data = (uint8_t*)malloc(size);
-  if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
-
-  // Main RIFF header.
-  dst = MuxEmitRiffHeader(data, size);
-
-  if (need_vp8x) {
-    int w, h;
-    WebPMuxError err;
-    assert(wpi->img_ != NULL);
-    err = MuxGetImageWidthHeight(wpi->img_, &w, &h);
-    if (err != WEBP_MUX_OK) {
-      free(data);
-      return err;
-    }
-    dst = EmitVP8XChunk(dst, w, h, ALPHA_FLAG);  // VP8X.
-    dst = ChunkListEmit(wpi->alpha_, dst);       // ALPH.
-  }
-
-  // Bitstream.
-  dst = ChunkListEmit(wpi->img_, dst);
-  assert(dst == data + size);
-
-  // Output.
-  bitstream->bytes_ = data;
-  bitstream->size_ = size;
-  return WEBP_MUX_OK;
-}
-
-WebPMuxError WebPMuxGetImage(const WebPMux* mux, WebPData* bitstream) {
-  WebPMuxError err;
-  WebPMuxImage* wpi = NULL;
-
-  if (mux == NULL || bitstream == NULL) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  err = MuxValidateForImage(mux);
-  if (err != WEBP_MUX_OK) return err;
-
-  // All well. Get the image.
-  err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, 1, WEBP_CHUNK_IMAGE,
-                       &wpi);
-  assert(err == WEBP_MUX_OK);  // Already tested above.
-
-  return SynthesizeBitstream(wpi, bitstream);
-}
-
-WebPMuxError WebPMuxGetMetadata(const WebPMux* mux, WebPData* metadata) {
-  if (mux == NULL || metadata == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-  return MuxGet(mux, IDX_META, 1, metadata);
-}
-
-WebPMuxError WebPMuxGetColorProfile(const WebPMux* mux,
-                                    WebPData* color_profile) {
-  if (mux == NULL || color_profile == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-  return MuxGet(mux, IDX_ICCP, 1, color_profile);
-}
-
-WebPMuxError WebPMuxGetLoopCount(const WebPMux* mux, int* loop_count) {
-  WebPData image;
-  WebPMuxError err;
-
-  if (mux == NULL || loop_count == NULL) return WEBP_MUX_INVALID_ARGUMENT;
-
-  err = MuxGet(mux, IDX_LOOP, 1, &image);
-  if (err != WEBP_MUX_OK) return err;
-  if (image.size_ < kChunks[WEBP_CHUNK_LOOP].size) return WEBP_MUX_BAD_DATA;
-  *loop_count = GetLE16(image.bytes_);
-
-  return WEBP_MUX_OK;
-}
-
-static WebPMuxError MuxGetFrameTileInternal(
-    const WebPMux* const mux, uint32_t nth, WebPData* const bitstream,
-    int* const x_offset, int* const y_offset, int* const duration,
-    uint32_t tag) {
-  const WebPData* frame_tile_data;
-  WebPMuxError err;
-  WebPMuxImage* wpi;
-
-  const int is_frame = (tag == kChunks[WEBP_CHUNK_FRAME].tag) ? 1 : 0;
-  const CHUNK_INDEX idx = is_frame ? IDX_FRAME : IDX_TILE;
-  const WebPChunkId id = kChunks[idx].id;
-
-  if (mux == NULL || bitstream == NULL ||
-      x_offset == NULL || y_offset == NULL || (is_frame && duration == NULL)) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  // Get the nth WebPMuxImage.
-  err = MuxImageGetNth((const WebPMuxImage**)&mux->images_, nth, id, &wpi);
-  if (err != WEBP_MUX_OK) return err;
-
-  // Get frame chunk.
-  assert(wpi->header_ != NULL);  // As MuxImageGetNth() already checked header_.
-  frame_tile_data = &wpi->header_->data_;
-
-  if (frame_tile_data->size_ < kChunks[idx].size) return WEBP_MUX_BAD_DATA;
-  *x_offset = 2 * GetLE24(frame_tile_data->bytes_ + 0);
-  *y_offset = 2 * GetLE24(frame_tile_data->bytes_ + 3);
-  if (is_frame) *duration = 1 + GetLE24(frame_tile_data->bytes_ + 12);
-
-  return SynthesizeBitstream(wpi, bitstream);
-}
-
-WebPMuxError WebPMuxGetFrame(const WebPMux* mux, uint32_t nth,
-                             WebPData* bitstream,
-                             int* x_offset, int* y_offset, int* duration) {
-  return MuxGetFrameTileInternal(mux, nth, bitstream, x_offset, y_offset,
-                                 duration, kChunks[IDX_FRAME].tag);
-}
-
-WebPMuxError WebPMuxGetTile(const WebPMux* mux, uint32_t nth,
-                            WebPData* bitstream,
-                            int* x_offset, int* y_offset) {
-  return MuxGetFrameTileInternal(mux, nth, bitstream, x_offset, y_offset, NULL,
-                                 kChunks[IDX_TILE].tag);
-}
-
-// Get chunk index from chunk id. Returns IDX_NIL if not found.
-static CHUNK_INDEX ChunkGetIndexFromId(WebPChunkId id) {
-  int i;
-  for (i = 0; kChunks[i].id != WEBP_CHUNK_NIL; ++i) {
-    if (id == kChunks[i].id) return i;
-  }
-  return IDX_NIL;
-}
-
-// Count number of chunks matching 'tag' in the 'chunk_list'.
-// If tag == NIL_TAG, any tag will be matched.
-static int CountChunks(const WebPChunk* const chunk_list, uint32_t tag) {
-  int count = 0;
-  const WebPChunk* current;
-  for (current = chunk_list; current != NULL; current = current->next_) {
-    if (tag == NIL_TAG || current->tag_ == tag) {
-      count++;  // Count chunks whose tags match.
-    }
-  }
-  return count;
-}
-
-WebPMuxError WebPMuxNumChunks(const WebPMux* mux,
-                              WebPChunkId id, int* num_elements) {
-  if (mux == NULL || num_elements == NULL) {
-    return WEBP_MUX_INVALID_ARGUMENT;
-  }
-
-  if (IsWPI(id)) {
-    *num_elements = MuxImageCount(mux->images_, id);
-  } else {
-    WebPChunk* const* chunk_list = MuxGetChunkListFromId(mux, id);
-    if (chunk_list == NULL) {
-      *num_elements = 0;
-    } else {
-      const CHUNK_INDEX idx = ChunkGetIndexFromId(id);
-      *num_elements = CountChunks(*chunk_list, kChunks[idx].tag);
-    }
-  }
-
-  return WEBP_MUX_OK;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 45
drivers/webpold/types.h

@@ -1,45 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-//  Common types
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_WEBP_TYPES_H_
-#define WEBP_WEBP_TYPES_H_
-
-#include <stddef.h>  // for size_t
-
-#ifndef _MSC_VER
-#include <inttypes.h>
-#ifdef __STRICT_ANSI__
-#define WEBP_INLINE
-#else  /* __STRICT_ANSI__ */
-#define WEBP_INLINE inline
-#endif
-#else
-typedef signed   char int8_t;
-typedef unsigned char uint8_t;
-typedef signed   short int16_t;
-typedef unsigned short uint16_t;
-typedef signed   int int32_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
-typedef long long int int64_t;
-#define WEBP_INLINE __forceinline
-#endif  /* _MSC_VER */
-
-#ifndef WEBP_EXTERN
-// This explicitly marks library functions and allows for changing the
-// signature for e.g., Windows DLL builds.
-#define WEBP_EXTERN(type) extern type
-#endif  /* WEBP_EXTERN */
-
-// Macro to check ABI compatibility (same major revision number)
-#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
-
-#endif  /* WEBP_WEBP_TYPES_H_ */

+ 0 - 229
drivers/webpold/utils/bit_reader.c

@@ -1,229 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Boolean decoder
-//
-// Author: Skal ([email protected])
-
-#include "./bit_reader.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define MK(X) (((bit_t)(X) << (BITS)) | (MASK))
-
-//------------------------------------------------------------------------------
-// VP8BitReader
-
-void VP8InitBitReader(VP8BitReader* const br,
-                      const uint8_t* const start, const uint8_t* const end) {
-  assert(br != NULL);
-  assert(start != NULL);
-  assert(start <= end);
-  br->range_   = MK(255 - 1);
-  br->buf_     = start;
-  br->buf_end_ = end;
-  br->value_   = 0;
-  br->missing_ = 8;   // to load the very first 8bits
-  br->eof_     = 0;
-}
-
-const uint8_t kVP8Log2Range[128] = {
-     7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
-  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  0
-};
-
-// range = (range << kVP8Log2Range[range]) + trailing 1's
-const bit_t kVP8NewRange[128] = {
-  MK(127), MK(127), MK(191), MK(127), MK(159), MK(191), MK(223), MK(127),
-  MK(143), MK(159), MK(175), MK(191), MK(207), MK(223), MK(239), MK(127),
-  MK(135), MK(143), MK(151), MK(159), MK(167), MK(175), MK(183), MK(191),
-  MK(199), MK(207), MK(215), MK(223), MK(231), MK(239), MK(247), MK(127),
-  MK(131), MK(135), MK(139), MK(143), MK(147), MK(151), MK(155), MK(159),
-  MK(163), MK(167), MK(171), MK(175), MK(179), MK(183), MK(187), MK(191),
-  MK(195), MK(199), MK(203), MK(207), MK(211), MK(215), MK(219), MK(223),
-  MK(227), MK(231), MK(235), MK(239), MK(243), MK(247), MK(251), MK(127),
-  MK(129), MK(131), MK(133), MK(135), MK(137), MK(139), MK(141), MK(143),
-  MK(145), MK(147), MK(149), MK(151), MK(153), MK(155), MK(157), MK(159),
-  MK(161), MK(163), MK(165), MK(167), MK(169), MK(171), MK(173), MK(175),
-  MK(177), MK(179), MK(181), MK(183), MK(185), MK(187), MK(189), MK(191),
-  MK(193), MK(195), MK(197), MK(199), MK(201), MK(203), MK(205), MK(207),
-  MK(209), MK(211), MK(213), MK(215), MK(217), MK(219), MK(221), MK(223),
-  MK(225), MK(227), MK(229), MK(231), MK(233), MK(235), MK(237), MK(239),
-  MK(241), MK(243), MK(245), MK(247), MK(249), MK(251), MK(253), MK(127)
-};
-
-#undef MK
-
-void VP8LoadFinalBytes(VP8BitReader* const br) {
-  assert(br != NULL && br->buf_ != NULL);
-  // Only read 8bits at a time
-  if (br->buf_ < br->buf_end_) {
-    br->value_ |= (bit_t)(*br->buf_++) << ((BITS) - 8 + br->missing_);
-    br->missing_ -= 8;
-  } else {
-    br->eof_ = 1;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Higher-level calls
-
-uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
-  uint32_t v = 0;
-  while (bits-- > 0) {
-    v |= VP8GetBit(br, 0x80) << bits;
-  }
-  return v;
-}
-
-int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
-  const int value = VP8GetValue(br, bits);
-  return VP8Get(br) ? -value : value;
-}
-
-//------------------------------------------------------------------------------
-// VP8LBitReader
-
-#define MAX_NUM_BIT_READ 25
-
-static const uint32_t kBitMask[MAX_NUM_BIT_READ] = {
-  0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767,
-  65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215
-};
-
-void VP8LInitBitReader(VP8LBitReader* const br,
-                       const uint8_t* const start,
-                       size_t length) {
-  size_t i;
-  assert(br != NULL);
-  assert(start != NULL);
-  assert(length < 0xfffffff8u);   // can't happen with a RIFF chunk.
-
-  br->buf_ = start;
-  br->len_ = length;
-  br->val_ = 0;
-  br->pos_ = 0;
-  br->bit_pos_ = 0;
-  br->eos_ = 0;
-  br->error_ = 0;
-  for (i = 0; i < sizeof(br->val_) && i < br->len_; ++i) {
-    br->val_ |= ((uint64_t)br->buf_[br->pos_]) << (8 * i);
-    ++br->pos_;
-  }
-}
-
-void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
-                            const uint8_t* const buf, size_t len) {
-  assert(br != NULL);
-  assert(buf != NULL);
-  assert(len < 0xfffffff8u);   // can't happen with a RIFF chunk.
-  br->eos_ = (br->pos_ >= len);
-  br->buf_ = buf;
-  br->len_ = len;
-}
-
-static void ShiftBytes(VP8LBitReader* const br) {
-  while (br->bit_pos_ >= 8 && br->pos_ < br->len_) {
-    br->val_ >>= 8;
-    br->val_ |= ((uint64_t)br->buf_[br->pos_]) << 56;
-    ++br->pos_;
-    br->bit_pos_ -= 8;
-  }
-}
-
-void VP8LFillBitWindow(VP8LBitReader* const br) {
-  if (br->bit_pos_ >= 32) {
-#if defined(__x86_64__) || defined(_M_X64)
-    if (br->pos_ + 8 < br->len_) {
-      br->val_ >>= 32;
-      // The expression below needs a little-endian arch to work correctly.
-      // This gives a large speedup for decoding speed.
-      br->val_ |= *(const uint64_t *)(br->buf_ + br->pos_) << 32;
-      br->pos_ += 4;
-      br->bit_pos_ -= 32;
-    } else {
-      // Slow path.
-      ShiftBytes(br);
-    }
-#else
-    // Always the slow path.
-    ShiftBytes(br);
-#endif
-  }
-  if (br->pos_ == br->len_ && br->bit_pos_ == 64) {
-    br->eos_ = 1;
-  }
-}
-
-uint32_t VP8LReadOneBit(VP8LBitReader* const br) {
-  const uint32_t val = (br->val_ >> br->bit_pos_) & 1;
-  // Flag an error at end_of_stream.
-  if (!br->eos_) {
-    ++br->bit_pos_;
-    if (br->bit_pos_ >= 32) {
-      ShiftBytes(br);
-    }
-    // After this last bit is read, check if eos needs to be flagged.
-    if (br->pos_ == br->len_ && br->bit_pos_ == 64) {
-      br->eos_ = 1;
-    }
-  } else {
-    br->error_ = 1;
-  }
-  return val;
-}
-
-uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
-  uint32_t val = 0;
-  assert(n_bits >= 0);
-  // Flag an error if end_of_stream or n_bits is more than allowed limit.
-  if (!br->eos_ && n_bits < MAX_NUM_BIT_READ) {
-    // If this read is going to cross the read buffer, set the eos flag.
-    if (br->pos_ == br->len_) {
-      if ((br->bit_pos_ + n_bits) >= 64) {
-        br->eos_ = 1;
-        if ((br->bit_pos_ + n_bits) > 64) return val;
-      }
-    }
-    val = (br->val_ >> br->bit_pos_) & kBitMask[n_bits];
-    br->bit_pos_ += n_bits;
-    if (br->bit_pos_ >= 40) {
-      if (br->pos_ + 5 < br->len_) {
-        br->val_ >>= 40;
-        br->val_ |=
-            (((uint64_t)br->buf_[br->pos_ + 0]) << 24) |
-            (((uint64_t)br->buf_[br->pos_ + 1]) << 32) |
-            (((uint64_t)br->buf_[br->pos_ + 2]) << 40) |
-            (((uint64_t)br->buf_[br->pos_ + 3]) << 48) |
-            (((uint64_t)br->buf_[br->pos_ + 4]) << 56);
-        br->pos_ += 5;
-        br->bit_pos_ -= 40;
-      }
-      if (br->bit_pos_ >= 8) {
-        ShiftBytes(br);
-      }
-    }
-  } else {
-    br->error_ = 1;
-  }
-  return val;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 198
drivers/webpold/utils/bit_reader.h

@@ -1,198 +0,0 @@
-//
-// Copyright 2010 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Boolean decoder
-//
-// Author: Skal ([email protected])
-//         Vikas Arora ([email protected])
-
-#ifndef WEBP_UTILS_BIT_READER_H_
-#define WEBP_UTILS_BIT_READER_H_
-
-#include <assert.h>
-#ifdef _MSC_VER
-#include <stdlib.h>  // _byteswap_ulong
-#endif
-#include <string.h>  // For memcpy
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define BITS 32     // can be 32, 16 or 8
-#define MASK ((((bit_t)1) << (BITS)) - 1)
-#if (BITS == 32)
-typedef uint64_t bit_t;   // natural register type
-typedef uint32_t lbit_t;  // natural type for memory I/O
-#elif (BITS == 16)
-typedef uint32_t bit_t;
-typedef uint16_t lbit_t;
-#else
-typedef uint32_t bit_t;
-typedef uint8_t lbit_t;
-#endif
-
-//------------------------------------------------------------------------------
-// Bitreader and code-tree reader
-
-typedef struct VP8BitReader VP8BitReader;
-struct VP8BitReader {
-  const uint8_t* buf_;        // next byte to be read
-  const uint8_t* buf_end_;    // end of read buffer
-  int eof_;                   // true if input is exhausted
-
-  // boolean decoder
-  bit_t range_;            // current range minus 1. In [127, 254] interval.
-  bit_t value_;            // current value
-  int missing_;            // number of missing bits in value_ (8bit)
-};
-
-// Initialize the bit reader and the boolean decoder.
-void VP8InitBitReader(VP8BitReader* const br,
-                      const uint8_t* const start, const uint8_t* const end);
-
-// return the next value made of 'num_bits' bits
-uint32_t VP8GetValue(VP8BitReader* const br, int num_bits);
-static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
-  return VP8GetValue(br, 1);
-}
-
-// return the next value with sign-extension.
-int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits);
-
-// Read a bit with proba 'prob'. Speed-critical function!
-extern const uint8_t kVP8Log2Range[128];
-extern const bit_t kVP8NewRange[128];
-
-void VP8LoadFinalBytes(VP8BitReader* const br);    // special case for the tail
-
-static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
-  assert(br && br->buf_);
-  // Read 'BITS' bits at a time if possible.
-  if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) {
-    // convert memory type to register type (with some zero'ing!)
-    bit_t bits;
-    lbit_t in_bits = *(lbit_t*)br->buf_;
-    br->buf_ += (BITS) >> 3;
-#if !defined(__BIG_ENDIAN__)
-#if (BITS == 32)
-#if defined(__i386__) || defined(__x86_64__)
-    __asm__ volatile("bswap %k0" : "=r"(in_bits) : "0"(in_bits));
-    bits = (bit_t)in_bits;   // 32b -> 64b zero-extension
-#elif defined(_MSC_VER)
-    bits = _byteswap_ulong(in_bits);
-#else
-    bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00)
-         | ((in_bits << 8) & 0xff0000)  | (in_bits << 24);
-#endif  // x86
-#elif (BITS == 16)
-    // gcc will recognize a 'rorw $8, ...' here:
-    bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8);
-#endif
-#else    // LITTLE_ENDIAN
-    bits = (bit_t)in_bits;
-#endif
-    br->value_ |= bits << br->missing_;
-    br->missing_ -= (BITS);
-  } else {
-    VP8LoadFinalBytes(br);    // no need to be inlined
-  }
-}
-
-static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, bit_t split) {
-  const bit_t value_split = split | (MASK);
-  if (br->missing_ > 0) {  // Make sure we have a least BITS bits in 'value_'
-    VP8LoadNewBytes(br);
-  }
-  if (br->value_ > value_split) {
-    br->range_ -= value_split + 1;
-    br->value_ -= value_split + 1;
-    return 1;
-  } else {
-    br->range_ = value_split;
-    return 0;
-  }
-}
-
-static WEBP_INLINE void VP8Shift(VP8BitReader* const br) {
-  // range_ is in [0..127] interval here.
-  const int idx = br->range_ >> (BITS);
-  const int shift = kVP8Log2Range[idx];
-  br->range_ = kVP8NewRange[idx];
-  br->value_ <<= shift;
-  br->missing_ += shift;
-}
-
-static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
-  // It's important to avoid generating a 64bit x 64bit multiply here.
-  // We just need an 8b x 8b after all.
-  const bit_t split =
-      (bit_t)((uint32_t)(br->range_ >> (BITS)) * prob) << ((BITS) - 8);
-  const int bit = VP8BitUpdate(br, split);
-  if (br->range_ <= (((bit_t)0x7e << (BITS)) | (MASK))) {
-    VP8Shift(br);
-  }
-  return bit;
-}
-
-static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) {
-  const bit_t split = (br->range_ >> 1);
-  const int bit = VP8BitUpdate(br, split);
-  VP8Shift(br);
-  return bit ? -v : v;
-}
-
-
-// -----------------------------------------------------------------------------
-// Bitreader
-
-typedef struct {
-  uint64_t       val_;
-  const uint8_t* buf_;
-  size_t         len_;
-  size_t         pos_;
-  int            bit_pos_;
-  int            eos_;
-  int            error_;
-} VP8LBitReader;
-
-void VP8LInitBitReader(VP8LBitReader* const br,
-                       const uint8_t* const start,
-                       size_t length);
-
-//  Sets a new data buffer.
-void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
-                            const uint8_t* const buffer, size_t length);
-
-// Reads the specified number of bits from Read Buffer.
-// Flags an error in case end_of_stream or n_bits is more than allowed limit.
-// Flags eos if this read attempt is going to cross the read buffer.
-uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);
-
-// Reads one bit from Read Buffer. Flags an error in case end_of_stream.
-// Flags eos after reading last bit from the buffer.
-uint32_t VP8LReadOneBit(VP8LBitReader* const br);
-
-// VP8LReadOneBitUnsafe is faster than VP8LReadOneBit, but it can be called only
-// 32 times after the last VP8LFillBitWindow. Any subsequent calls
-// (without VP8LFillBitWindow) will return invalid data.
-static WEBP_INLINE uint32_t VP8LReadOneBitUnsafe(VP8LBitReader* const br) {
-  const uint32_t val = (br->val_ >> br->bit_pos_) & 1;
-  ++br->bit_pos_;
-  return val;
-}
-
-// Advances the Read buffer by 4 bytes to make room for reading next 32 bits.
-void VP8LFillBitWindow(VP8LBitReader* const br);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_UTILS_BIT_READER_H_ */

+ 0 - 284
drivers/webpold/utils/bit_writer.c

@@ -1,284 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Bit writing and boolean coder
-//
-// Author: Skal ([email protected])
-//         Vikas Arora ([email protected])
-
-#include <assert.h>
-#include <string.h>   // for memcpy()
-#include <stdlib.h>
-#include "./bit_writer.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// VP8BitWriter
-
-static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
-  uint8_t* new_buf;
-  size_t new_size;
-  const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size;
-  const size_t needed_size = (size_t)needed_size_64b;
-  if (needed_size_64b != needed_size) {
-    bw->error_ = 1;
-    return 0;
-  }
-  if (needed_size <= bw->max_pos_) return 1;
-  // If the following line wraps over 32bit, the test just after will catch it.
-  new_size = 2 * bw->max_pos_;
-  if (new_size < needed_size) new_size = needed_size;
-  if (new_size < 1024) new_size = 1024;
-  new_buf = (uint8_t*)malloc(new_size);
-  if (new_buf == NULL) {
-    bw->error_ = 1;
-    return 0;
-  }
-  memcpy(new_buf, bw->buf_, bw->pos_);
-  free(bw->buf_);
-  bw->buf_ = new_buf;
-  bw->max_pos_ = new_size;
-  return 1;
-}
-
-static void kFlush(VP8BitWriter* const bw) {
-  const int s = 8 + bw->nb_bits_;
-  const int32_t bits = bw->value_ >> s;
-  assert(bw->nb_bits_ >= 0);
-  bw->value_ -= bits << s;
-  bw->nb_bits_ -= 8;
-  if ((bits & 0xff) != 0xff) {
-    size_t pos = bw->pos_;
-    if (!BitWriterResize(bw, bw->run_ + 1)) {
-      return;
-    }
-    if (bits & 0x100) {  // overflow -> propagate carry over pending 0xff's
-      if (pos > 0) bw->buf_[pos - 1]++;
-    }
-    if (bw->run_ > 0) {
-      const int value = (bits & 0x100) ? 0x00 : 0xff;
-      for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
-    }
-    bw->buf_[pos++] = bits;
-    bw->pos_ = pos;
-  } else {
-    bw->run_++;   // delay writing of bytes 0xff, pending eventual carry.
-  }
-}
-
-//------------------------------------------------------------------------------
-// renormalization
-
-static const uint8_t kNorm[128] = {  // renorm_sizes[i] = 8 - log2(i)
-     7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
-  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  0
-};
-
-// range = ((range + 1) << kVP8Log2Range[range]) - 1
-static const uint8_t kNewRange[128] = {
-  127, 127, 191, 127, 159, 191, 223, 127, 143, 159, 175, 191, 207, 223, 239,
-  127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239,
-  247, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179,
-  183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239,
-  243, 247, 251, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149,
-  151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179,
-  181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209,
-  211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239,
-  241, 243, 245, 247, 249, 251, 253, 127
-};
-
-int VP8PutBit(VP8BitWriter* const bw, int bit, int prob) {
-  const int split = (bw->range_ * prob) >> 8;
-  if (bit) {
-    bw->value_ += split + 1;
-    bw->range_ -= split + 1;
-  } else {
-    bw->range_ = split;
-  }
-  if (bw->range_ < 127) {   // emit 'shift' bits out and renormalize
-    const int shift = kNorm[bw->range_];
-    bw->range_ = kNewRange[bw->range_];
-    bw->value_ <<= shift;
-    bw->nb_bits_ += shift;
-    if (bw->nb_bits_ > 0) kFlush(bw);
-  }
-  return bit;
-}
-
-int VP8PutBitUniform(VP8BitWriter* const bw, int bit) {
-  const int split = bw->range_ >> 1;
-  if (bit) {
-    bw->value_ += split + 1;
-    bw->range_ -= split + 1;
-  } else {
-    bw->range_ = split;
-  }
-  if (bw->range_ < 127) {
-    bw->range_ = kNewRange[bw->range_];
-    bw->value_ <<= 1;
-    bw->nb_bits_ += 1;
-    if (bw->nb_bits_ > 0) kFlush(bw);
-  }
-  return bit;
-}
-
-void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) {
-  int mask;
-  for (mask = 1 << (nb_bits - 1); mask; mask >>= 1)
-    VP8PutBitUniform(bw, value & mask);
-}
-
-void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) {
-  if (!VP8PutBitUniform(bw, value != 0))
-    return;
-  if (value < 0) {
-    VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1);
-  } else {
-    VP8PutValue(bw, value << 1, nb_bits + 1);
-  }
-}
-
-//------------------------------------------------------------------------------
-
-int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) {
-  bw->range_   = 255 - 1;
-  bw->value_   = 0;
-  bw->run_     = 0;
-  bw->nb_bits_ = -8;
-  bw->pos_     = 0;
-  bw->max_pos_ = 0;
-  bw->error_   = 0;
-  bw->buf_     = NULL;
-  return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1;
-}
-
-uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
-  VP8PutValue(bw, 0, 9 - bw->nb_bits_);
-  bw->nb_bits_ = 0;   // pad with zeroes
-  kFlush(bw);
-  return bw->buf_;
-}
-
-int VP8BitWriterAppend(VP8BitWriter* const bw,
-                       const uint8_t* data, size_t size) {
-  assert(data);
-  if (bw->nb_bits_ != -8) return 0;   // kFlush() must have been called
-  if (!BitWriterResize(bw, size)) return 0;
-  memcpy(bw->buf_ + bw->pos_, data, size);
-  bw->pos_ += size;
-  return 1;
-}
-
-void VP8BitWriterWipeOut(VP8BitWriter* const bw) {
-  if (bw) {
-    free(bw->buf_);
-    memset(bw, 0, sizeof(*bw));
-  }
-}
-
-//------------------------------------------------------------------------------
-// VP8LBitWriter
-
-// Returns 1 on success.
-static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
-  uint8_t* allocated_buf;
-  size_t allocated_size;
-  const size_t current_size = VP8LBitWriterNumBytes(bw);
-  const uint64_t size_required_64b = (uint64_t)current_size + extra_size;
-  const size_t size_required = (size_t)size_required_64b;
-  if (size_required != size_required_64b) {
-    bw->error_ = 1;
-    return 0;
-  }
-  if (bw->max_bytes_ > 0 && size_required <= bw->max_bytes_) return 1;
-  allocated_size = (3 * bw->max_bytes_) >> 1;
-  if (allocated_size < size_required) allocated_size = size_required;
-  // make allocated size multiple of 1k
-  allocated_size = (((allocated_size >> 10) + 1) << 10);
-  allocated_buf = (uint8_t*)malloc(allocated_size);
-  if (allocated_buf == NULL) {
-    bw->error_ = 1;
-    return 0;
-  }
-  memcpy(allocated_buf, bw->buf_, current_size);
-  free(bw->buf_);
-  bw->buf_ = allocated_buf;
-  bw->max_bytes_ = allocated_size;
-  memset(allocated_buf + current_size, 0, allocated_size - current_size);
-  return 1;
-}
-
-int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
-  memset(bw, 0, sizeof(*bw));
-  return VP8LBitWriterResize(bw, expected_size);
-}
-
-void VP8LBitWriterDestroy(VP8LBitWriter* const bw) {
-  if (bw != NULL) {
-    free(bw->buf_);
-    memset(bw, 0, sizeof(*bw));
-  }
-}
-
-void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) {
-  if (n_bits < 1) return;
-#if !defined(__BIG_ENDIAN__)
-  // Technically, this branch of the code can write up to 25 bits at a time,
-  // but in prefix encoding, the maximum number of bits written is 18 at a time.
-  {
-    uint8_t* const p = &bw->buf_[bw->bit_pos_ >> 3];
-    uint32_t v = *(const uint32_t*)p;
-    v |= bits << (bw->bit_pos_ & 7);
-    *(uint32_t*)p = v;
-    bw->bit_pos_ += n_bits;
-  }
-#else  // BIG_ENDIAN
-  {
-    uint8_t* p = &bw->buf_[bw->bit_pos_ >> 3];
-    const int bits_reserved_in_first_byte = bw->bit_pos_ & 7;
-    const int bits_left_to_write = n_bits - 8 + bits_reserved_in_first_byte;
-    // implicit & 0xff is assumed for uint8_t arithmetics
-    *p++ |= bits << bits_reserved_in_first_byte;
-    bits >>= 8 - bits_reserved_in_first_byte;
-    if (bits_left_to_write >= 1) {
-      *p++ = bits;
-      bits >>= 8;
-      if (bits_left_to_write >= 9) {
-        *p++ = bits;
-        bits >>= 8;
-      }
-    }
-    assert(n_bits <= 25);
-    *p = bits;
-    bw->bit_pos_ += n_bits;
-  }
-#endif
-  if ((bw->bit_pos_ >> 3) > (bw->max_bytes_ - 8)) {
-    const uint64_t extra_size = 32768ULL + bw->max_bytes_;
-    if (extra_size != (size_t)extra_size ||
-        !VP8LBitWriterResize(bw, (size_t)extra_size)) {
-      bw->bit_pos_ = 0;
-      bw->error_ = 1;
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 123
drivers/webpold/utils/bit_writer.h

@@ -1,123 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Bit writing and boolean coder
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_UTILS_BIT_WRITER_H_
-#define WEBP_UTILS_BIT_WRITER_H_
-
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Bit-writing
-
-typedef struct VP8BitWriter VP8BitWriter;
-struct VP8BitWriter {
-  int32_t  range_;      // range-1
-  int32_t  value_;
-  int      run_;        // number of outstanding bits
-  int      nb_bits_;    // number of pending bits
-  uint8_t* buf_;        // internal buffer. Re-allocated regularly. Not owned.
-  size_t   pos_;
-  size_t   max_pos_;
-  int      error_;      // true in case of error
-};
-
-// Initialize the object. Allocates some initial memory based on expected_size.
-int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size);
-// Finalize the bitstream coding. Returns a pointer to the internal buffer.
-uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw);
-// Release any pending memory and zeroes the object. Not a mandatory call.
-// Only useful in case of error, when the internal buffer hasn't been grabbed!
-void VP8BitWriterWipeOut(VP8BitWriter* const bw);
-
-int VP8PutBit(VP8BitWriter* const bw, int bit, int prob);
-int VP8PutBitUniform(VP8BitWriter* const bw, int bit);
-void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits);
-void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits);
-
-// Appends some bytes to the internal buffer. Data is copied.
-int VP8BitWriterAppend(VP8BitWriter* const bw,
-                       const uint8_t* data, size_t size);
-
-// return approximate write position (in bits)
-static WEBP_INLINE uint64_t VP8BitWriterPos(const VP8BitWriter* const bw) {
-  return (uint64_t)(bw->pos_ + bw->run_) * 8 + 8 + bw->nb_bits_;
-}
-
-// Returns a pointer to the internal buffer.
-static WEBP_INLINE uint8_t* VP8BitWriterBuf(const VP8BitWriter* const bw) {
-  return bw->buf_;
-}
-// Returns the size of the internal buffer.
-static WEBP_INLINE size_t VP8BitWriterSize(const VP8BitWriter* const bw) {
-  return bw->pos_;
-}
-
-//------------------------------------------------------------------------------
-// VP8LBitWriter
-// TODO(vikasa): VP8LBitWriter is copied as-is from lossless code. There's scope
-// of re-using VP8BitWriter. Will evaluate once basic lossless encoder is
-// implemented.
-
-typedef struct {
-  uint8_t* buf_;
-  size_t bit_pos_;
-  size_t max_bytes_;
-
-  // After all bits are written, the caller must observe the state of
-  // error_. A value of 1 indicates that a memory allocation failure
-  // has happened during bit writing. A value of 0 indicates successful
-  // writing of bits.
-  int error_;
-} VP8LBitWriter;
-
-static WEBP_INLINE size_t VP8LBitWriterNumBytes(VP8LBitWriter* const bw) {
-  return (bw->bit_pos_ + 7) >> 3;
-}
-
-static WEBP_INLINE uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) {
-  return bw->buf_;
-}
-
-// Returns 0 in case of memory allocation error.
-int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size);
-
-void VP8LBitWriterDestroy(VP8LBitWriter* const bw);
-
-// This function writes bits into bytes in increasing addresses, and within
-// a byte least-significant-bit first.
-//
-// The function can write up to 16 bits in one go with WriteBits
-// Example: let's assume that 3 bits (Rs below) have been written already:
-//
-// BYTE-0     BYTE+1       BYTE+2
-//
-// 0000 0RRR    0000 0000    0000 0000
-//
-// Now, we could write 5 or less bits in MSB by just sifting by 3
-// and OR'ing to BYTE-0.
-//
-// For n bits, we take the last 5 bytes, OR that with high bits in BYTE-0,
-// and locate the rest in BYTE+1 and BYTE+2.
-//
-// VP8LBitWriter's error_ flag is set in case of  memory allocation error.
-void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_UTILS_BIT_WRITER_H_ */

+ 0 - 44
drivers/webpold/utils/color_cache.c

@@ -1,44 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Color Cache for WebP Lossless
-//
-// Author: Jyrki Alakuijala ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-#include "./color_cache.h"
-#include "../utils/utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// VP8LColorCache.
-
-int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
-  const int hash_size = 1 << hash_bits;
-  assert(cc != NULL);
-  assert(hash_bits > 0);
-  cc->colors_ = (uint32_t*)WebPSafeCalloc((uint64_t)hash_size,
-                                          sizeof(*cc->colors_));
-  if (cc->colors_ == NULL) return 0;
-  cc->hash_shift_ = 32 - hash_bits;
-  return 1;
-}
-
-void VP8LColorCacheClear(VP8LColorCache* const cc) {
-  if (cc != NULL) {
-    free(cc->colors_);
-    cc->colors_ = NULL;
-  }
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif

+ 0 - 68
drivers/webpold/utils/color_cache.h

@@ -1,68 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Color Cache for WebP Lossless
-//
-// Authors: Jyrki Alakuijala ([email protected])
-//          Urvang Joshi ([email protected])
-
-#ifndef WEBP_UTILS_COLOR_CACHE_H_
-#define WEBP_UTILS_COLOR_CACHE_H_
-
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// Main color cache struct.
-typedef struct {
-  uint32_t *colors_;  // color entries
-  int hash_shift_;    // Hash shift: 32 - hash_bits.
-} VP8LColorCache;
-
-static const uint32_t kHashMul = 0x1e35a7bd;
-
-static WEBP_INLINE uint32_t VP8LColorCacheLookup(
-    const VP8LColorCache* const cc, uint32_t key) {
-  assert(key <= (~0U >> cc->hash_shift_));
-  return cc->colors_[key];
-}
-
-static WEBP_INLINE void VP8LColorCacheInsert(const VP8LColorCache* const cc,
-                                             uint32_t argb) {
-  const uint32_t key = (kHashMul * argb) >> cc->hash_shift_;
-  cc->colors_[key] = argb;
-}
-
-static WEBP_INLINE int VP8LColorCacheGetIndex(const VP8LColorCache* const cc,
-                                              uint32_t argb) {
-  return (kHashMul * argb) >> cc->hash_shift_;
-}
-
-static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache* const cc,
-                                              uint32_t argb) {
-  const uint32_t key = (kHashMul * argb) >> cc->hash_shift_;
-  return cc->colors_[key] == argb;
-}
-
-//------------------------------------------------------------------------------
-
-// Initializes the color cache with 'hash_bits' bits for the keys.
-// Returns false in case of memory error.
-int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits);
-
-// Delete the memory associated to color cache.
-void VP8LColorCacheClear(VP8LColorCache* const color_cache);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif  // WEBP_UTILS_COLOR_CACHE_H_

+ 0 - 229
drivers/webpold/utils/filters.c

@@ -1,229 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Spatial prediction using various filters
-//
-// Author: Urvang ([email protected])
-
-#include "./filters.h"
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Helpful macro.
-
-# define SANITY_CHECK(in, out)                              \
-  assert(in != NULL);                                       \
-  assert(out != NULL);                                      \
-  assert(width > 0);                                        \
-  assert(height > 0);                                       \
-  assert(bpp > 0);                                          \
-  assert(stride >= width * bpp);
-
-static WEBP_INLINE void PredictLine(const uint8_t* src, const uint8_t* pred,
-                                    uint8_t* dst, int length, int inverse) {
-  int i;
-  if (inverse) {
-    for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i];
-  } else {
-    for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i];
-  }
-}
-
-//------------------------------------------------------------------------------
-// Horizontal filter.
-
-static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in,
-    int width, int height, int bpp, int stride, int inverse, uint8_t* out) {
-  int h;
-  const uint8_t* preds = (inverse ? out : in);
-  SANITY_CHECK(in, out);
-
-  // Filter line-by-line.
-  for (h = 0; h < height; ++h) {
-    // Leftmost pixel is predicted from above (except for topmost scanline).
-    if (h == 0) {
-      memcpy((void*)out, (const void*)in, bpp);
-    } else {
-      PredictLine(in, preds - stride, out, bpp, inverse);
-    }
-    PredictLine(in + bpp, preds, out + bpp, bpp * (width - 1), inverse);
-    preds += stride;
-    in += stride;
-    out += stride;
-  }
-}
-
-static void HorizontalFilter(const uint8_t* data, int width, int height,
-                             int bpp, int stride, uint8_t* filtered_data) {
-  DoHorizontalFilter(data, width, height, bpp, stride, 0, filtered_data);
-}
-
-static void HorizontalUnfilter(const uint8_t* data, int width, int height,
-                               int bpp, int stride, uint8_t* recon_data) {
-  DoHorizontalFilter(data, width, height, bpp, stride, 1, recon_data);
-}
-
-//------------------------------------------------------------------------------
-// Vertical filter.
-
-static WEBP_INLINE void DoVerticalFilter(const uint8_t* in,
-    int width, int height, int bpp, int stride, int inverse, uint8_t* out) {
-  int h;
-  const uint8_t* preds = (inverse ? out : in);
-  SANITY_CHECK(in, out);
-
-  // Very first top-left pixel is copied.
-  memcpy((void*)out, (const void*)in, bpp);
-  // Rest of top scan-line is left-predicted.
-  PredictLine(in + bpp, preds, out + bpp, bpp * (width - 1), inverse);
-
-  // Filter line-by-line.
-  for (h = 1; h < height; ++h) {
-    in += stride;
-    out += stride;
-    PredictLine(in, preds, out, bpp * width, inverse);
-    preds += stride;
-  }
-}
-
-static void VerticalFilter(const uint8_t* data, int width, int height,
-                           int bpp, int stride, uint8_t* filtered_data) {
-  DoVerticalFilter(data, width, height, bpp, stride, 0, filtered_data);
-}
-
-static void VerticalUnfilter(const uint8_t* data, int width, int height,
-                             int bpp, int stride, uint8_t* recon_data) {
-  DoVerticalFilter(data, width, height, bpp, stride, 1, recon_data);
-}
-
-//------------------------------------------------------------------------------
-// Gradient filter.
-
-static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) {
-  const int g = a + b - c;
-  return (g < 0) ? 0 : (g > 255) ? 255 : g;
-}
-
-static WEBP_INLINE
-void DoGradientFilter(const uint8_t* in, int width, int height,
-                      int bpp, int stride, int inverse, uint8_t* out) {
-  const uint8_t* preds = (inverse ? out : in);
-  int h;
-  SANITY_CHECK(in, out);
-
-  // left prediction for top scan-line
-  memcpy((void*)out, (const void*)in, bpp);
-  PredictLine(in + bpp, preds, out + bpp, bpp * (width - 1), inverse);
-
-  // Filter line-by-line.
-  for (h = 1; h < height; ++h) {
-    int w;
-    preds += stride;
-    in += stride;
-    out += stride;
-    // leftmost pixel: predict from above.
-    PredictLine(in, preds - stride, out, bpp, inverse);
-    for (w = bpp; w < width * bpp; ++w) {
-      const int pred = GradientPredictor(preds[w - bpp],
-                                         preds[w - stride],
-                                         preds[w - stride - bpp]);
-      out[w] = in[w] + (inverse ? pred : -pred);
-    }
-  }
-}
-
-static void GradientFilter(const uint8_t* data, int width, int height,
-                           int bpp, int stride, uint8_t* filtered_data) {
-  DoGradientFilter(data, width, height, bpp, stride, 0, filtered_data);
-}
-
-static void GradientUnfilter(const uint8_t* data, int width, int height,
-                             int bpp, int stride, uint8_t* recon_data) {
-  DoGradientFilter(data, width, height, bpp, stride, 1, recon_data);
-}
-
-#undef SANITY_CHECK
-
-// -----------------------------------------------------------------------------
-// Quick estimate of a potentially interesting filter mode to try, in addition
-// to the default NONE.
-
-#define SMAX 16
-#define SDIFF(a, b) (abs((a) - (b)) >> 4)   // Scoring diff, in [0..SMAX)
-
-WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data,
-                                    int width, int height, int stride) {
-  int i, j;
-  int bins[WEBP_FILTER_LAST][SMAX];
-  memset(bins, 0, sizeof(bins));
-  // We only sample every other pixels. That's enough.
-  for (j = 2; j < height - 1; j += 2) {
-    const uint8_t* const p = data + j * stride;
-    int mean = p[0];
-    for (i = 2; i < width - 1; i += 2) {
-      const int diff0 = SDIFF(p[i], mean);
-      const int diff1 = SDIFF(p[i], p[i - 1]);
-      const int diff2 = SDIFF(p[i], p[i - width]);
-      const int grad_pred =
-          GradientPredictor(p[i - 1], p[i - width], p[i - width - 1]);
-      const int diff3 = SDIFF(p[i], grad_pred);
-      bins[WEBP_FILTER_NONE][diff0] = 1;
-      bins[WEBP_FILTER_HORIZONTAL][diff1] = 1;
-      bins[WEBP_FILTER_VERTICAL][diff2] = 1;
-      bins[WEBP_FILTER_GRADIENT][diff3] = 1;
-      mean = (3 * mean + p[i] + 2) >> 2;
-    }
-  }
-  {
-    WEBP_FILTER_TYPE filter, best_filter = WEBP_FILTER_NONE;
-    int best_score = 0x7fffffff;
-    for (filter = WEBP_FILTER_NONE; filter < WEBP_FILTER_LAST; ++filter) {
-      int score = 0;
-      for (i = 0; i < SMAX; ++i) {
-        if (bins[filter][i] > 0) {
-          score += i;
-        }
-      }
-      if (score < best_score) {
-        best_score = score;
-        best_filter = filter;
-      }
-    }
-    return best_filter;
-  }
-}
-
-#undef SMAX
-#undef SDIFF
-
-//------------------------------------------------------------------------------
-
-const WebPFilterFunc WebPFilters[WEBP_FILTER_LAST] = {
-  NULL,              // WEBP_FILTER_NONE
-  HorizontalFilter,  // WEBP_FILTER_HORIZONTAL
-  VerticalFilter,    // WEBP_FILTER_VERTICAL
-  GradientFilter     // WEBP_FILTER_GRADIENT
-};
-
-const WebPFilterFunc WebPUnfilters[WEBP_FILTER_LAST] = {
-  NULL,                // WEBP_FILTER_NONE
-  HorizontalUnfilter,  // WEBP_FILTER_HORIZONTAL
-  VerticalUnfilter,    // WEBP_FILTER_VERTICAL
-  GradientUnfilter     // WEBP_FILTER_GRADIENT
-};
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 54
drivers/webpold/utils/filters.h

@@ -1,54 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Spatial prediction using various filters
-//
-// Author: Urvang ([email protected])
-
-#ifndef WEBP_UTILS_FILTERS_H_
-#define WEBP_UTILS_FILTERS_H_
-
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// Filters.
-typedef enum {
-  WEBP_FILTER_NONE = 0,
-  WEBP_FILTER_HORIZONTAL,
-  WEBP_FILTER_VERTICAL,
-  WEBP_FILTER_GRADIENT,
-  WEBP_FILTER_LAST = WEBP_FILTER_GRADIENT + 1,  // end marker
-  WEBP_FILTER_BEST,
-  WEBP_FILTER_FAST
-} WEBP_FILTER_TYPE;
-
-typedef void (*WebPFilterFunc)(const uint8_t* in, int width, int height,
-                               int bpp, int stride, uint8_t* out);
-
-// Filter the given data using the given predictor.
-// 'in' corresponds to a 2-dimensional pixel array of size (stride * height)
-// in raster order.
-// 'bpp' is number of bytes per pixel, and
-// 'stride' is number of bytes per scan line (with possible padding).
-// 'out' should be pre-allocated.
-extern const WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
-
-// Reconstruct the original data from the given filtered data.
-extern const WebPFilterFunc WebPUnfilters[WEBP_FILTER_LAST];
-
-// Fast estimate of a potentially good filter.
-extern WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data,
-                                           int width, int height, int stride);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_UTILS_FILTERS_H_ */

+ 0 - 238
drivers/webpold/utils/huffman.c

@@ -1,238 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Utilities for building and looking up Huffman trees.
-//
-// Author: Urvang Joshi ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-#include "./huffman.h"
-#include "../utils/utils.h"
-#include "../format_constants.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define NON_EXISTENT_SYMBOL (-1)
-
-static void TreeNodeInit(HuffmanTreeNode* const node) {
-  node->children_ = -1;   // means: 'unassigned so far'
-}
-
-static int NodeIsEmpty(const HuffmanTreeNode* const node) {
-  return (node->children_ < 0);
-}
-
-static int IsFull(const HuffmanTree* const tree) {
-  return (tree->num_nodes_ == tree->max_nodes_);
-}
-
-static void AssignChildren(HuffmanTree* const tree,
-                           HuffmanTreeNode* const node) {
-  HuffmanTreeNode* const children = tree->root_ + tree->num_nodes_;
-  node->children_ = (int)(children - node);
-  assert(children - node == (int)(children - node));
-  tree->num_nodes_ += 2;
-  TreeNodeInit(children + 0);
-  TreeNodeInit(children + 1);
-}
-
-static int TreeInit(HuffmanTree* const tree, int num_leaves) {
-  assert(tree != NULL);
-  if (num_leaves == 0) return 0;
-  // We allocate maximum possible nodes in the tree at once.
-  // Note that a Huffman tree is a full binary tree; and in a full binary tree
-  // with L leaves, the total number of nodes N = 2 * L - 1.
-  tree->max_nodes_ = 2 * num_leaves - 1;
-  tree->root_ = (HuffmanTreeNode*)WebPSafeMalloc((uint64_t)tree->max_nodes_,
-                                                 sizeof(*tree->root_));
-  if (tree->root_ == NULL) return 0;
-  TreeNodeInit(tree->root_);  // Initialize root.
-  tree->num_nodes_ = 1;
-  return 1;
-}
-
-void HuffmanTreeRelease(HuffmanTree* const tree) {
-  if (tree != NULL) {
-    free(tree->root_);
-    tree->root_ = NULL;
-    tree->max_nodes_ = 0;
-    tree->num_nodes_ = 0;
-  }
-}
-
-int HuffmanCodeLengthsToCodes(const int* const code_lengths,
-                              int code_lengths_size, int* const huff_codes) {
-  int symbol;
-  int code_len;
-  int code_length_hist[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
-  int curr_code;
-  int next_codes[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
-  int max_code_length = 0;
-
-  assert(code_lengths != NULL);
-  assert(code_lengths_size > 0);
-  assert(huff_codes != NULL);
-
-  // Calculate max code length.
-  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
-    if (code_lengths[symbol] > max_code_length) {
-      max_code_length = code_lengths[symbol];
-    }
-  }
-  if (max_code_length > MAX_ALLOWED_CODE_LENGTH) return 0;
-
-  // Calculate code length histogram.
-  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
-    ++code_length_hist[code_lengths[symbol]];
-  }
-  code_length_hist[0] = 0;
-
-  // Calculate the initial values of 'next_codes' for each code length.
-  // next_codes[code_len] denotes the code to be assigned to the next symbol
-  // of code length 'code_len'.
-  curr_code = 0;
-  next_codes[0] = -1;  // Unused, as code length = 0 implies code doesn't exist.
-  for (code_len = 1; code_len <= max_code_length; ++code_len) {
-    curr_code = (curr_code + code_length_hist[code_len - 1]) << 1;
-    next_codes[code_len] = curr_code;
-  }
-
-  // Get symbols.
-  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
-    if (code_lengths[symbol] > 0) {
-      huff_codes[symbol] = next_codes[code_lengths[symbol]]++;
-    } else {
-      huff_codes[symbol] = NON_EXISTENT_SYMBOL;
-    }
-  }
-  return 1;
-}
-
-static int TreeAddSymbol(HuffmanTree* const tree,
-                         int symbol, int code, int code_length) {
-  HuffmanTreeNode* node = tree->root_;
-  const HuffmanTreeNode* const max_node = tree->root_ + tree->max_nodes_;
-  while (code_length-- > 0) {
-    if (node >= max_node) {
-      return 0;
-    }
-    if (NodeIsEmpty(node)) {
-      if (IsFull(tree)) return 0;    // error: too many symbols.
-      AssignChildren(tree, node);
-    } else if (HuffmanTreeNodeIsLeaf(node)) {
-      return 0;  // leaf is already occupied.
-    }
-    node += node->children_ + ((code >> code_length) & 1);
-  }
-  if (NodeIsEmpty(node)) {
-    node->children_ = 0;      // turn newly created node into a leaf.
-  } else if (!HuffmanTreeNodeIsLeaf(node)) {
-    return 0;   // trying to assign a symbol to already used code.
-  }
-  node->symbol_ = symbol;  // Add symbol in this node.
-  return 1;
-}
-
-int HuffmanTreeBuildImplicit(HuffmanTree* const tree,
-                             const int* const code_lengths,
-                             int code_lengths_size) {
-  int symbol;
-  int num_symbols = 0;
-  int root_symbol = 0;
-
-  assert(tree != NULL);
-  assert(code_lengths != NULL);
-
-  // Find out number of symbols and the root symbol.
-  for (symbol = 0; symbol < code_lengths_size; ++symbol) {
-    if (code_lengths[symbol] > 0) {
-      // Note: code length = 0 indicates non-existent symbol.
-      ++num_symbols;
-      root_symbol = symbol;
-    }
-  }
-
-  // Initialize the tree. Will fail for num_symbols = 0
-  if (!TreeInit(tree, num_symbols)) return 0;
-
-  // Build tree.
-  if (num_symbols == 1) {  // Trivial case.
-    const int max_symbol = code_lengths_size;
-    if (root_symbol < 0 || root_symbol >= max_symbol) {
-      HuffmanTreeRelease(tree);
-      return 0;
-    }
-    return TreeAddSymbol(tree, root_symbol, 0, 0);
-  } else {  // Normal case.
-    int ok = 0;
-
-    // Get Huffman codes from the code lengths.
-    int* const codes =
-        (int*)WebPSafeMalloc((uint64_t)code_lengths_size, sizeof(*codes));
-    if (codes == NULL) goto End;
-
-    if (!HuffmanCodeLengthsToCodes(code_lengths, code_lengths_size, codes)) {
-      goto End;
-    }
-
-    // Add symbols one-by-one.
-    for (symbol = 0; symbol < code_lengths_size; ++symbol) {
-      if (code_lengths[symbol] > 0) {
-        if (!TreeAddSymbol(tree, symbol, codes[symbol], code_lengths[symbol])) {
-          goto End;
-        }
-      }
-    }
-    ok = 1;
- End:
-    free(codes);
-    ok = ok && IsFull(tree);
-    if (!ok) HuffmanTreeRelease(tree);
-    return ok;
-  }
-}
-
-int HuffmanTreeBuildExplicit(HuffmanTree* const tree,
-                             const int* const code_lengths,
-                             const int* const codes,
-                             const int* const symbols, int max_symbol,
-                             int num_symbols) {
-  int ok = 0;
-  int i;
-
-  assert(tree != NULL);
-  assert(code_lengths != NULL);
-  assert(codes != NULL);
-  assert(symbols != NULL);
-
-  // Initialize the tree. Will fail if num_symbols = 0.
-  if (!TreeInit(tree, num_symbols)) return 0;
-
-  // Add symbols one-by-one.
-  for (i = 0; i < num_symbols; ++i) {
-    if (codes[i] != NON_EXISTENT_SYMBOL) {
-      if (symbols[i] < 0 || symbols[i] >= max_symbol) {
-        goto End;
-      }
-      if (!TreeAddSymbol(tree, symbols[i], codes[i], code_lengths[i])) {
-        goto End;
-      }
-    }
-  }
-  ok = 1;
- End:
-  ok = ok && IsFull(tree);
-  if (!ok) HuffmanTreeRelease(tree);
-  return ok;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 78
drivers/webpold/utils/huffman.h

@@ -1,78 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Utilities for building and looking up Huffman trees.
-//
-// Author: Urvang Joshi ([email protected])
-
-#ifndef WEBP_UTILS_HUFFMAN_H_
-#define WEBP_UTILS_HUFFMAN_H_
-
-#include <assert.h>
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// A node of a Huffman tree.
-typedef struct {
-  int symbol_;
-  int children_;  // delta offset to both children (contiguous) or 0 if leaf.
-} HuffmanTreeNode;
-
-// Huffman Tree.
-typedef struct HuffmanTree HuffmanTree;
-struct HuffmanTree {
-  HuffmanTreeNode* root_;   // all the nodes, starting at root.
-  int max_nodes_;           // max number of nodes
-  int num_nodes_;           // number of currently occupied nodes
-};
-
-// Returns true if the given node is a leaf of the Huffman tree.
-static WEBP_INLINE int HuffmanTreeNodeIsLeaf(
-    const HuffmanTreeNode* const node) {
-  return (node->children_ == 0);
-}
-
-// Go down one level. Most critical function. 'right_child' must be 0 or 1.
-static WEBP_INLINE const HuffmanTreeNode* HuffmanTreeNextNode(
-    const HuffmanTreeNode* node, int right_child) {
-  return node + node->children_ + right_child;
-}
-
-// Releases the nodes of the Huffman tree.
-// Note: It does NOT free 'tree' itself.
-void HuffmanTreeRelease(HuffmanTree* const tree);
-
-// Builds Huffman tree assuming code lengths are implicitly in symbol order.
-// Returns false in case of error (invalid tree or memory error).
-int HuffmanTreeBuildImplicit(HuffmanTree* const tree,
-                             const int* const code_lengths,
-                             int code_lengths_size);
-
-// Build a Huffman tree with explicitly given lists of code lengths, codes
-// and symbols. Verifies that all symbols added are smaller than max_symbol.
-// Returns false in case of an invalid symbol, invalid tree or memory error.
-int HuffmanTreeBuildExplicit(HuffmanTree* const tree,
-                             const int* const code_lengths,
-                             const int* const codes,
-                             const int* const symbols, int max_symbol,
-                             int num_symbols);
-
-// Utility: converts Huffman code lengths to corresponding Huffman codes.
-// 'huff_codes' should be pre-allocated.
-// Returns false in case of error (memory allocation, invalid codes).
-int HuffmanCodeLengthsToCodes(const int* const code_lengths,
-                              int code_lengths_size, int* const huff_codes);
-
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  // WEBP_UTILS_HUFFMAN_H_

+ 0 - 439
drivers/webpold/utils/huffman_encode.c

@@ -1,439 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Author: Jyrki Alakuijala ([email protected])
-//
-// Entropy encoding (Huffman) for webp lossless.
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "./huffman_encode.h"
-#include "../utils/utils.h"
-#include "../format_constants.h"
-
-// -----------------------------------------------------------------------------
-// Util function to optimize the symbol map for RLE coding
-
-// Heuristics for selecting the stride ranges to collapse.
-static int ValuesShouldBeCollapsedToStrideAverage(int a, int b) {
-  return abs(a - b) < 4;
-}
-
-// Change the population counts in a way that the consequent
-// Hufmann tree compression, especially its RLE-part, give smaller output.
-static int OptimizeHuffmanForRle(int length, int* const counts) {
-  uint8_t* good_for_rle;
-  // 1) Let's make the Huffman code more compatible with rle encoding.
-  int i;
-  for (; length >= 0; --length) {
-    if (length == 0) {
-      return 1;  // All zeros.
-    }
-    if (counts[length - 1] != 0) {
-      // Now counts[0..length - 1] does not have trailing zeros.
-      break;
-    }
-  }
-  // 2) Let's mark all population counts that already can be encoded
-  // with an rle code.
-  good_for_rle = (uint8_t*)calloc(length, 1);
-  if (good_for_rle == NULL) {
-    return 0;
-  }
-  {
-    // Let's not spoil any of the existing good rle codes.
-    // Mark any seq of 0's that is longer as 5 as a good_for_rle.
-    // Mark any seq of non-0's that is longer as 7 as a good_for_rle.
-    int symbol = counts[0];
-    int stride = 0;
-    for (i = 0; i < length + 1; ++i) {
-      if (i == length || counts[i] != symbol) {
-        if ((symbol == 0 && stride >= 5) ||
-            (symbol != 0 && stride >= 7)) {
-          int k;
-          for (k = 0; k < stride; ++k) {
-            good_for_rle[i - k - 1] = 1;
-          }
-        }
-        stride = 1;
-        if (i != length) {
-          symbol = counts[i];
-        }
-      } else {
-        ++stride;
-      }
-    }
-  }
-  // 3) Let's replace those population counts that lead to more rle codes.
-  {
-    int stride = 0;
-    int limit = counts[0];
-    int sum = 0;
-    for (i = 0; i < length + 1; ++i) {
-      if (i == length || good_for_rle[i] ||
-          (i != 0 && good_for_rle[i - 1]) ||
-          !ValuesShouldBeCollapsedToStrideAverage(counts[i], limit)) {
-        if (stride >= 4 || (stride >= 3 && sum == 0)) {
-          int k;
-          // The stride must end, collapse what we have, if we have enough (4).
-          int count = (sum + stride / 2) / stride;
-          if (count < 1) {
-            count = 1;
-          }
-          if (sum == 0) {
-            // Don't make an all zeros stride to be upgraded to ones.
-            count = 0;
-          }
-          for (k = 0; k < stride; ++k) {
-            // We don't want to change value at counts[i],
-            // that is already belonging to the next stride. Thus - 1.
-            counts[i - k - 1] = count;
-          }
-        }
-        stride = 0;
-        sum = 0;
-        if (i < length - 3) {
-          // All interesting strides have a count of at least 4,
-          // at least when non-zeros.
-          limit = (counts[i] + counts[i + 1] +
-                   counts[i + 2] + counts[i + 3] + 2) / 4;
-        } else if (i < length) {
-          limit = counts[i];
-        } else {
-          limit = 0;
-        }
-      }
-      ++stride;
-      if (i != length) {
-        sum += counts[i];
-        if (stride >= 4) {
-          limit = (sum + stride / 2) / stride;
-        }
-      }
-    }
-  }
-  free(good_for_rle);
-  return 1;
-}
-
-typedef struct {
-  int total_count_;
-  int value_;
-  int pool_index_left_;
-  int pool_index_right_;
-} HuffmanTree;
-
-// A comparer function for two Huffman trees: sorts first by 'total count'
-// (more comes first), and then by 'value' (more comes first).
-static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) {
-  const HuffmanTree* const t1 = (const HuffmanTree*)ptr1;
-  const HuffmanTree* const t2 = (const HuffmanTree*)ptr2;
-  if (t1->total_count_ > t2->total_count_) {
-    return -1;
-  } else if (t1->total_count_ < t2->total_count_) {
-    return 1;
-  } else {
-    if (t1->value_ < t2->value_) {
-      return -1;
-    }
-    if (t1->value_ > t2->value_) {
-      return 1;
-    }
-    return 0;
-  }
-}
-
-static void SetBitDepths(const HuffmanTree* const tree,
-                         const HuffmanTree* const pool,
-                         uint8_t* const bit_depths, int level) {
-  if (tree->pool_index_left_ >= 0) {
-    SetBitDepths(&pool[tree->pool_index_left_], pool, bit_depths, level + 1);
-    SetBitDepths(&pool[tree->pool_index_right_], pool, bit_depths, level + 1);
-  } else {
-    bit_depths[tree->value_] = level;
-  }
-}
-
-// Create an optimal Huffman tree.
-//
-// (data,length): population counts.
-// tree_limit: maximum bit depth (inclusive) of the codes.
-// bit_depths[]: how many bits are used for the symbol.
-//
-// Returns 0 when an error has occurred.
-//
-// The catch here is that the tree cannot be arbitrarily deep
-//
-// count_limit is the value that is to be faked as the minimum value
-// and this minimum value is raised until the tree matches the
-// maximum length requirement.
-//
-// This algorithm is not of excellent performance for very long data blocks,
-// especially when population counts are longer than 2**tree_limit, but
-// we are not planning to use this with extremely long blocks.
-//
-// See http://en.wikipedia.org/wiki/Huffman_coding
-static int GenerateOptimalTree(const int* const histogram, int histogram_size,
-                               int tree_depth_limit,
-                               uint8_t* const bit_depths) {
-  int count_min;
-  HuffmanTree* tree_pool;
-  HuffmanTree* tree;
-  int tree_size_orig = 0;
-  int i;
-
-  for (i = 0; i < histogram_size; ++i) {
-    if (histogram[i] != 0) {
-      ++tree_size_orig;
-    }
-  }
-
-  // 3 * tree_size is enough to cover all the nodes representing a
-  // population and all the inserted nodes combining two existing nodes.
-  // The tree pool needs 2 * (tree_size_orig - 1) entities, and the
-  // tree needs exactly tree_size_orig entities.
-  tree = (HuffmanTree*)WebPSafeMalloc(3ULL * tree_size_orig, sizeof(*tree));
-  if (tree == NULL) return 0;
-  tree_pool = tree + tree_size_orig;
-
-  // For block sizes with less than 64k symbols we never need to do a
-  // second iteration of this loop.
-  // If we actually start running inside this loop a lot, we would perhaps
-  // be better off with the Katajainen algorithm.
-  assert(tree_size_orig <= (1 << (tree_depth_limit - 1)));
-  for (count_min = 1; ; count_min *= 2) {
-    int tree_size = tree_size_orig;
-    // We need to pack the Huffman tree in tree_depth_limit bits.
-    // So, we try by faking histogram entries to be at least 'count_min'.
-    int idx = 0;
-    int j;
-    for (j = 0; j < histogram_size; ++j) {
-      if (histogram[j] != 0) {
-        const int count =
-            (histogram[j] < count_min) ? count_min : histogram[j];
-        tree[idx].total_count_ = count;
-        tree[idx].value_ = j;
-        tree[idx].pool_index_left_ = -1;
-        tree[idx].pool_index_right_ = -1;
-        ++idx;
-      }
-    }
-
-    // Build the Huffman tree.
-    qsort(tree, tree_size, sizeof(*tree), CompareHuffmanTrees);
-
-    if (tree_size > 1) {  // Normal case.
-      int tree_pool_size = 0;
-      while (tree_size > 1) {  // Finish when we have only one root.
-        int count;
-        tree_pool[tree_pool_size++] = tree[tree_size - 1];
-        tree_pool[tree_pool_size++] = tree[tree_size - 2];
-        count = tree_pool[tree_pool_size - 1].total_count_ +
-            tree_pool[tree_pool_size - 2].total_count_;
-        tree_size -= 2;
-        {
-          // Search for the insertion point.
-          int k;
-          for (k = 0; k < tree_size; ++k) {
-            if (tree[k].total_count_ <= count) {
-              break;
-            }
-          }
-          memmove(tree + (k + 1), tree + k, (tree_size - k) * sizeof(*tree));
-          tree[k].total_count_ = count;
-          tree[k].value_ = -1;
-
-          tree[k].pool_index_left_ = tree_pool_size - 1;
-          tree[k].pool_index_right_ = tree_pool_size - 2;
-          tree_size = tree_size + 1;
-        }
-      }
-      SetBitDepths(&tree[0], tree_pool, bit_depths, 0);
-    } else if (tree_size == 1) {  // Trivial case: only one element.
-      bit_depths[tree[0].value_] = 1;
-    }
-
-    {
-      // Test if this Huffman tree satisfies our 'tree_depth_limit' criteria.
-      int max_depth = bit_depths[0];
-      for (j = 1; j < histogram_size; ++j) {
-        if (max_depth < bit_depths[j]) {
-          max_depth = bit_depths[j];
-        }
-      }
-      if (max_depth <= tree_depth_limit) {
-        break;
-      }
-    }
-  }
-  free(tree);
-  return 1;
-}
-
-// -----------------------------------------------------------------------------
-// Coding of the Huffman tree values
-
-static HuffmanTreeToken* CodeRepeatedValues(int repetitions,
-                                            HuffmanTreeToken* tokens,
-                                            int value, int prev_value) {
-  assert(value <= MAX_ALLOWED_CODE_LENGTH);
-  if (value != prev_value) {
-    tokens->code = value;
-    tokens->extra_bits = 0;
-    ++tokens;
-    --repetitions;
-  }
-  while (repetitions >= 1) {
-    if (repetitions < 3) {
-      int i;
-      for (i = 0; i < repetitions; ++i) {
-        tokens->code = value;
-        tokens->extra_bits = 0;
-        ++tokens;
-      }
-      break;
-    } else if (repetitions < 7) {
-      tokens->code = 16;
-      tokens->extra_bits = repetitions - 3;
-      ++tokens;
-      break;
-    } else {
-      tokens->code = 16;
-      tokens->extra_bits = 3;
-      ++tokens;
-      repetitions -= 6;
-    }
-  }
-  return tokens;
-}
-
-static HuffmanTreeToken* CodeRepeatedZeros(int repetitions,
-                                           HuffmanTreeToken* tokens) {
-  while (repetitions >= 1) {
-    if (repetitions < 3) {
-      int i;
-      for (i = 0; i < repetitions; ++i) {
-        tokens->code = 0;   // 0-value
-        tokens->extra_bits = 0;
-        ++tokens;
-      }
-      break;
-    } else if (repetitions < 11) {
-      tokens->code = 17;
-      tokens->extra_bits = repetitions - 3;
-      ++tokens;
-      break;
-    } else if (repetitions < 139) {
-      tokens->code = 18;
-      tokens->extra_bits = repetitions - 11;
-      ++tokens;
-      break;
-    } else {
-      tokens->code = 18;
-      tokens->extra_bits = 0x7f;  // 138 repeated 0s
-      ++tokens;
-      repetitions -= 138;
-    }
-  }
-  return tokens;
-}
-
-int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
-                                    HuffmanTreeToken* tokens, int max_tokens) {
-  HuffmanTreeToken* const starting_token = tokens;
-  HuffmanTreeToken* const ending_token = tokens + max_tokens;
-  const int depth_size = tree->num_symbols;
-  int prev_value = 8;  // 8 is the initial value for rle.
-  int i = 0;
-  assert(tokens != NULL);
-  while (i < depth_size) {
-    const int value = tree->code_lengths[i];
-    int k = i + 1;
-    int runs;
-    while (k < depth_size && tree->code_lengths[k] == value) ++k;
-    runs = k - i;
-    if (value == 0) {
-      tokens = CodeRepeatedZeros(runs, tokens);
-    } else {
-      tokens = CodeRepeatedValues(runs, tokens, value, prev_value);
-      prev_value = value;
-    }
-    i += runs;
-    assert(tokens <= ending_token);
-  }
-  (void)ending_token;    // suppress 'unused variable' warning
-  return (int)(tokens - starting_token);
-}
-
-// -----------------------------------------------------------------------------
-
-// Pre-reversed 4-bit values.
-static const uint8_t kReversedBits[16] = {
-  0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
-  0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
-};
-
-static uint32_t ReverseBits(int num_bits, uint32_t bits) {
-  uint32_t retval = 0;
-  int i = 0;
-  while (i < num_bits) {
-    i += 4;
-    retval |= kReversedBits[bits & 0xf] << (MAX_ALLOWED_CODE_LENGTH + 1 - i);
-    bits >>= 4;
-  }
-  retval >>= (MAX_ALLOWED_CODE_LENGTH + 1 - num_bits);
-  return retval;
-}
-
-// Get the actual bit values for a tree of bit depths.
-static void ConvertBitDepthsToSymbols(HuffmanTreeCode* const tree) {
-  // 0 bit-depth means that the symbol does not exist.
-  int i;
-  int len;
-  uint32_t next_code[MAX_ALLOWED_CODE_LENGTH + 1];
-  int depth_count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 };
-
-  assert(tree != NULL);
-  len = tree->num_symbols;
-  for (i = 0; i < len; ++i) {
-    const int code_length = tree->code_lengths[i];
-    assert(code_length <= MAX_ALLOWED_CODE_LENGTH);
-    ++depth_count[code_length];
-  }
-  depth_count[0] = 0;  // ignore unused symbol
-  next_code[0] = 0;
-  {
-    uint32_t code = 0;
-    for (i = 1; i <= MAX_ALLOWED_CODE_LENGTH; ++i) {
-      code = (code + depth_count[i - 1]) << 1;
-      next_code[i] = code;
-    }
-  }
-  for (i = 0; i < len; ++i) {
-    const int code_length = tree->code_lengths[i];
-    tree->codes[i] = ReverseBits(code_length, next_code[code_length]++);
-  }
-}
-
-// -----------------------------------------------------------------------------
-// Main entry point
-
-int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit,
-                          HuffmanTreeCode* const tree) {
-  const int num_symbols = tree->num_symbols;
-  if (!OptimizeHuffmanForRle(num_symbols, histogram)) {
-    return 0;
-  }
-  if (!GenerateOptimalTree(histogram, num_symbols,
-                           tree_depth_limit, tree->code_lengths)) {
-    return 0;
-  }
-  // Create the actual bit codes for the bit lengths.
-  ConvertBitDepthsToSymbols(tree);
-  return 1;
-}

+ 0 - 47
drivers/webpold/utils/huffman_encode.h

@@ -1,47 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Author: Jyrki Alakuijala ([email protected])
-//
-// Entropy encoding (Huffman) for webp lossless
-
-#ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_
-#define WEBP_UTILS_HUFFMAN_ENCODE_H_
-
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// Struct for holding the tree header in coded form.
-typedef struct {
-  uint8_t code;         // value (0..15) or escape code (16,17,18)
-  uint8_t extra_bits;   // extra bits for escape codes
-} HuffmanTreeToken;
-
-// Struct to represent the tree codes (depth and bits array).
-typedef struct {
-  int       num_symbols;   // Number of symbols.
-  uint8_t*  code_lengths;  // Code lengths of the symbols.
-  uint16_t* codes;         // Symbol Codes.
-} HuffmanTreeCode;
-
-// Turn the Huffman tree into a token sequence.
-// Returns the number of tokens used.
-int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
-                                    HuffmanTreeToken* tokens, int max_tokens);
-
-// Create an optimized tree, and tokenize it.
-int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit,
-                          HuffmanTreeCode* const tree);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif  // WEBP_UTILS_HUFFMAN_ENCODE_H_

+ 0 - 154
drivers/webpold/utils/quant_levels.c

@@ -1,154 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Quantize levels for specified number of quantization-levels ([2, 256]).
-// Min and max values are preserved (usual 0 and 255 for alpha plane).
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-
-#include "./quant_levels.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define NUM_SYMBOLS     256
-
-#define MAX_ITER  6             // Maximum number of convergence steps.
-#define ERROR_THRESHOLD 1e-4    // MSE stopping criterion.
-
-// -----------------------------------------------------------------------------
-// Quantize levels.
-
-int QuantizeLevels(uint8_t* const data, int width, int height,
-                   int num_levels, uint64_t* const sse) {
-  int freq[NUM_SYMBOLS] = { 0 };
-  int q_level[NUM_SYMBOLS] = { 0 };
-  double inv_q_level[NUM_SYMBOLS] = { 0 };
-  int min_s = 255, max_s = 0;
-  const size_t data_size = height * width;
-  int i, num_levels_in, iter;
-  double last_err = 1.e38, err = 0.;
-  const double err_threshold = ERROR_THRESHOLD * data_size;
-
-  if (data == NULL) {
-    return 0;
-  }
-
-  if (width <= 0 || height <= 0) {
-    return 0;
-  }
-
-  if (num_levels < 2 || num_levels > 256) {
-    return 0;
-  }
-
-  {
-    size_t n;
-    num_levels_in = 0;
-    for (n = 0; n < data_size; ++n) {
-      num_levels_in += (freq[data[n]] == 0);
-      if (min_s > data[n]) min_s = data[n];
-      if (max_s < data[n]) max_s = data[n];
-      ++freq[data[n]];
-    }
-  }
-
-  if (num_levels_in <= num_levels) goto End;  // nothing to do!
-
-  // Start with uniformly spread centroids.
-  for (i = 0; i < num_levels; ++i) {
-    inv_q_level[i] = min_s + (double)(max_s - min_s) * i / (num_levels - 1);
-  }
-
-  // Fixed values. Won't be changed.
-  q_level[min_s] = 0;
-  q_level[max_s] = num_levels - 1;
-  assert(inv_q_level[0] == min_s);
-  assert(inv_q_level[num_levels - 1] == max_s);
-
-  // k-Means iterations.
-  for (iter = 0; iter < MAX_ITER; ++iter) {
-    double q_sum[NUM_SYMBOLS] = { 0 };
-    double q_count[NUM_SYMBOLS] = { 0 };
-    int s, slot = 0;
-
-    // Assign classes to representatives.
-    for (s = min_s; s <= max_s; ++s) {
-      // Keep track of the nearest neighbour 'slot'
-      while (slot < num_levels - 1 &&
-             2 * s > inv_q_level[slot] + inv_q_level[slot + 1]) {
-        ++slot;
-      }
-      if (freq[s] > 0) {
-        q_sum[slot] += s * freq[s];
-        q_count[slot] += freq[s];
-      }
-      q_level[s] = slot;
-    }
-
-    // Assign new representatives to classes.
-    if (num_levels > 2) {
-      for (slot = 1; slot < num_levels - 1; ++slot) {
-        const double count = q_count[slot];
-        if (count > 0.) {
-          inv_q_level[slot] = q_sum[slot] / count;
-        }
-      }
-    }
-
-    // Compute convergence error.
-    err = 0.;
-    for (s = min_s; s <= max_s; ++s) {
-      const double error = s - inv_q_level[q_level[s]];
-      err += freq[s] * error * error;
-    }
-
-    // Check for convergence: we stop as soon as the error is no
-    // longer improving.
-    if (last_err - err < err_threshold) break;
-    last_err = err;
-  }
-
-  // Remap the alpha plane to quantized values.
-  {
-    // double->int rounding operation can be costly, so we do it
-    // once for all before remapping. We also perform the data[] -> slot
-    // mapping, while at it (avoid one indirection in the final loop).
-    uint8_t map[NUM_SYMBOLS];
-    int s;
-    size_t n;
-    for (s = min_s; s <= max_s; ++s) {
-      const int slot = q_level[s];
-      map[s] = (uint8_t)(inv_q_level[slot] + .5);
-    }
-    // Final pass.
-    for (n = 0; n < data_size; ++n) {
-      data[n] = map[data[n]];
-    }
-  }
- End:
-  // Store sum of squared error if needed.
-  if (sse != NULL) *sse = (uint64_t)err;
-
-  return 1;
-}
-
-int DequantizeLevels(uint8_t* const data, int width, int height) {
-  if (data == NULL || width <= 0 || height <= 0) return 0;
-  // TODO(skal): implement gradient smoothing.
-  (void)data;
-  (void)width;
-  (void)height;
-  return 1;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 39
drivers/webpold/utils/quant_levels.h

@@ -1,39 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Alpha plane quantization utility
-//
-// Author:  Vikas Arora ([email protected])
-
-#ifndef WEBP_UTILS_QUANT_LEVELS_H_
-#define WEBP_UTILS_QUANT_LEVELS_H_
-
-#include <stdlib.h>
-
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-// Replace the input 'data' of size 'width'x'height' with 'num-levels'
-// quantized values. If not NULL, 'sse' will contain the sum of squared error.
-// Valid range for 'num_levels' is [2, 256].
-// Returns false in case of error (data is NULL, or parameters are invalid).
-int QuantizeLevels(uint8_t* const data, int width, int height, int num_levels,
-                   uint64_t* const sse);
-
-// Apply post-processing to input 'data' of size 'width'x'height' assuming
-// that the source was quantized to a reduced number of levels.
-// Returns false in case of error (data is NULL, invalid parameters, ...).
-int DequantizeLevels(uint8_t* const data, int width, int height);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_UTILS_QUANT_LEVELS_H_ */

+ 0 - 152
drivers/webpold/utils/rescaler.c

@@ -1,152 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Rescaling functions
-//
-// Author: Skal ([email protected])
-
-#include <assert.h>
-#include <stdlib.h>
-#include "./rescaler.h"
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#define RFIX 30
-#define MULT_FIX(x,y) (((int64_t)(x) * (y) + (1 << (RFIX - 1))) >> RFIX)
-
-void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height,
-                      uint8_t* const dst, int dst_width, int dst_height,
-                      int dst_stride, int num_channels, int x_add, int x_sub,
-                      int y_add, int y_sub, int32_t* const work) {
-  wrk->x_expand = (src_width < dst_width);
-  wrk->src_width = src_width;
-  wrk->src_height = src_height;
-  wrk->dst_width = dst_width;
-  wrk->dst_height = dst_height;
-  wrk->dst = dst;
-  wrk->dst_stride = dst_stride;
-  wrk->num_channels = num_channels;
-  // for 'x_expand', we use bilinear interpolation
-  wrk->x_add = wrk->x_expand ? (x_sub - 1) : x_add - x_sub;
-  wrk->x_sub = wrk->x_expand ? (x_add - 1) : x_sub;
-  wrk->y_accum = y_add;
-  wrk->y_add = y_add;
-  wrk->y_sub = y_sub;
-  wrk->fx_scale = (1 << RFIX) / x_sub;
-  wrk->fy_scale = (1 << RFIX) / y_sub;
-  wrk->fxy_scale = wrk->x_expand ?
-      ((int64_t)dst_height << RFIX) / (x_sub * src_height) :
-      ((int64_t)dst_height << RFIX) / (x_add * src_height);
-  wrk->irow = work;
-  wrk->frow = work + num_channels * dst_width;
-}
-
-void WebPRescalerImportRow(WebPRescaler* const wrk,
-                           const uint8_t* const src, int channel) {
-  const int x_stride = wrk->num_channels;
-  const int x_out_max = wrk->dst_width * wrk->num_channels;
-  int x_in = channel;
-  int x_out;
-  int accum = 0;
-  if (!wrk->x_expand) {
-    int sum = 0;
-    for (x_out = channel; x_out < x_out_max; x_out += x_stride) {
-      accum += wrk->x_add;
-      for (; accum > 0; accum -= wrk->x_sub) {
-        sum += src[x_in];
-        x_in += x_stride;
-      }
-      {        // Emit next horizontal pixel.
-        const int32_t base = src[x_in];
-        const int32_t frac = base * (-accum);
-        x_in += x_stride;
-        wrk->frow[x_out] = (sum + base) * wrk->x_sub - frac;
-        // fresh fractional start for next pixel
-        sum = (int)MULT_FIX(frac, wrk->fx_scale);
-      }
-    }
-  } else {        // simple bilinear interpolation
-    int left = src[channel], right = src[channel];
-    for (x_out = channel; x_out < x_out_max; x_out += x_stride) {
-      if (accum < 0) {
-        left = right;
-        x_in += x_stride;
-        right = src[x_in];
-        accum += wrk->x_add;
-      }
-      wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
-      accum -= wrk->x_sub;
-    }
-  }
-  // Accumulate the new row's contribution
-  for (x_out = channel; x_out < x_out_max; x_out += x_stride) {
-    wrk->irow[x_out] += wrk->frow[x_out];
-  }
-}
-
-uint8_t* WebPRescalerExportRow(WebPRescaler* const wrk) {
-  if (wrk->y_accum <= 0) {
-    int x_out;
-    uint8_t* const dst = wrk->dst;
-    int32_t* const irow = wrk->irow;
-    const int32_t* const frow = wrk->frow;
-    const int yscale = wrk->fy_scale * (-wrk->y_accum);
-    const int x_out_max = wrk->dst_width * wrk->num_channels;
-
-    for (x_out = 0; x_out < x_out_max; ++x_out) {
-      const int frac = (int)MULT_FIX(frow[x_out], yscale);
-      const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
-      dst[x_out] = (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
-      irow[x_out] = frac;   // new fractional start
-    }
-    wrk->y_accum += wrk->y_add;
-    wrk->dst += wrk->dst_stride;
-    return dst;
-  } else {
-    return NULL;
-  }
-}
-
-#undef MULT_FIX
-#undef RFIX
-
-//------------------------------------------------------------------------------
-// all-in-one calls
-
-int WebPRescalerImport(WebPRescaler* const wrk, int num_lines,
-                       const uint8_t* src, int src_stride) {
-  int total_imported = 0;
-  while (total_imported < num_lines && wrk->y_accum > 0) {
-    int channel;
-    for (channel = 0; channel < wrk->num_channels; ++channel) {
-      WebPRescalerImportRow(wrk, src, channel);
-    }
-    src += src_stride;
-    ++total_imported;
-    wrk->y_accum -= wrk->y_sub;
-  }
-  return total_imported;
-}
-
-int WebPRescalerExport(WebPRescaler* const rescaler) {
-  int total_exported = 0;
-  while (WebPRescalerHasPendingOutput(rescaler)) {
-    WebPRescalerExportRow(rescaler);
-    ++total_exported;
-  }
-  return total_exported;
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 76
drivers/webpold/utils/rescaler.h

@@ -1,76 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Rescaling functions
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_UTILS_RESCALER_H_
-#define WEBP_UTILS_RESCALER_H_
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include "../types.h"
-
-// Structure used for on-the-fly rescaling
-typedef struct {
-  int x_expand;               // true if we're expanding in the x direction
-  int num_channels;           // bytes to jump between pixels
-  int fy_scale, fx_scale;     // fixed-point scaling factor
-  int64_t fxy_scale;          // ''
-  // we need hpel-precise add/sub increments, for the downsampled U/V planes.
-  int y_accum;                // vertical accumulator
-  int y_add, y_sub;           // vertical increments (add ~= src, sub ~= dst)
-  int x_add, x_sub;           // horizontal increments (add ~= src, sub ~= dst)
-  int src_width, src_height;  // source dimensions
-  int dst_width, dst_height;  // destination dimensions
-  uint8_t* dst;
-  int dst_stride;
-  int32_t* irow, *frow;       // work buffer
-} WebPRescaler;
-
-// Initialize a rescaler given scratch area 'work' and dimensions of src & dst.
-void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height,
-                      uint8_t* const dst,
-                      int dst_width, int dst_height, int dst_stride,
-                      int num_channels,
-                      int x_add, int x_sub,
-                      int y_add, int y_sub,
-                      int32_t* const work);
-
-// Import a row of data and save its contribution in the rescaler.
-// 'channel' denotes the channel number to be imported.
-void WebPRescalerImportRow(WebPRescaler* const rescaler,
-                           const uint8_t* const src, int channel);
-
-// Import multiple rows over all channels, until at least one row is ready to
-// be exported. Returns the actual number of lines that were imported.
-int WebPRescalerImport(WebPRescaler* const rescaler, int num_rows,
-                       const uint8_t* src, int src_stride);
-
-// Return true if there is pending output rows ready.
-static WEBP_INLINE
-int WebPRescalerHasPendingOutput(const WebPRescaler* const rescaler) {
-  return (rescaler->y_accum <= 0);
-}
-
-// Export one row from rescaler. Returns the pointer where output was written,
-// or NULL if no row was pending.
-uint8_t* WebPRescalerExportRow(WebPRescaler* const wrk);
-
-// Export as many rows as possible. Return the numbers of rows written.
-int WebPRescalerExport(WebPRescaler* const wrk);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_UTILS_RESCALER_H_ */

+ 0 - 247
drivers/webpold/utils/thread.c

@@ -1,247 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Multi-threaded worker
-//
-// Author: Skal ([email protected])
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <string.h>   // for memset()
-#include "./thread.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#ifdef WEBP_USE_THREAD
-
-#if defined(_WIN32)
-
-//------------------------------------------------------------------------------
-// simplistic pthread emulation layer
-
-#include <process.h>
-
-// _beginthreadex requires __stdcall
-#define THREADFN unsigned int __stdcall
-#define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val)
-
-static int pthread_create(pthread_t* const thread, const void* attr,
-                          unsigned int (__stdcall *start)(void*), void* arg) {
-  (void)attr;
-  *thread = (pthread_t)_beginthreadex(NULL,   /* void *security */
-                                      0,      /* unsigned stack_size */
-                                      start,
-                                      arg,
-                                      0,      /* unsigned initflag */
-                                      NULL);  /* unsigned *thrdaddr */
-  if (*thread == NULL) return 1;
-  SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL);
-  return 0;
-}
-
-static int pthread_join(pthread_t thread, void** value_ptr) {
-  (void)value_ptr;
-  return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 ||
-          CloseHandle(thread) == 0);
-}
-
-// Mutex
-static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) {
-  (void)mutexattr;
-  InitializeCriticalSection(mutex);
-  return 0;
-}
-
-static int pthread_mutex_lock(pthread_mutex_t* const mutex) {
-  EnterCriticalSection(mutex);
-  return 0;
-}
-
-static int pthread_mutex_unlock(pthread_mutex_t* const mutex) {
-  LeaveCriticalSection(mutex);
-  return 0;
-}
-
-static int pthread_mutex_destroy(pthread_mutex_t* const mutex) {
-  DeleteCriticalSection(mutex);
-  return 0;
-}
-
-// Condition
-static int pthread_cond_destroy(pthread_cond_t* const condition) {
-  int ok = 1;
-  ok &= (CloseHandle(condition->waiting_sem_) != 0);
-  ok &= (CloseHandle(condition->received_sem_) != 0);
-  ok &= (CloseHandle(condition->signal_event_) != 0);
-  return !ok;
-}
-
-static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) {
-  (void)cond_attr;
-  condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
-  condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
-  condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
-  if (condition->waiting_sem_ == NULL ||
-      condition->received_sem_ == NULL ||
-      condition->signal_event_ == NULL) {
-    pthread_cond_destroy(condition);
-    return 1;
-  }
-  return 0;
-}
-
-static int pthread_cond_signal(pthread_cond_t* const condition) {
-  int ok = 1;
-  if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) {
-    // a thread is waiting in pthread_cond_wait: allow it to be notified
-    ok = SetEvent(condition->signal_event_);
-    // wait until the event is consumed so the signaler cannot consume
-    // the event via its own pthread_cond_wait.
-    ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) !=
-           WAIT_OBJECT_0);
-  }
-  return !ok;
-}
-
-static int pthread_cond_wait(pthread_cond_t* const condition,
-                             pthread_mutex_t* const mutex) {
-  int ok;
-  // note that there is a consumer available so the signal isn't dropped in
-  // pthread_cond_signal
-  if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL))
-    return 1;
-  // now unlock the mutex so pthread_cond_signal may be issued
-  pthread_mutex_unlock(mutex);
-  ok = (WaitForSingleObject(condition->signal_event_, INFINITE) ==
-        WAIT_OBJECT_0);
-  ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL);
-  pthread_mutex_lock(mutex);
-  return !ok;
-}
-
-#else  // _WIN32
-# define THREADFN void*
-# define THREAD_RETURN(val) val
-#endif
-
-//------------------------------------------------------------------------------
-
-static THREADFN WebPWorkerThreadLoop(void *ptr) {    // thread loop
-  WebPWorker* const worker = (WebPWorker*)ptr;
-  int done = 0;
-  while (!done) {
-    pthread_mutex_lock(&worker->mutex_);
-    while (worker->status_ == OK) {   // wait in idling mode
-      pthread_cond_wait(&worker->condition_, &worker->mutex_);
-    }
-    if (worker->status_ == WORK) {
-      if (worker->hook) {
-        worker->had_error |= !worker->hook(worker->data1, worker->data2);
-      }
-      worker->status_ = OK;
-    } else if (worker->status_ == NOT_OK) {   // finish the worker
-      done = 1;
-    }
-    // signal to the main thread that we're done (for Sync())
-    pthread_cond_signal(&worker->condition_);
-    pthread_mutex_unlock(&worker->mutex_);
-  }
-  return THREAD_RETURN(NULL);    // Thread is finished
-}
-
-// main thread state control
-static void WebPWorkerChangeState(WebPWorker* const worker,
-                                  WebPWorkerStatus new_status) {
-  // no-op when attempting to change state on a thread that didn't come up
-  if (worker->status_ < OK) return;
-
-  pthread_mutex_lock(&worker->mutex_);
-  // wait for the worker to finish
-  while (worker->status_ != OK) {
-    pthread_cond_wait(&worker->condition_, &worker->mutex_);
-  }
-  // assign new status and release the working thread if needed
-  if (new_status != OK) {
-    worker->status_ = new_status;
-    pthread_cond_signal(&worker->condition_);
-  }
-  pthread_mutex_unlock(&worker->mutex_);
-}
-
-#endif
-
-//------------------------------------------------------------------------------
-
-void WebPWorkerInit(WebPWorker* const worker) {
-  memset(worker, 0, sizeof(*worker));
-  worker->status_ = NOT_OK;
-}
-
-int WebPWorkerSync(WebPWorker* const worker) {
-#ifdef WEBP_USE_THREAD
-  WebPWorkerChangeState(worker, OK);
-#endif
-  assert(worker->status_ <= OK);
-  return !worker->had_error;
-}
-
-int WebPWorkerReset(WebPWorker* const worker) {
-  int ok = 1;
-  worker->had_error = 0;
-  if (worker->status_ < OK) {
-#ifdef WEBP_USE_THREAD
-    if (pthread_mutex_init(&worker->mutex_, NULL) ||
-        pthread_cond_init(&worker->condition_, NULL)) {
-      return 0;
-    }
-    pthread_mutex_lock(&worker->mutex_);
-    ok = !pthread_create(&worker->thread_, NULL, WebPWorkerThreadLoop, worker);
-    if (ok) worker->status_ = OK;
-    pthread_mutex_unlock(&worker->mutex_);
-#else
-    worker->status_ = OK;
-#endif
-  } else if (worker->status_ > OK) {
-    ok = WebPWorkerSync(worker);
-  }
-  assert(!ok || (worker->status_ == OK));
-  return ok;
-}
-
-void WebPWorkerLaunch(WebPWorker* const worker) {
-#ifdef WEBP_USE_THREAD
-  WebPWorkerChangeState(worker, WORK);
-#else
-  if (worker->hook)
-    worker->had_error |= !worker->hook(worker->data1, worker->data2);
-#endif
-}
-
-void WebPWorkerEnd(WebPWorker* const worker) {
-  if (worker->status_ >= OK) {
-#ifdef WEBP_USE_THREAD
-    WebPWorkerChangeState(worker, NOT_OK);
-    pthread_join(worker->thread_, NULL);
-    pthread_mutex_destroy(&worker->mutex_);
-    pthread_cond_destroy(&worker->condition_);
-#else
-    worker->status_ = NOT_OK;
-#endif
-  }
-  assert(worker->status_ == NOT_OK);
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 86
drivers/webpold/utils/thread.h

@@ -1,86 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Multi-threaded worker
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_UTILS_THREAD_H_
-#define WEBP_UTILS_THREAD_H_
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#if WEBP_USE_THREAD
-
-#if defined(_WIN32)
-
-#include <windows.h>
-typedef HANDLE pthread_t;
-typedef CRITICAL_SECTION pthread_mutex_t;
-typedef struct {
-  HANDLE waiting_sem_;
-  HANDLE received_sem_;
-  HANDLE signal_event_;
-} pthread_cond_t;
-
-#else
-
-#include <pthread.h>
-
-#endif    /* _WIN32 */
-#endif    /* WEBP_USE_THREAD */
-
-// State of the worker thread object
-typedef enum {
-  NOT_OK = 0,   // object is unusable
-  OK,           // ready to work
-  WORK          // busy finishing the current task
-} WebPWorkerStatus;
-
-// Function to be called by the worker thread. Takes two opaque pointers as
-// arguments (data1 and data2), and should return false in case of error.
-typedef int (*WebPWorkerHook)(void*, void*);
-
-// Synchronize object used to launch job in the worker thread
-typedef struct {
-#if WEBP_USE_THREAD
-  pthread_mutex_t mutex_;
-  pthread_cond_t  condition_;
-  pthread_t       thread_;
-#endif
-  WebPWorkerStatus status_;
-  WebPWorkerHook hook;    // hook to call
-  void* data1;            // first argument passed to 'hook'
-  void* data2;            // second argument passed to 'hook'
-  int had_error;          // return value of the last call to 'hook'
-} WebPWorker;
-
-// Must be called first, before any other method.
-void WebPWorkerInit(WebPWorker* const worker);
-// Must be called initialize the object and spawn the thread. Re-entrant.
-// Will potentially launch the thread. Returns false in case of error.
-int WebPWorkerReset(WebPWorker* const worker);
-// Make sure the previous work is finished. Returns true if worker->had_error
-// was not set and not error condition was triggered by the working thread.
-int WebPWorkerSync(WebPWorker* const worker);
-// Trigger the thread to call hook() with data1 and data2 argument. These
-// hook/data1/data2 can be changed at any time before calling this function,
-// but not be changed afterward until the next call to WebPWorkerSync().
-void WebPWorkerLaunch(WebPWorker* const worker);
-// Kill the thread and terminate the object. To use the object again, one
-// must call WebPWorkerReset() again.
-void WebPWorkerEnd(WebPWorker* const worker);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_UTILS_THREAD_H_ */

+ 0 - 44
drivers/webpold/utils/utils.c

@@ -1,44 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Misc. common utility functions
-//
-// Author: Skal ([email protected])
-
-#include <stdlib.h>
-#include "./utils.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Checked memory allocation
-
-static int CheckSizeArguments(uint64_t nmemb, size_t size) {
-  const uint64_t total_size = nmemb * size;
-  if (nmemb == 0) return 1;
-  if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0;
-  if (total_size != (size_t)total_size) return 0;
-  return 1;
-}
-
-void* WebPSafeMalloc(uint64_t nmemb, size_t size) {
-  if (!CheckSizeArguments(nmemb, size)) return NULL;
-  return malloc((size_t)(nmemb * size));
-}
-
-void* WebPSafeCalloc(uint64_t nmemb, size_t size) {
-  if (!CheckSizeArguments(nmemb, size)) return NULL;
-  return calloc((size_t)nmemb, size);
-}
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif

+ 0 - 44
drivers/webpold/utils/utils.h

@@ -1,44 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// This code is licensed under the same terms as WebM:
-//  Software License Agreement:  http://www.webmproject.org/license/software/
-//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
-// -----------------------------------------------------------------------------
-//
-// Misc. common utility functions
-//
-// Author: Skal ([email protected])
-
-#ifndef WEBP_UTILS_UTILS_H_
-#define WEBP_UTILS_UTILS_H_
-
-#include "../types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-//------------------------------------------------------------------------------
-// Memory allocation
-
-// This is the maximum memory amount that libwebp will ever try to allocate.
-#define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 40)
-
-// size-checking safe malloc/calloc: verify that the requested size is not too
-// large, or return NULL. You don't need to call these for constructs like
-// malloc(sizeof(foo)), but only if there's picture-dependent size involved
-// somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this
-// safe malloc() borrows the signature from calloc(), pointing at the dangerous
-// underlying multiply involved.
-void* WebPSafeMalloc(uint64_t nmemb, size_t size);
-// Note that WebPSafeCalloc() expects the second argument type to be 'size_t'
-// in order to favor the "calloc(num_foo, sizeof(foo))" pattern.
-void* WebPSafeCalloc(uint64_t nmemb, size_t size);
-
-//------------------------------------------------------------------------------
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    // extern "C"
-#endif
-
-#endif  /* WEBP_UTILS_UTILS_H_ */