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 |