diff --git a/Android.mk b/Android.mk index ef11b13a..336b95f0 100644 --- a/Android.mk +++ b/Android.mk @@ -29,6 +29,7 @@ LOCAL_SRC_FILES := \ src/dsp/enc_sse2.c \ src/dsp/lossless.c \ src/dsp/upsampling.c \ + src/dsp/upsampling_mips32.c \ src/dsp/upsampling_sse2.c \ src/dsp/yuv.c \ src/enc/alpha.c \ diff --git a/Makefile.vc b/Makefile.vc index 046f7f7e..677c0672 100644 --- a/Makefile.vc +++ b/Makefile.vc @@ -174,6 +174,7 @@ DSP_DEC_OBJS = \ $(DIROBJ)\dsp\dec_sse2.obj \ $(DIROBJ)\dsp\lossless.obj \ $(DIROBJ)\dsp\upsampling.obj \ + $(DIROBJ)\dsp\upsampling_mips32.obj \ $(DIROBJ)\dsp\upsampling_neon.obj \ $(DIROBJ)\dsp\upsampling_sse2.obj \ $(DIROBJ)\dsp\yuv.obj \ diff --git a/makefile.unix b/makefile.unix index ed87c130..160762f2 100644 --- a/makefile.unix +++ b/makefile.unix @@ -105,6 +105,7 @@ DSP_DEC_OBJS = \ src/dsp/dec_sse2.o \ src/dsp/lossless.o \ src/dsp/upsampling.o \ + src/dsp/upsampling_mips32.o \ src/dsp/upsampling_neon.o \ src/dsp/upsampling_sse2.o \ src/dsp/yuv.o \ diff --git a/src/dsp/Makefile.am b/src/dsp/Makefile.am index 558f4b61..1e66b448 100644 --- a/src/dsp/Makefile.am +++ b/src/dsp/Makefile.am @@ -18,6 +18,7 @@ COMMON_SOURCES += dsp.h COMMON_SOURCES += lossless.c COMMON_SOURCES += lossless.h COMMON_SOURCES += upsampling.c +COMMON_SOURCES += upsampling_mips32.c COMMON_SOURCES += upsampling_neon.c COMMON_SOURCES += upsampling_sse2.c COMMON_SOURCES += yuv.c diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h index 0f764948..bd448961 100644 --- a/src/dsp/dsp.h +++ b/src/dsp/dsp.h @@ -189,6 +189,9 @@ typedef void (*WebPSampleLinePairFunc)( // Sampling functions to convert YUV to RGB(A) modes extern WebPSampleLinePairFunc WebPSamplers[/* MODE_LAST */]; +// Initializes MIPS version of the samplers. +void WebPInitSamplersMIPS32(void); + // 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). diff --git a/src/dsp/upsampling.c b/src/dsp/upsampling.c index 87726415..e90310e8 100644 --- a/src/dsp/upsampling.c +++ b/src/dsp/upsampling.c @@ -343,6 +343,11 @@ void WebPInitSamplers(void) { // If defined, use CPUInfo() to overwrite some pointers with faster versions. if (VP8GetCPUInfo != NULL) { +#if defined(WEBP_USE_MIPS32) + if (VP8GetCPUInfo(kMIPS32)) { + WebPInitSamplersMIPS32(); + } +#endif // WEBP_USE_MIPS32 } } diff --git a/src/dsp/upsampling_mips32.c b/src/dsp/upsampling_mips32.c new file mode 100644 index 00000000..8ea35a3f --- /dev/null +++ b/src/dsp/upsampling_mips32.c @@ -0,0 +1,124 @@ +// 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 +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// MIPS version of YUV to RGB upsampling functions. +// +// Author(s): Djordje Pesut (djordje.pesut@imgtec.com) +// Jovan Zelincevic (jovan.zelincevic@imgtec.com) + +#include "./dsp.h" + +#if defined(WEBP_USE_MIPS32) + +#include +#include +#include "./yuv.h" + +//------------------------------------------------------------------------------ +// simple point-sampling + +#define SAMPLE_FUNC_MIPS(FUNC_NAME, XSTEP, R, G, B, A) \ +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, r, g, b; \ + int temp0, temp1, temp2, temp3, temp4; \ + for (i = 0; i < (len >> 1); i++) { \ + temp1 = kVToR * v[0]; \ + temp3 = kVToG * v[0]; \ + temp2 = kUToG * u[0]; \ + temp4 = kUToB * u[0]; \ + temp0 = kYScale * top_y[0]; \ + temp1 += kRCst; \ + temp3 -= kGCst; \ + temp2 += temp3; \ + temp4 += kBCst; \ + r = VP8Clip8(temp0 + temp1); \ + g = VP8Clip8(temp0 - temp2); \ + b = VP8Clip8(temp0 + temp4); \ + temp0 = kYScale * top_y[1]; \ + top_dst[R] = r; \ + top_dst[G] = g; \ + top_dst[B] = b; \ + if (A) top_dst[A] = 0xff; \ + r = VP8Clip8(temp0 + temp1); \ + g = VP8Clip8(temp0 - temp2); \ + b = VP8Clip8(temp0 + temp4); \ + temp0 = kYScale * bottom_y[0]; \ + top_dst[R + XSTEP] = r; \ + top_dst[G + XSTEP] = g; \ + top_dst[B + XSTEP] = b; \ + if (A) top_dst[A + XSTEP] = 0xff; \ + r = VP8Clip8(temp0 + temp1); \ + g = VP8Clip8(temp0 - temp2); \ + b = VP8Clip8(temp0 + temp4); \ + temp0 = kYScale * bottom_y[1]; \ + bottom_dst[R] = r; \ + bottom_dst[G] = g; \ + bottom_dst[B] = b; \ + if (A) bottom_dst[A] = 0xff; \ + r = VP8Clip8(temp0 + temp1); \ + g = VP8Clip8(temp0 - temp2); \ + b = VP8Clip8(temp0 + temp4); \ + bottom_dst[R + XSTEP] = r; \ + bottom_dst[G + XSTEP] = g; \ + bottom_dst[B + XSTEP] = b; \ + if (A) bottom_dst[A + XSTEP] = 0xff; \ + top_y += 2; \ + bottom_y += 2; \ + u++; \ + v++; \ + top_dst += 2 * XSTEP; \ + bottom_dst += 2 * XSTEP; \ + } \ + if (len & 1) { \ + temp1 = kVToR * v[0]; \ + temp3 = kVToG * v[0]; \ + temp2 = kUToG * u[0]; \ + temp4 = kUToB * u[0]; \ + temp0 = kYScale * top_y[0]; \ + temp1 += kRCst; \ + temp3 -= kGCst; \ + temp2 += temp3; \ + temp4 += kBCst; \ + r = VP8Clip8(temp0 + temp1); \ + g = VP8Clip8(temp0 - temp2); \ + b = VP8Clip8(temp0 + temp4); \ + temp0 = kYScale * bottom_y[0]; \ + top_dst[R] = r; \ + top_dst[G] = g; \ + top_dst[B] = b; \ + if (A) top_dst[A] = 0xff; \ + r = VP8Clip8(temp0 + temp1); \ + g = VP8Clip8(temp0 - temp2); \ + b = VP8Clip8(temp0 + temp4); \ + bottom_dst[R] = r; \ + bottom_dst[G] = g; \ + bottom_dst[B] = b; \ + if (A) bottom_dst[A] = 0xff; \ + } \ +} + +SAMPLE_FUNC_MIPS(SampleRgbLinePairMIPS, 3, 0, 1, 2, 0) +SAMPLE_FUNC_MIPS(SampleRgbaLinePairMIPS, 4, 0, 1, 2, 3) +SAMPLE_FUNC_MIPS(SampleBgrLinePairMIPS, 3, 2, 1, 0, 0) +SAMPLE_FUNC_MIPS(SampleBgraLinePairMIPS, 4, 2, 1, 0, 3) + +#endif // WEBP_USE_MIPS32 + +//------------------------------------------------------------------------------ + +void WebPInitSamplersMIPS32(void) { +#if defined(WEBP_USE_MIPS32) + WebPSamplers[MODE_RGB] = SampleRgbLinePairMIPS; + WebPSamplers[MODE_RGBA] = SampleRgbaLinePairMIPS; + WebPSamplers[MODE_BGR] = SampleBgrLinePairMIPS; + WebPSamplers[MODE_BGRA] = SampleBgraLinePairMIPS; +#endif // WEBP_USE_MIPS32 +}