Commit 980150f7 authored by fbarchard@google.com's avatar fbarchard@google.com

Compute slope considering filtering, mirror.

BUG=261
TEST=valgrind
R=tpsiaki@google.com

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

git-svn-id: http://libyuv.googlecode.com/svn/trunk@896 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 09d5f2bf
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 895
Version: 896
License: BSD
License File: LICENSE
......
......@@ -55,10 +55,6 @@ extern "C" {
#define HAS_SCALEROWDOWN38_MIPS_DSPR2
#endif
FilterMode ScaleFilterReduce(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode filtering);
// Scale ARGB vertically with bilinear interpolation.
void ScalePlaneVertical(int src_height,
int dst_width, int dst_height,
......@@ -67,6 +63,17 @@ void ScalePlaneVertical(int src_height,
int x, int y, int dy,
int bpp, FilterMode filtering);
// Simplify the filtering based on scale factors.
FilterMode ScaleFilterReduce(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode filtering);
// Compute slope values for stepping.
void ScaleSlope(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode filtering,
int* x, int* y, int* dx, int* dy);
void ScaleRowDown2_C(const uint8* src_ptr, ptrdiff_t /* src_stride */,
uint8* dst, int dst_width);
void ScaleRowDown2Linear_C(const uint8* src_ptr, ptrdiff_t src_stride,
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 895
#define LIBYUV_VERSION 896
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
......@@ -593,33 +593,8 @@ static void ScaleARGB(const uint8* src, int src_stride,
int dy = 0;
int x = 0;
int y = 0;
if (filtering) {
// Scale step for bilinear sampling renders last pixel once for upsample.
if (dst_width <= Abs(src_width)) {
dx = FixedDiv(Abs(src_width), dst_width);
x = (dx >> 1) - 32768;
} else if (dst_width > 1) {
dx = FixedDiv(Abs(src_width) - 1, dst_width - 1);
}
if (dst_height <= src_height) {
dy = FixedDiv(src_height, dst_height);
y = (dy >> 1) - 32768;
} else if (dst_height > 1) {
dy = FixedDiv(src_height - 1, dst_height - 1);
}
} else {
// Scale step for point sampling duplicates all pixels equally.
dx = FixedDiv(Abs(src_width), dst_width);
dy = FixedDiv(src_height, dst_height);
x = dx >> 1;
y = dy >> 1;
}
// Negative src_width means horizontally mirror.
if (src_width < 0) {
x += (dst_width - 1) * dx;
dx = -dx;
src_width = -src_width;
}
ScaleSlope(src_width, src_height, dst_width, dst_height, filtering,
&dx, &dy, &x, &y);
if (clip_x) {
x += clip_x * dx;
dst += clip_x * 4;
......
......@@ -534,7 +534,7 @@ void ScalePlaneVertical(int src_height,
}
}
// Scale plane vertically with bilinear interpolation.
// Simplify the filtering based on scale factors.
FilterMode ScaleFilterReduce(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode filtering) {
......@@ -575,6 +575,73 @@ FilterMode ScaleFilterReduce(int src_width, int src_height,
return filtering;
}
#define CENTERSTART(dx, s) (dx < 0) ? -((-dx >> 1) + s) : ((dx >> 1) + s)
#define FIXEDDIV1(src, dst) FixedDiv((src << 16) - 0x00010001, \
(dst << 16) - 0x00010001);
// Compute slope values for stepping.
void ScaleSlope(int src_width, int src_height,
int dst_width, int src_height,
FilterMode filtering,
int* x, int* y, int* dx, int* dy) {
assert(x != NULL);
assert(y != NULL);
assert(dx != NULL);
assert(dy != NULL);
assert(src_width != 0);
assert(src_height != 0);
assert(dst_width > 0);
assert(dst_height > 0);
if (filtering == kFilterBox) {
// Scale step for point sampling duplicates all pixels equally.
*dx = FixedDiv(Abs(src_width), dst_width);
*dy = FixedDiv(src_height, dst_height);
*x = 0;
*y = 0;
} else if (filtering == kFilterBilinear) {
// Scale step for bilinear sampling renders last pixel once for upsample.
if (dst_width <= Abs(src_width)) {
*dx = FixedDiv(Abs(src_width), dst_width);
*x = CENTERSTART(*dx, -32768);
} else if (dst_width > 1) {
*dx = FIXEDDIV1(Abs(src_width), dst_width);
*x = 0;
}
if (dst_height <= src_height) {
*dy = FixedDiv(src_height, dst_height);
*y = CENTERSTART(*dy, -32768);
} else if (dst_height > 1) {
*dy = FIXEDDIV1(src_height, dst_height);
*y = 0;
}
} else if (filtering == kFilterLinear) {
// Scale step for bilinear sampling renders last pixel once for upsample.
if (dst_width <= Abs(src_width)) {
*dx = FixedDiv(Abs(src_width), dst_width);
*x = CENTERSTART(*dx, -32768);
} else if (dst_width > 1) {
*dx = FIXEDDIV1(Abs(src_width), dst_width);
*x = 0;
}
*dy = FixedDiv(src_height, dst_height);
*y = *dy >> 1;
} else {
// Scale step for point sampling duplicates all pixels equally.
*dx = FixedDiv(Abs(src_width), dst_width);
*dy = FixedDiv(src_height, dst_height);
*x = CENTERSTART(*dx, 0);
*y = CENTERSTART(*dy, 0);
}
// Negative src_width means horizontally mirror.
if (src_width < 0) {
*x += (dst_width - 1) * dx;
*dx = -*dx;
src_width = -src_width;
}
}
#undef CENTERSTART
#undef FIXEDDIV1
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
......
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