mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-10-28 18:07:12 +08:00
Scale*BilinearUp: Add invariants assertions and simplify loop
In ScaleARGBBilinearUp, ScalePlaneBilinearUp, ScalePlaneBilinearUp_16, and ScaleUVBilinearUp, dy is strictly < 65536 (dy < 1.0 in 16.16 fixed point), so yi (y >> 16) advances strictly in unit increments (0 -> 1 -> 2 -> ... -> H - 1). Because yi transitions across each integer row in sequence: - src is primed at row 2 and incrementally advanced by 1 row on each integer transition while (y + 65536) < max_y. - When y >= max_y - 65536, src increments stop, leaving src pointing to the final row (H - 1). - Therefore, src is always pointing to row yi + 1 before each buffer swap, making the inner 'src = src_ptr + yi * src_stride' recomputation and nested 'if (yi != lasty)' checks redundant. Bug: 540206290, 539110937 Test: LibYUVScaleTest.* Change-Id: Ic5cc5c601d4771e9df8b9a882df2f7f3e6777b23 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8252878 Commit-Queue: Dale Curtis <dalecurtis@chromium.org> Reviewed-by: Frank Barchard <fbarchard@google.com> Reviewed-by: Wan-Teh Chang <wtc@google.com>
This commit is contained in:
parent
2e58f4b971
commit
3f42e3840b
@ -1219,6 +1219,11 @@ static int ScalePlaneBilinearUp(int src_width,
|
||||
const uint8_t* src_ptr,
|
||||
uint8_t* dst_ptr,
|
||||
enum FilterMode filtering) {
|
||||
assert(src_width > 0);
|
||||
assert(src_height > 0);
|
||||
assert(dst_width > 0);
|
||||
assert(dst_height > 0);
|
||||
|
||||
int j;
|
||||
// Initial source x/y coordinate and step values as 16.16 fixed point.
|
||||
int x = 0;
|
||||
@ -1234,6 +1239,7 @@ static int ScalePlaneBilinearUp(int src_width,
|
||||
filtering ? ScaleFilterCols_C : ScaleCols_C;
|
||||
ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y,
|
||||
&dx, &dy);
|
||||
assert(dy <= 65536);
|
||||
src_width = Abs(src_width);
|
||||
|
||||
#if defined(HAS_INTERPOLATEROW_AVX2)
|
||||
@ -1327,22 +1333,27 @@ static int ScalePlaneBilinearUp(int src_width,
|
||||
src += src_stride;
|
||||
}
|
||||
|
||||
// 2-row rolling buffer:
|
||||
// rowptr and (rowptr + rowstride) hold the scaled rows for yi and yi + 1.
|
||||
// Because dy <= 65536 (dy <= 1.0 in 16.16), yi advances in unit steps.
|
||||
// When yi != lasty:
|
||||
// 1. Scale the next source row into the older buffer (rowptr).
|
||||
// 2. Swap buffer pointers (rowptr += rowstride; rowstride = -rowstride;)
|
||||
// so rowptr points to yi and (rowptr + rowstride) points to yi + 1.
|
||||
// 3. Advance src by 1 row if row yi + 2 exists ((y + 65536) < max_y),
|
||||
// otherwise clamp src at (src_height - 1) to avoid reading out of bounds.
|
||||
for (j = 0; j < dst_height; ++j) {
|
||||
if (y > max_y) {
|
||||
y = max_y;
|
||||
}
|
||||
yi = y >> 16;
|
||||
if (yi != lasty) {
|
||||
if (y > max_y) {
|
||||
y = max_y;
|
||||
yi = y >> 16;
|
||||
src = src_ptr + yi * src_stride;
|
||||
}
|
||||
if (yi != lasty) {
|
||||
ScaleFilterCols(rowptr, src, dst_width, x, dx);
|
||||
rowptr += rowstride;
|
||||
rowstride = -rowstride;
|
||||
lasty = yi;
|
||||
if ((y + 65536) < max_y) {
|
||||
src += src_stride;
|
||||
}
|
||||
ScaleFilterCols(rowptr, src, dst_width, x, dx);
|
||||
rowptr += rowstride;
|
||||
rowstride = -rowstride;
|
||||
lasty = yi;
|
||||
if ((y + 65536) < max_y) {
|
||||
src += src_stride;
|
||||
}
|
||||
}
|
||||
if (filtering == kFilterLinear) {
|
||||
@ -1705,6 +1716,11 @@ static int ScalePlaneBilinearUp_16(int src_width,
|
||||
const uint16_t* src_ptr,
|
||||
uint16_t* dst_ptr,
|
||||
enum FilterMode filtering) {
|
||||
assert(src_width > 0);
|
||||
assert(src_height > 0);
|
||||
assert(dst_width > 0);
|
||||
assert(dst_height > 0);
|
||||
|
||||
int j;
|
||||
// Initial source x/y coordinate and step values as 16.16 fixed point.
|
||||
int x = 0;
|
||||
@ -1720,6 +1736,7 @@ static int ScalePlaneBilinearUp_16(int src_width,
|
||||
filtering ? ScaleFilterCols_16_C : ScaleCols_16_C;
|
||||
ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y,
|
||||
&dx, &dy);
|
||||
assert(dy <= 65536);
|
||||
src_width = Abs(src_width);
|
||||
|
||||
#if defined(HAS_INTERPOLATEROW_16_SSSE3)
|
||||
@ -1768,6 +1785,7 @@ static int ScalePlaneBilinearUp_16(int src_width,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (y > max_y) {
|
||||
y = max_y;
|
||||
}
|
||||
@ -1793,22 +1811,27 @@ static int ScalePlaneBilinearUp_16(int src_width,
|
||||
src += src_stride;
|
||||
}
|
||||
|
||||
// 2-row rolling buffer:
|
||||
// rowptr and (rowptr + rowstride) hold the scaled rows for yi and yi + 1.
|
||||
// Because dy <= 65536 (dy <= 1.0 in 16.16), yi advances in unit steps.
|
||||
// When yi != lasty:
|
||||
// 1. Scale the next source row into the older buffer (rowptr).
|
||||
// 2. Swap buffer pointers (rowptr += rowstride; rowstride = -rowstride;)
|
||||
// so rowptr points to yi and (rowptr + rowstride) points to yi + 1.
|
||||
// 3. Advance src by 1 row if row yi + 2 exists ((y + 65536) < max_y),
|
||||
// otherwise clamp src at (src_height - 1) to avoid reading out of bounds.
|
||||
for (j = 0; j < dst_height; ++j) {
|
||||
if (y > max_y) {
|
||||
y = max_y;
|
||||
}
|
||||
yi = y >> 16;
|
||||
if (yi != lasty) {
|
||||
if (y > max_y) {
|
||||
y = max_y;
|
||||
yi = y >> 16;
|
||||
src = src_ptr + yi * src_stride;
|
||||
}
|
||||
if (yi != lasty) {
|
||||
ScaleFilterCols(rowptr, src, dst_width, x, dx);
|
||||
rowptr += rowstride;
|
||||
rowstride = -rowstride;
|
||||
lasty = yi;
|
||||
if ((y + 65536) < max_y) {
|
||||
src += src_stride;
|
||||
}
|
||||
ScaleFilterCols(rowptr, src, dst_width, x, dx);
|
||||
rowptr += rowstride;
|
||||
rowstride = -rowstride;
|
||||
lasty = yi;
|
||||
if ((y + 65536) < max_y) {
|
||||
src += src_stride;
|
||||
}
|
||||
}
|
||||
if (filtering == kFilterLinear) {
|
||||
|
||||
@ -441,6 +441,12 @@ static int ScaleARGBBilinearUp(int src_width,
|
||||
int y,
|
||||
int dy,
|
||||
enum FilterMode filtering) {
|
||||
assert(src_width > 0);
|
||||
assert(src_height > 0);
|
||||
assert(dst_width > 0);
|
||||
assert(dst_height > 0);
|
||||
assert(dy <= 65536);
|
||||
|
||||
int j;
|
||||
void (*InterpolateRow)(uint8_t* dst_argb, const uint8_t* src_argb,
|
||||
ptrdiff_t src_stride, int dst_width,
|
||||
@ -576,6 +582,15 @@ static int ScaleARGBBilinearUp(int src_width,
|
||||
src += src_stride;
|
||||
}
|
||||
|
||||
// 2-row rolling buffer:
|
||||
// rowptr and (rowptr + rowstride) hold the scaled rows for yi and yi + 1.
|
||||
// Because dy <= 65536 (dy <= 1.0 in 16.16), yi advances in unit steps.
|
||||
// When yi != lasty:
|
||||
// 1. Scale the next source row into the older buffer (rowptr).
|
||||
// 2. Swap buffer pointers (rowptr += rowstride; rowstride = -rowstride;)
|
||||
// so rowptr points to yi and (rowptr + rowstride) points to yi + 1.
|
||||
// 3. Advance src by 1 row if row yi + 2 exists ((y64 + 65536) < max_y),
|
||||
// otherwise clamp src at (src_height - 1) to avoid reading out of bounds.
|
||||
for (j = 0; j < dst_height; ++j) {
|
||||
if (y64 > max_y) {
|
||||
y64 = max_y;
|
||||
|
||||
@ -463,6 +463,12 @@ static int ScaleUVBilinearUp(int src_width,
|
||||
int y,
|
||||
int dy,
|
||||
enum FilterMode filtering) {
|
||||
assert(src_width > 0);
|
||||
assert(src_height > 0);
|
||||
assert(dst_width > 0);
|
||||
assert(dst_height > 0);
|
||||
assert(dy <= 65536);
|
||||
|
||||
int j;
|
||||
void (*InterpolateRow)(uint8_t* dst_uv, const uint8_t* src_uv,
|
||||
ptrdiff_t src_stride, int dst_width,
|
||||
@ -575,22 +581,27 @@ static int ScaleUVBilinearUp(int src_width,
|
||||
src += src_stride;
|
||||
}
|
||||
|
||||
// 2-row rolling buffer:
|
||||
// rowptr and (rowptr + rowstride) hold the scaled rows for yi and yi + 1.
|
||||
// Because dy <= 65536 (dy <= 1.0 in 16.16), yi advances in unit steps.
|
||||
// When yi != lasty:
|
||||
// 1. Scale the next source row into the older buffer (rowptr).
|
||||
// 2. Swap buffer pointers (rowptr += rowstride; rowstride = -rowstride;)
|
||||
// so rowptr points to yi and (rowptr + rowstride) points to yi + 1.
|
||||
// 3. Advance src by 1 row if row yi + 2 exists ((y + 65536) < max_y),
|
||||
// otherwise clamp src at (src_height - 1) to avoid reading out of bounds.
|
||||
for (j = 0; j < dst_height; ++j) {
|
||||
if (y > max_y) {
|
||||
y = max_y;
|
||||
}
|
||||
yi = y >> 16;
|
||||
if (yi != lasty) {
|
||||
if (y > max_y) {
|
||||
y = max_y;
|
||||
yi = y >> 16;
|
||||
src = src_uv + yi * src_stride;
|
||||
}
|
||||
if (yi != lasty) {
|
||||
ScaleUVFilterCols(rowptr, src, dst_width, x, dx);
|
||||
rowptr += rowstride;
|
||||
rowstride = -rowstride;
|
||||
lasty = yi;
|
||||
if ((y + 65536) < max_y) {
|
||||
src += src_stride;
|
||||
}
|
||||
ScaleUVFilterCols(rowptr, src, dst_width, x, dx);
|
||||
rowptr += rowstride;
|
||||
rowstride = -rowstride;
|
||||
lasty = yi;
|
||||
if ((y + 65536) < max_y) {
|
||||
src += src_stride;
|
||||
}
|
||||
}
|
||||
if (filtering == kFilterLinear) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user