Commit 02836484 authored by fbarchard@google.com's avatar fbarchard@google.com

ARGB Scale ported to C

BUG=303
TESTED=cl /c /TC /Iinclude source/scale_argb.cc
R=tpsiaki@google.com

Review URL: https://webrtc-codereview.appspot.com/7169004

git-svn-id: http://libyuv.googlecode.com/svn/trunk@972 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent d3f1821b
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 971 Version: 972
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,6 +11,6 @@ ...@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 971 #define LIBYUV_VERSION 972
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
...@@ -170,6 +170,12 @@ static void ScaleARGBBilinearDown(int src_width, int src_height, ...@@ -170,6 +170,12 @@ static void ScaleARGBBilinearDown(int src_width, int src_height,
int x, int dx, int y, int dy, int x, int dx, int y, int dy,
enum FilterMode filtering) { enum FilterMode filtering) {
int j; int j;
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
InterpolateRow_C;
void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb,
int dst_width, int x, int dx) =
(src_width >= 32768) ? ScaleARGBFilterCols64_C : ScaleARGBFilterCols_C;
int64 xlast = x + (int64)(dst_width - 1) * dx; int64 xlast = x + (int64)(dst_width - 1) * dx;
int64 xl = (dx >= 0) ? x : xlast; int64 xl = (dx >= 0) ? x : xlast;
int64 xr = (dx >= 0) ? xlast : x; int64 xr = (dx >= 0) ? xlast : x;
...@@ -179,9 +185,6 @@ static void ScaleARGBBilinearDown(int src_width, int src_height, ...@@ -179,9 +185,6 @@ static void ScaleARGBBilinearDown(int src_width, int src_height,
clip_src_width = (((xr - xl) + 1 + 3) & ~3) * 4; // Width aligned to 4. clip_src_width = (((xr - xl) + 1 + 3) & ~3) * 4; // Width aligned to 4.
src_argb += xl * 4; src_argb += xl * 4;
x -= (int)(xl << 16); x -= (int)(xl << 16);
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
InterpolateRow_C;
#if defined(HAS_INTERPOLATEROW_SSE2) #if defined(HAS_INTERPOLATEROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && clip_src_width >= 16) { if (TestCpuFlag(kCpuHasSSE2) && clip_src_width >= 16) {
InterpolateRow = InterpolateRow_Any_SSE2; InterpolateRow = InterpolateRow_Any_SSE2;
...@@ -229,9 +232,6 @@ static void ScaleARGBBilinearDown(int src_width, int src_height, ...@@ -229,9 +232,6 @@ static void ScaleARGBBilinearDown(int src_width, int src_height,
} }
} }
#endif #endif
void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb,
int dst_width, int x, int dx) =
(src_width >= 32768) ? ScaleARGBFilterCols64_C : ScaleARGBFilterCols_C;
#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3) #if defined(HAS_SCALEARGBFILTERCOLS_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) {
ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3; ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3;
...@@ -239,26 +239,31 @@ static void ScaleARGBBilinearDown(int src_width, int src_height, ...@@ -239,26 +239,31 @@ static void ScaleARGBBilinearDown(int src_width, int src_height,
#endif #endif
// TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear.
// Allocate a row of ARGB. // Allocate a row of ARGB.
align_buffer_64(row, clip_src_width * 4); {
align_buffer_64(row, clip_src_width * 4);
const int max_y = (src_height - 1) << 16; const int max_y = (src_height - 1) << 16;
for (j = 0; j < dst_height; ++j) {
if (y > max_y) { if (y > max_y) {
y = max_y; y = max_y;
} }
int yi = y >> 16; for (j = 0; j < dst_height; ++j) {
const uint8* src = src_argb + yi * src_stride; int yi = y >> 16;
if (filtering == kFilterLinear) { const uint8* src = src_argb + yi * src_stride;
ScaleARGBFilterCols(dst_argb, src, dst_width, x, dx); if (filtering == kFilterLinear) {
} else { ScaleARGBFilterCols(dst_argb, src, dst_width, x, dx);
int yf = (y >> 8) & 255; } else {
InterpolateRow(row, src, src_stride, clip_src_width, yf); int yf = (y >> 8) & 255;
ScaleARGBFilterCols(dst_argb, row, dst_width, x, dx); InterpolateRow(row, src, src_stride, clip_src_width, yf);
ScaleARGBFilterCols(dst_argb, row, dst_width, x, dx);
}
dst_argb += dst_stride;
y += dy;
if (y > max_y) {
y = max_y;
}
} }
dst_argb += dst_stride; free_aligned_buffer_64(row);
y += dy;
} }
free_aligned_buffer_64(row);
} }
// Scale ARGB up with bilinear interpolation. // Scale ARGB up with bilinear interpolation.
...@@ -275,6 +280,7 @@ static void ScaleARGBBilinearUp(int src_width, int src_height, ...@@ -275,6 +280,7 @@ static void ScaleARGBBilinearUp(int src_width, int src_height,
void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb, void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb,
int dst_width, int x, int dx) = int dst_width, int x, int dx) =
filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C; filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C;
const int max_y = (src_height - 1) << 16;
#if defined(HAS_INTERPOLATEROW_SSE2) #if defined(HAS_INTERPOLATEROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) && dst_width >= 4) { if (TestCpuFlag(kCpuHasSSE2) && dst_width >= 4) {
InterpolateRow = InterpolateRow_Any_SSE2; InterpolateRow = InterpolateRow_Any_SSE2;
...@@ -344,54 +350,56 @@ static void ScaleARGBBilinearUp(int src_width, int src_height, ...@@ -344,54 +350,56 @@ static void ScaleARGBBilinearUp(int src_width, int src_height,
#endif #endif
} }
const int max_y = (src_height - 1) << 16;
if (y > max_y) { if (y > max_y) {
y = max_y; y = max_y;
} }
int yi = y >> 16;
const uint8* src = src_argb + yi * src_stride;
// Allocate 2 rows of ARGB. {
const int kRowSize = (dst_width * 4 + 15) & ~15; int yi = y >> 16;
align_buffer_64(row, kRowSize * 2); const uint8* src = src_argb + yi * src_stride;
uint8* rowptr = row; // Allocate 2 rows of ARGB.
int rowstride = kRowSize; const int kRowSize = (dst_width * 4 + 15) & ~15;
int lasty = yi; align_buffer_64(row, kRowSize * 2);
ScaleARGBFilterCols(rowptr, src, dst_width, x, dx); uint8* rowptr = row;
if (src_height > 1) { int rowstride = kRowSize;
int lasty = yi;
ScaleARGBFilterCols(rowptr, src, dst_width, x, dx);
if (src_height > 1) {
src += src_stride;
}
ScaleARGBFilterCols(rowptr + rowstride, src, dst_width, x, dx);
src += src_stride; src += src_stride;
}
ScaleARGBFilterCols(rowptr + rowstride, src, dst_width, x, dx);
src += src_stride;
for (j = 0; j < dst_height; ++j) { for (j = 0; j < dst_height; ++j) {
yi = y >> 16; yi = y >> 16;
if (yi != lasty) {
if (y > max_y) {
y = max_y;
yi = y >> 16;
src = src_argb + yi * src_stride;
}
if (yi != lasty) { if (yi != lasty) {
ScaleARGBFilterCols(rowptr, src, dst_width, x, dx); if (y > max_y) {
rowptr += rowstride; y = max_y;
rowstride = -rowstride; yi = y >> 16;
lasty = yi; src = src_argb + yi * src_stride;
src += src_stride; }
if (yi != lasty) {
ScaleARGBFilterCols(rowptr, src, dst_width, x, dx);
rowptr += rowstride;
rowstride = -rowstride;
lasty = yi;
src += src_stride;
}
} }
if (filtering == kFilterLinear) {
InterpolateRow(dst_argb, rowptr, 0, dst_width * 4, 0);
} else {
int yf = (y >> 8) & 255;
InterpolateRow(dst_argb, rowptr, rowstride, dst_width * 4, yf);
}
dst_argb += dst_stride;
y += dy;
} }
if (filtering == kFilterLinear) { free_aligned_buffer_64(row);
InterpolateRow(dst_argb, rowptr, 0, dst_width * 4, 0);
} else {
int yf = (y >> 8) & 255;
InterpolateRow(dst_argb, rowptr, rowstride, dst_width * 4, yf);
}
dst_argb += dst_stride;
y += dy;
} }
free_aligned_buffer_64(row);
} }
#ifdef YUVSCALEUP #ifdef YUVSCALEUP
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment