| Index: third_party/libwebp/dsp/rescaler_mips32.c
|
| diff --git a/third_party/libwebp/utils/rescaler.c b/third_party/libwebp/dsp/rescaler_mips32.c
|
| similarity index 52%
|
| copy from third_party/libwebp/utils/rescaler.c
|
| copy to third_party/libwebp/dsp/rescaler_mips32.c
|
| index 3a43229127fd52f93bc09c978640bdf1472de95a..ddaa39133639a6b8d1998ab42c88e0a6f807db5f 100644
|
| --- a/third_party/libwebp/utils/rescaler.c
|
| +++ b/third_party/libwebp/dsp/rescaler_mips32.c
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2012 Google Inc. All Rights Reserved.
|
| +// Copyright 2014 Google Inc. All Rights Reserved.
|
| //
|
| // Use of this source code is governed by a BSD-style license
|
| // that can be found in the COPYING file in the root of the source
|
| @@ -7,207 +7,21 @@
|
| // be found in the AUTHORS file in the root of the source tree.
|
| // -----------------------------------------------------------------------------
|
| //
|
| -// Rescaling functions
|
| +// MIPS version of rescaling functions
|
| //
|
| -// Author: Skal (pascal.massimino@gmail.com)
|
| +// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
|
|
|
| -#include <assert.h>
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| -#include "./rescaler.h"
|
| -#include "../dsp/dsp.h"
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Implementations of critical functions ImportRow / ExportRow
|
| -
|
| -// Import a row of data and save its contribution in the rescaler.
|
| -// 'channel' denotes the channel number to be imported. 'Expand' corresponds to
|
| -// the wrk->x_expand case. Otherwise, 'Shrink' is to be used.
|
| -typedef void (*WebPRescalerImportRowFunc)(WebPRescaler* const wrk,
|
| - const uint8_t* src);
|
| -static WebPRescalerImportRowFunc WebPRescalerImportRowExpand;
|
| -static WebPRescalerImportRowFunc WebPRescalerImportRowShrink;
|
| -
|
| -// Export one row (starting at x_out position) from rescaler.
|
| -// 'Expand' corresponds to the wrk->y_expand case.
|
| -// Otherwise 'Shrink' is to be used
|
| -typedef void (*WebPRescalerExportRowFunc)(WebPRescaler* const wrk);
|
| -static WebPRescalerExportRowFunc WebPRescalerExportRowExpand;
|
| -static WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
|
| -
|
| -#define WEBP_RESCALER_RFIX 32 // fixed-point precision for multiplies
|
| -#define WEBP_RESCALER_ONE (1ull << WEBP_RESCALER_RFIX)
|
| -#define WEBP_RESCALER_FRAC(x, y) \
|
| - ((uint32_t)(((uint64_t)(x) << WEBP_RESCALER_RFIX) / (y)))
|
| -#define ROUNDER (WEBP_RESCALER_ONE >> 1)
|
| -#define MULT_FIX(x, y) (((uint64_t)(x) * (y) + ROUNDER) >> WEBP_RESCALER_RFIX)
|
| +#include "./dsp.h"
|
|
|
| -static void ImportRowExpandC(WebPRescaler* const wrk, const uint8_t* src) {
|
| - const int x_stride = wrk->num_channels;
|
| - const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| - int channel;
|
| - assert(!WebPRescalerInputDone(wrk));
|
| - assert(wrk->x_expand);
|
| - for (channel = 0; channel < x_stride; ++channel) {
|
| - int x_in = channel;
|
| - int x_out = channel;
|
| - // simple bilinear interpolation
|
| - int accum = wrk->x_add;
|
| - int left = src[x_in];
|
| - int right = (wrk->src_width > 1) ? src[x_in + x_stride] : left;
|
| - x_in += x_stride;
|
| - while (1) {
|
| - wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
|
| - x_out += x_stride;
|
| - if (x_out >= x_out_max) break;
|
| - accum -= wrk->x_sub;
|
| - if (accum < 0) {
|
| - left = right;
|
| - x_in += x_stride;
|
| - assert(x_in < wrk->src_width * x_stride);
|
| - right = src[x_in];
|
| - accum += wrk->x_add;
|
| - }
|
| - }
|
| - assert(wrk->x_sub == 0 /* <- special case for src_width=1 */ || accum == 0);
|
| - }
|
| -}
|
| -
|
| -static void ImportRowShrinkC(WebPRescaler* const wrk, const uint8_t* src) {
|
| - const int x_stride = wrk->num_channels;
|
| - const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| - int channel;
|
| - assert(!WebPRescalerInputDone(wrk));
|
| - assert(!wrk->x_expand);
|
| - for (channel = 0; channel < x_stride; ++channel) {
|
| - int x_in = channel;
|
| - int x_out = channel;
|
| - uint32_t sum = 0;
|
| - int accum = 0;
|
| - while (x_out < x_out_max) {
|
| - uint32_t base = 0;
|
| - accum += wrk->x_add;
|
| - while (accum > 0) {
|
| - accum -= wrk->x_sub;
|
| - assert(x_in < wrk->src_width * x_stride);
|
| - base = src[x_in];
|
| - sum += base;
|
| - x_in += x_stride;
|
| - }
|
| - { // Emit next horizontal pixel.
|
| - const rescaler_t frac = base * (-accum);
|
| - wrk->frow[x_out] = sum * wrk->x_sub - frac;
|
| - // fresh fractional start for next pixel
|
| - sum = (int)MULT_FIX(frac, wrk->fx_scale);
|
| - }
|
| - x_out += x_stride;
|
| - }
|
| - assert(accum == 0);
|
| - }
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Row export
|
| -
|
| -static void ExportRowExpandC(WebPRescaler* const wrk) {
|
| - int x_out;
|
| - uint8_t* const dst = wrk->dst;
|
| - rescaler_t* const irow = wrk->irow;
|
| - const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| - const rescaler_t* const frow = wrk->frow;
|
| - assert(!WebPRescalerOutputDone(wrk));
|
| - assert(wrk->y_accum <= 0);
|
| - assert(wrk->y_expand);
|
| - assert(wrk->y_sub != 0);
|
| - if (wrk->y_accum == 0) {
|
| - for (x_out = 0; x_out < x_out_max; ++x_out) {
|
| - const uint32_t J = frow[x_out];
|
| - const int v = (int)MULT_FIX(J, wrk->fy_scale);
|
| - assert(v >= 0 && v <= 255);
|
| - dst[x_out] = v;
|
| - }
|
| - } else {
|
| - const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
|
| - const uint32_t A = (uint32_t)(WEBP_RESCALER_ONE - B);
|
| - for (x_out = 0; x_out < x_out_max; ++x_out) {
|
| - const uint64_t I = (uint64_t)A * frow[x_out]
|
| - + (uint64_t)B * irow[x_out];
|
| - const uint32_t J = (uint32_t)((I + ROUNDER) >> WEBP_RESCALER_RFIX);
|
| - const int v = (int)MULT_FIX(J, wrk->fy_scale);
|
| - assert(v >= 0 && v <= 255);
|
| - dst[x_out] = v;
|
| - }
|
| - }
|
| -}
|
| -
|
| -static void ExportRowShrinkC(WebPRescaler* const wrk) {
|
| - int x_out;
|
| - uint8_t* const dst = wrk->dst;
|
| - rescaler_t* const irow = wrk->irow;
|
| - const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| - const rescaler_t* const frow = wrk->frow;
|
| - const uint32_t yscale = wrk->fy_scale * (-wrk->y_accum);
|
| - assert(!WebPRescalerOutputDone(wrk));
|
| - assert(wrk->y_accum <= 0);
|
| - assert(!wrk->y_expand);
|
| - if (yscale) {
|
| - for (x_out = 0; x_out < x_out_max; ++x_out) {
|
| - const uint32_t frac = (uint32_t)MULT_FIX(frow[x_out], yscale);
|
| - const int v = (int)MULT_FIX(irow[x_out] - frac, wrk->fxy_scale);
|
| - assert(v >= 0 && v <= 255);
|
| - dst[x_out] = v;
|
| - irow[x_out] = frac; // new fractional start
|
| - }
|
| - } else {
|
| - for (x_out = 0; x_out < x_out_max; ++x_out) {
|
| - const int v = (int)MULT_FIX(irow[x_out], wrk->fxy_scale);
|
| - assert(v >= 0 && v <= 255);
|
| - dst[x_out] = v;
|
| - irow[x_out] = 0;
|
| - }
|
| - }
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Main entry calls
|
| -
|
| -void WebPRescalerImportRow(WebPRescaler* const wrk, const uint8_t* src) {
|
| - assert(!WebPRescalerInputDone(wrk));
|
| - if (!wrk->x_expand) {
|
| - WebPRescalerImportRowShrink(wrk, src);
|
| - } else {
|
| - WebPRescalerImportRowExpand(wrk, src);
|
| - }
|
| -}
|
| +#if defined(WEBP_USE_MIPS32)
|
|
|
| -void WebPRescalerExportRow(WebPRescaler* const wrk) {
|
| - if (wrk->y_accum <= 0) {
|
| - assert(!WebPRescalerOutputDone(wrk));
|
| - if (wrk->y_expand) {
|
| - WebPRescalerExportRowExpand(wrk);
|
| - } else if (wrk->fxy_scale) {
|
| - WebPRescalerExportRowShrink(wrk);
|
| - } else { // very special case for src = dst = 1x1
|
| - int i;
|
| - assert(wrk->src_width == 1 && wrk->dst_width <= 2);
|
| - assert(wrk->src_height == 1 && wrk->dst_height == 1);
|
| - for (i = 0; i < wrk->num_channels * wrk->dst_width; ++i) {
|
| - wrk->dst[i] = wrk->irow[i];
|
| - wrk->irow[i] = 0;
|
| - }
|
| - }
|
| - wrk->y_accum += wrk->y_add;
|
| - wrk->dst += wrk->dst_stride;
|
| - ++wrk->dst_y;
|
| - }
|
| -}
|
| +#include <assert.h>
|
| +#include "../utils/rescaler.h"
|
|
|
| //------------------------------------------------------------------------------
|
| -// MIPS version
|
| -
|
| -#if defined(WEBP_USE_MIPS32)
|
| +// Row import
|
|
|
| -static void ImportRowShrinkMIPS(WebPRescaler* const wrk, const uint8_t* src) {
|
| +static void ImportRowShrink(WebPRescaler* const wrk, const uint8_t* src) {
|
| const int x_stride = wrk->num_channels;
|
| const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| const int fx_scale = wrk->fx_scale;
|
| @@ -266,7 +80,7 @@ static void ImportRowShrinkMIPS(WebPRescaler* const wrk, const uint8_t* src) {
|
| }
|
| }
|
|
|
| -static void ImportRowExpandMIPS(WebPRescaler* const wrk, const uint8_t* src) {
|
| +static void ImportRowExpand(WebPRescaler* const wrk, const uint8_t* src) {
|
| const int x_stride = wrk->num_channels;
|
| const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| const int x_add = wrk->x_add;
|
| @@ -330,7 +144,7 @@ static void ImportRowExpandMIPS(WebPRescaler* const wrk, const uint8_t* src) {
|
| //------------------------------------------------------------------------------
|
| // Row export
|
|
|
| -static void ExportRowExpandMIPS(WebPRescaler* const wrk) {
|
| +static void ExportRowExpand(WebPRescaler* const wrk) {
|
| uint8_t* dst = wrk->dst;
|
| rescaler_t* irow = wrk->irow;
|
| const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| @@ -393,7 +207,7 @@ static void ExportRowExpandMIPS(WebPRescaler* const wrk) {
|
| }
|
| }
|
|
|
| -static void ExportRowShrinkMIPS(WebPRescaler* const wrk) {
|
| +static void ExportRowShrink(WebPRescaler* const wrk) {
|
| const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| uint8_t* dst = wrk->dst;
|
| rescaler_t* irow = wrk->irow;
|
| @@ -458,121 +272,20 @@ static void ExportRowShrinkMIPS(WebPRescaler* const wrk) {
|
| }
|
| }
|
|
|
| -#endif // WEBP_USE_MIPS32
|
| -
|
| //------------------------------------------------------------------------------
|
| +// Entry point
|
|
|
| -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, rescaler_t* const work) {
|
| - const int x_add = src_width, x_sub = dst_width;
|
| - const int y_add = src_height, y_sub = dst_height;
|
| - wrk->x_expand = (src_width < dst_width);
|
| - wrk->y_expand = (src_height < dst_height);
|
| - wrk->src_width = src_width;
|
| - wrk->src_height = src_height;
|
| - wrk->dst_width = dst_width;
|
| - wrk->dst_height = dst_height;
|
| - wrk->src_y = 0;
|
| - wrk->dst_y = 0;
|
| - 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;
|
| - wrk->x_sub = wrk->x_expand ? (x_add - 1) : x_sub;
|
| - if (!wrk->x_expand) { // fx_scale is not used otherwise
|
| - wrk->fx_scale = WEBP_RESCALER_FRAC(1, wrk->x_sub);
|
| - }
|
| - // vertical scaling parameters
|
| - wrk->y_add = wrk->y_expand ? y_add - 1 : y_add;
|
| - wrk->y_sub = wrk->y_expand ? y_sub - 1 : y_sub;
|
| - wrk->y_accum = wrk->y_expand ? wrk->y_sub : wrk->y_add;
|
| - if (!wrk->y_expand) {
|
| - // this is WEBP_RESCALER_FRAC(dst_height, x_add * y_add) without the cast.
|
| - const uint64_t ratio =
|
| - (uint64_t)dst_height * WEBP_RESCALER_ONE / (wrk->x_add * wrk->y_add);
|
| - if (ratio != (uint32_t)ratio) {
|
| - // We can't represent the ratio with the current fixed-point precision.
|
| - // => We special-case fxy_scale = 0, in WebPRescalerExportRow().
|
| - wrk->fxy_scale = 0;
|
| - } else {
|
| - wrk->fxy_scale = (uint32_t)ratio;
|
| - }
|
| - wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->y_sub);
|
| - } else {
|
| - wrk->fy_scale = WEBP_RESCALER_FRAC(1, wrk->x_add);
|
| - // wrk->fxy_scale is unused here.
|
| - }
|
| - wrk->irow = work;
|
| - wrk->frow = work + num_channels * dst_width;
|
| - memset(work, 0, 2 * dst_width * num_channels * sizeof(*work));
|
| -
|
| - if (WebPRescalerImportRowExpand == NULL) {
|
| - WebPRescalerImportRowExpand = ImportRowExpandC;
|
| - WebPRescalerImportRowShrink = ImportRowShrinkC;
|
| - WebPRescalerExportRowExpand = ExportRowExpandC;
|
| - WebPRescalerExportRowShrink = ExportRowShrinkC;
|
| - if (VP8GetCPUInfo != NULL) {
|
| -#if defined(WEBP_USE_MIPS32)
|
| - if (VP8GetCPUInfo(kMIPS32)) {
|
| - WebPRescalerImportRowExpand = ImportRowExpandMIPS;
|
| - WebPRescalerImportRowShrink = ImportRowShrinkMIPS;
|
| - WebPRescalerExportRowExpand = ExportRowExpandMIPS;
|
| - WebPRescalerExportRowShrink = ExportRowShrinkMIPS;
|
| - }
|
| -#endif
|
| - }
|
| - }
|
| -}
|
| -
|
| -#undef MULT_FIX
|
| -#undef WEBP_RESCALER_RFIX
|
| -#undef WEBP_RESCALER_ONE
|
| -#undef WEBP_RESCALER_FRAC
|
| -#undef ROUNDER
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// all-in-one calls
|
| +extern void WebPRescalerDspInitMIPS32(void);
|
|
|
| -int WebPRescaleNeededLines(const WebPRescaler* const wrk, int max_num_lines) {
|
| - const int num_lines = (wrk->y_accum + wrk->y_sub - 1) / wrk->y_sub;
|
| - return (num_lines > max_num_lines) ? max_num_lines : num_lines;
|
| +WEBP_TSAN_IGNORE_FUNCTION void WebPRescalerDspInitMIPS32(void) {
|
| + WebPRescalerImportRowExpand = ImportRowExpand;
|
| + WebPRescalerImportRowShrink = ImportRowShrink;
|
| + WebPRescalerExportRowExpand = ExportRowExpand;
|
| + WebPRescalerExportRowShrink = ExportRowShrink;
|
| }
|
|
|
| -int WebPRescalerImport(WebPRescaler* const wrk, int num_lines,
|
| - const uint8_t* src, int src_stride) {
|
| - int total_imported = 0;
|
| - while (total_imported < num_lines && !WebPRescalerHasPendingOutput(wrk)) {
|
| - if (wrk->y_expand) {
|
| - rescaler_t* const tmp = wrk->irow;
|
| - wrk->irow = wrk->frow;
|
| - wrk->frow = tmp;
|
| - }
|
| - WebPRescalerImportRow(wrk, src);
|
| - if (!wrk->y_expand) { // Accumulate the contribution of the new row.
|
| - int x;
|
| - for (x = 0; x < wrk->num_channels * wrk->dst_width; ++x) {
|
| - wrk->irow[x] += wrk->frow[x];
|
| - }
|
| - }
|
| - ++wrk->src_y;
|
| - src += src_stride;
|
| - ++total_imported;
|
| - wrk->y_accum -= wrk->y_sub;
|
| - }
|
| - return total_imported;
|
| -}
|
| +#else // !WEBP_USE_MIPS32
|
|
|
| -int WebPRescalerExport(WebPRescaler* const rescaler) {
|
| - int total_exported = 0;
|
| - while (WebPRescalerHasPendingOutput(rescaler)) {
|
| - WebPRescalerExportRow(rescaler);
|
| - ++total_exported;
|
| - }
|
| - return total_exported;
|
| -}
|
| +WEBP_DSP_INIT_STUB(WebPRescalerDspInitMIPS32)
|
|
|
| -//------------------------------------------------------------------------------
|
| +#endif // WEBP_USE_MIPS32
|
|
|