| Index: third_party/libwebp/utils/rescaler.c
|
| diff --git a/third_party/libwebp/utils/rescaler.c b/third_party/libwebp/utils/rescaler.c
|
| index 3a43229127fd52f93bc09c978640bdf1472de95a..00c9300bfbdd5009e88f87e45b9a59f158584884 100644
|
| --- a/third_party/libwebp/utils/rescaler.c
|
| +++ b/third_party/libwebp/utils/rescaler.c
|
| @@ -14,451 +14,8 @@
|
| #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)
|
| -
|
| -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);
|
| - }
|
| -}
|
| -
|
| -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;
|
| - }
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// MIPS version
|
| -
|
| -#if defined(WEBP_USE_MIPS32)
|
| -
|
| -static void ImportRowShrinkMIPS(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;
|
| - const int x_add = wrk->x_add;
|
| - const int x_sub = wrk->x_sub;
|
| - const int x_stride1 = x_stride << 2;
|
| - int channel;
|
| - assert(!wrk->x_expand);
|
| - assert(!WebPRescalerInputDone(wrk));
|
| -
|
| - for (channel = 0; channel < x_stride; ++channel) {
|
| - const uint8_t* src1 = src + channel;
|
| - rescaler_t* frow = wrk->frow + channel;
|
| - int temp1, temp2, temp3;
|
| - int base, frac, sum;
|
| - int accum, accum1;
|
| - int loop_c = x_out_max - channel;
|
| -
|
| - __asm__ volatile (
|
| - "li %[temp1], 0x8000 \n\t"
|
| - "li %[temp2], 0x10000 \n\t"
|
| - "li %[sum], 0 \n\t"
|
| - "li %[accum], 0 \n\t"
|
| - "1: \n\t"
|
| - "addu %[accum], %[accum], %[x_add] \n\t"
|
| - "li %[base], 0 \n\t"
|
| - "blez %[accum], 3f \n\t"
|
| - "2: \n\t"
|
| - "lbu %[base], 0(%[src1]) \n\t"
|
| - "subu %[accum], %[accum], %[x_sub] \n\t"
|
| - "addu %[src1], %[src1], %[x_stride] \n\t"
|
| - "addu %[sum], %[sum], %[base] \n\t"
|
| - "bgtz %[accum], 2b \n\t"
|
| - "3: \n\t"
|
| - "negu %[accum1], %[accum] \n\t"
|
| - "mul %[frac], %[base], %[accum1] \n\t"
|
| - "mul %[temp3], %[sum], %[x_sub] \n\t"
|
| - "subu %[loop_c], %[loop_c], %[x_stride] \n\t"
|
| - "mult %[temp1], %[temp2] \n\t"
|
| - "maddu %[frac], %[fx_scale] \n\t"
|
| - "mfhi %[sum] \n\t"
|
| - "subu %[temp3], %[temp3], %[frac] \n\t"
|
| - "sw %[temp3], 0(%[frow]) \n\t"
|
| - "addu %[frow], %[frow], %[x_stride1] \n\t"
|
| - "bgtz %[loop_c], 1b \n\t"
|
| - : [accum]"=&r"(accum), [src1]"+r"(src1), [temp3]"=&r"(temp3),
|
| - [sum]"=&r"(sum), [base]"=&r"(base), [frac]"=&r"(frac),
|
| - [frow]"+r"(frow), [accum1]"=&r"(accum1),
|
| - [temp2]"=&r"(temp2), [temp1]"=&r"(temp1)
|
| - : [x_stride]"r"(x_stride), [fx_scale]"r"(fx_scale),
|
| - [x_sub]"r"(x_sub), [x_add]"r"(x_add),
|
| - [loop_c]"r"(loop_c), [x_stride1]"r"(x_stride1)
|
| - : "memory", "hi", "lo"
|
| - );
|
| - assert(accum == 0);
|
| - }
|
| -}
|
| -
|
| -static void ImportRowExpandMIPS(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;
|
| - const int x_sub = wrk->x_sub;
|
| - const int src_width = wrk->src_width;
|
| - const int x_stride1 = x_stride << 2;
|
| - int channel;
|
| - assert(wrk->x_expand);
|
| - assert(!WebPRescalerInputDone(wrk));
|
| -
|
| - for (channel = 0; channel < x_stride; ++channel) {
|
| - const uint8_t* src1 = src + channel;
|
| - rescaler_t* frow = wrk->frow + channel;
|
| - int temp1, temp2, temp3, temp4;
|
| - int frac;
|
| - int accum;
|
| - int x_out = channel;
|
| -
|
| - __asm__ volatile (
|
| - "addiu %[temp3], %[src_width], -1 \n\t"
|
| - "lbu %[temp2], 0(%[src1]) \n\t"
|
| - "addu %[src1], %[src1], %[x_stride] \n\t"
|
| - "bgtz %[temp3], 0f \n\t"
|
| - "addiu %[temp1], %[temp2], 0 \n\t"
|
| - "b 3f \n\t"
|
| - "0: \n\t"
|
| - "lbu %[temp1], 0(%[src1]) \n\t"
|
| - "3: \n\t"
|
| - "addiu %[accum], %[x_add], 0 \n\t"
|
| - "1: \n\t"
|
| - "subu %[temp3], %[temp2], %[temp1] \n\t"
|
| - "mul %[temp3], %[temp3], %[accum] \n\t"
|
| - "mul %[temp4], %[temp1], %[x_add] \n\t"
|
| - "addu %[temp3], %[temp4], %[temp3] \n\t"
|
| - "sw %[temp3], 0(%[frow]) \n\t"
|
| - "addu %[frow], %[frow], %[x_stride1] \n\t"
|
| - "addu %[x_out], %[x_out], %[x_stride] \n\t"
|
| - "subu %[temp3], %[x_out], %[x_out_max] \n\t"
|
| - "bgez %[temp3], 2f \n\t"
|
| - "subu %[accum], %[accum], %[x_sub] \n\t"
|
| - "bgez %[accum], 4f \n\t"
|
| - "addiu %[temp2], %[temp1], 0 \n\t"
|
| - "addu %[src1], %[src1], %[x_stride] \n\t"
|
| - "lbu %[temp1], 0(%[src1]) \n\t"
|
| - "addu %[accum], %[accum], %[x_add] \n\t"
|
| - "4: \n\t"
|
| - "b 1b \n\t"
|
| - "2: \n\t"
|
| - : [src1]"+r"(src1), [accum]"=&r"(accum), [temp1]"=&r"(temp1),
|
| - [temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),
|
| - [x_out]"+r"(x_out), [frac]"=&r"(frac), [frow]"+r"(frow)
|
| - : [x_stride]"r"(x_stride), [x_add]"r"(x_add), [x_sub]"r"(x_sub),
|
| - [x_stride1]"r"(x_stride1), [src_width]"r"(src_width),
|
| - [x_out_max]"r"(x_out_max)
|
| - : "memory", "hi", "lo"
|
| - );
|
| - assert(wrk->x_sub == 0 /* <- special case for src_width=1 */ || accum == 0);
|
| - }
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Row export
|
| -
|
| -static void ExportRowExpandMIPS(WebPRescaler* const wrk) {
|
| - uint8_t* dst = wrk->dst;
|
| - rescaler_t* irow = wrk->irow;
|
| - const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| - const rescaler_t* frow = wrk->frow;
|
| - int temp0, temp1, temp3, temp4, temp5, loop_end;
|
| - const int temp2 = (int)wrk->fy_scale;
|
| - const int temp6 = x_out_max << 2;
|
| - assert(!WebPRescalerOutputDone(wrk));
|
| - assert(wrk->y_accum <= 0);
|
| - assert(wrk->y_expand);
|
| - assert(wrk->y_sub != 0);
|
| - if (wrk->y_accum == 0) {
|
| - __asm__ volatile (
|
| - "li %[temp3], 0x10000 \n\t"
|
| - "li %[temp4], 0x8000 \n\t"
|
| - "addu %[loop_end], %[frow], %[temp6] \n\t"
|
| - "1: \n\t"
|
| - "lw %[temp0], 0(%[frow]) \n\t"
|
| - "addiu %[dst], %[dst], 1 \n\t"
|
| - "addiu %[frow], %[frow], 4 \n\t"
|
| - "mult %[temp3], %[temp4] \n\t"
|
| - "maddu %[temp0], %[temp2] \n\t"
|
| - "mfhi %[temp5] \n\t"
|
| - "sb %[temp5], -1(%[dst]) \n\t"
|
| - "bne %[frow], %[loop_end], 1b \n\t"
|
| - : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
|
| - [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow),
|
| - [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
|
| - : [temp2]"r"(temp2), [temp6]"r"(temp6)
|
| - : "memory", "hi", "lo"
|
| - );
|
| - } else {
|
| - const uint32_t B = WEBP_RESCALER_FRAC(-wrk->y_accum, wrk->y_sub);
|
| - const uint32_t A = (uint32_t)(WEBP_RESCALER_ONE - B);
|
| - __asm__ volatile (
|
| - "li %[temp3], 0x10000 \n\t"
|
| - "li %[temp4], 0x8000 \n\t"
|
| - "addu %[loop_end], %[frow], %[temp6] \n\t"
|
| - "1: \n\t"
|
| - "lw %[temp0], 0(%[frow]) \n\t"
|
| - "lw %[temp1], 0(%[irow]) \n\t"
|
| - "addiu %[dst], %[dst], 1 \n\t"
|
| - "mult %[temp3], %[temp4] \n\t"
|
| - "maddu %[A], %[temp0] \n\t"
|
| - "maddu %[B], %[temp1] \n\t"
|
| - "addiu %[frow], %[frow], 4 \n\t"
|
| - "addiu %[irow], %[irow], 4 \n\t"
|
| - "mfhi %[temp5] \n\t"
|
| - "mult %[temp3], %[temp4] \n\t"
|
| - "maddu %[temp5], %[temp2] \n\t"
|
| - "mfhi %[temp5] \n\t"
|
| - "sb %[temp5], -1(%[dst]) \n\t"
|
| - "bne %[frow], %[loop_end], 1b \n\t"
|
| - : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
|
| - [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow),
|
| - [irow]"+r"(irow), [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
|
| - : [temp2]"r"(temp2), [temp6]"r"(temp6), [A]"r"(A), [B]"r"(B)
|
| - : "memory", "hi", "lo"
|
| - );
|
| - }
|
| -}
|
| -
|
| -static void ExportRowShrinkMIPS(WebPRescaler* const wrk) {
|
| - const int x_out_max = wrk->dst_width * wrk->num_channels;
|
| - uint8_t* dst = wrk->dst;
|
| - rescaler_t* irow = wrk->irow;
|
| - const rescaler_t* frow = wrk->frow;
|
| - const int yscale = wrk->fy_scale * (-wrk->y_accum);
|
| - int temp0, temp1, temp3, temp4, temp5, loop_end;
|
| - const int temp2 = (int)wrk->fxy_scale;
|
| - const int temp6 = x_out_max << 2;
|
| -
|
| - assert(!WebPRescalerOutputDone(wrk));
|
| - assert(wrk->y_accum <= 0);
|
| - assert(!wrk->y_expand);
|
| - assert(wrk->fxy_scale != 0);
|
| - if (yscale) {
|
| - __asm__ volatile (
|
| - "li %[temp3], 0x10000 \n\t"
|
| - "li %[temp4], 0x8000 \n\t"
|
| - "addu %[loop_end], %[frow], %[temp6] \n\t"
|
| - "1: \n\t"
|
| - "lw %[temp0], 0(%[frow]) \n\t"
|
| - "mult %[temp3], %[temp4] \n\t"
|
| - "addiu %[frow], %[frow], 4 \n\t"
|
| - "maddu %[temp0], %[yscale] \n\t"
|
| - "mfhi %[temp1] \n\t"
|
| - "lw %[temp0], 0(%[irow]) \n\t"
|
| - "addiu %[dst], %[dst], 1 \n\t"
|
| - "addiu %[irow], %[irow], 4 \n\t"
|
| - "subu %[temp0], %[temp0], %[temp1] \n\t"
|
| - "mult %[temp3], %[temp4] \n\t"
|
| - "maddu %[temp0], %[temp2] \n\t"
|
| - "mfhi %[temp5] \n\t"
|
| - "sw %[temp1], -4(%[irow]) \n\t"
|
| - "sb %[temp5], -1(%[dst]) \n\t"
|
| - "bne %[frow], %[loop_end], 1b \n\t"
|
| - : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
|
| - [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [frow]"+r"(frow),
|
| - [irow]"+r"(irow), [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
|
| - : [temp2]"r"(temp2), [yscale]"r"(yscale), [temp6]"r"(temp6)
|
| - : "memory", "hi", "lo"
|
| - );
|
| - } else {
|
| - __asm__ volatile (
|
| - "li %[temp3], 0x10000 \n\t"
|
| - "li %[temp4], 0x8000 \n\t"
|
| - "addu %[loop_end], %[irow], %[temp6] \n\t"
|
| - "1: \n\t"
|
| - "lw %[temp0], 0(%[irow]) \n\t"
|
| - "addiu %[dst], %[dst], 1 \n\t"
|
| - "addiu %[irow], %[irow], 4 \n\t"
|
| - "mult %[temp3], %[temp4] \n\t"
|
| - "maddu %[temp0], %[temp2] \n\t"
|
| - "mfhi %[temp5] \n\t"
|
| - "sw $zero, -4(%[irow]) \n\t"
|
| - "sb %[temp5], -1(%[dst]) \n\t"
|
| - "bne %[irow], %[loop_end], 1b \n\t"
|
| - : [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp3]"=&r"(temp3),
|
| - [temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [irow]"+r"(irow),
|
| - [dst]"+r"(dst), [loop_end]"=&r"(loop_end)
|
| - : [temp2]"r"(temp2), [temp6]"r"(temp6)
|
| - : "memory", "hi", "lo"
|
| - );
|
| - }
|
| -}
|
| -
|
| -#endif // WEBP_USE_MIPS32
|
| +#include "./rescaler.h"
|
|
|
| //------------------------------------------------------------------------------
|
|
|
| @@ -510,30 +67,37 @@ void WebPRescalerInit(WebPRescaler* const wrk, int src_width, int src_height,
|
| 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
|
| + WebPRescalerDspInit();
|
| +}
|
| +
|
| +int WebPRescalerGetScaledDimensions(int src_width, int src_height,
|
| + int* const scaled_width,
|
| + int* const scaled_height) {
|
| + assert(scaled_width != NULL);
|
| + assert(scaled_height != NULL);
|
| + {
|
| + int width = *scaled_width;
|
| + int height = *scaled_height;
|
| +
|
| + // if width is unspecified, scale original proportionally to height ratio.
|
| + if (width == 0) {
|
| + width = (src_width * height + src_height / 2) / src_height;
|
| }
|
| + // if height is unspecified, scale original proportionally to width ratio.
|
| + if (height == 0) {
|
| + height = (src_height * width + src_width / 2) / src_width;
|
| + }
|
| + // Check if the overall dimensions still make sense.
|
| + if (width <= 0 || height <= 0) {
|
| + return 0;
|
| + }
|
| +
|
| + *scaled_width = width;
|
| + *scaled_height = height;
|
| + return 1;
|
| }
|
| }
|
|
|
| -#undef MULT_FIX
|
| -#undef WEBP_RESCALER_RFIX
|
| -#undef WEBP_RESCALER_ONE
|
| -#undef WEBP_RESCALER_FRAC
|
| -#undef ROUNDER
|
| -
|
| //------------------------------------------------------------------------------
|
| // all-in-one calls
|
|
|
|
|