aboutsummaryrefslogtreecommitdiff
path: root/source/scale_argb.cc
diff options
context:
space:
mode:
authorWan-Teh Chang <wtc@google.com>2023-11-03 14:23:15 -0700
committerlibyuv LUCI CQ <libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-11-03 23:53:24 +0000
commitfb6341d326846fbbe669ad5173e520f66b339621 (patch)
treebcc580080b85f58ca751fae121e99bcef148ac64 /source/scale_argb.cc
parent31e1d6f896615342d5d5b6bde8f7b50b3fd698dc (diff)
downloadlibyuv-fb6341d326846fbbe669ad5173e520f66b339621.tar.gz
Change ScalePlane,ScalePlane_16,... to return int
Change ScalePlane(), ScalePlane_16(), and ScalePlane_12() to return int so that they can report memory allocation failures (by returning 1). BUG=libyuv:968 Change-Id: Ie5c183ee42e3d595302671f9ecb7b3472dc8fdb5 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/5005031 Commit-Queue: Wan-Teh Chang <wtc@google.com> Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Diffstat (limited to 'source/scale_argb.cc')
-rw-r--r--source/scale_argb.cc199
1 files changed, 103 insertions, 96 deletions
diff --git a/source/scale_argb.cc b/source/scale_argb.cc
index fa35b0c9..65d0c892 100644
--- a/source/scale_argb.cc
+++ b/source/scale_argb.cc
@@ -151,23 +151,26 @@ static void ScaleARGBDown2(int src_width,
// ScaleARGB ARGB, 1/4
// This is an optimized version for scaling down a ARGB to 1/4 of
// its original size.
-static void ScaleARGBDown4Box(int src_width,
- int src_height,
- int dst_width,
- int dst_height,
- int src_stride,
- int dst_stride,
- const uint8_t* src_argb,
- uint8_t* dst_argb,
- int x,
- int dx,
- int y,
- int dy) {
+static int ScaleARGBDown4Box(int src_width,
+ int src_height,
+ int dst_width,
+ int dst_height,
+ int src_stride,
+ int dst_stride,
+ const uint8_t* src_argb,
+ uint8_t* dst_argb,
+ int x,
+ int dx,
+ int y,
+ int dy) {
int j;
// Allocate 2 rows of ARGB.
const int row_size = (dst_width * 2 * 4 + 31) & ~31;
+ // TODO(fbarchard): Remove this row buffer and implement a ScaleARGBRowDown4
+ // but implemented via a 2 pass wrapper that uses a very small array on the
+ // stack with a horizontal loop.
align_buffer_64(row, row_size * 2);
- if (!row) return;
+ if (!row) return 1;
int row_stride = src_stride * (dy >> 16);
void (*ScaleARGBRowDown2)(const uint8_t* src_argb, ptrdiff_t src_stride,
uint8_t* dst_argb, int dst_width) =
@@ -210,6 +213,7 @@ static void ScaleARGBDown4Box(int src_width,
dst_argb += dst_stride;
}
free_aligned_buffer_64(row);
+ return 0;
}
// ScaleARGB ARGB Even
@@ -297,19 +301,19 @@ static void ScaleARGBDownEven(int src_width,
}
// Scale ARGB down with bilinear interpolation.
-static void ScaleARGBBilinearDown(int src_width,
- int src_height,
- int dst_width,
- int dst_height,
- int src_stride,
- int dst_stride,
- const uint8_t* src_argb,
- uint8_t* dst_argb,
- int x,
- int dx,
- int y,
- int dy,
- enum FilterMode filtering) {
+static int ScaleARGBBilinearDown(int src_width,
+ int src_height,
+ int dst_width,
+ int dst_height,
+ int src_stride,
+ int dst_stride,
+ const uint8_t* src_argb,
+ uint8_t* dst_argb,
+ int x,
+ int dx,
+ int y,
+ int dy,
+ enum FilterMode filtering) {
int j;
void (*InterpolateRow)(uint8_t* dst_argb, const uint8_t* src_argb,
ptrdiff_t src_stride, int dst_width,
@@ -408,7 +412,7 @@ static void ScaleARGBBilinearDown(int src_width,
// Allocate a row of ARGB.
{
align_buffer_64(row, clip_src_width * 4);
- if (!row) return;
+ if (!row) return 1;
const int max_y = (src_height - 1) << 16;
if (y > max_y) {
@@ -432,22 +436,23 @@ static void ScaleARGBBilinearDown(int src_width,
}
free_aligned_buffer_64(row);
}
+ return 0;
}
// Scale ARGB up with bilinear interpolation.
-static void ScaleARGBBilinearUp(int src_width,
- int src_height,
- int dst_width,
- int dst_height,
- int src_stride,
- int dst_stride,
- const uint8_t* src_argb,
- uint8_t* dst_argb,
- int x,
- int dx,
- int y,
- int dy,
- enum FilterMode filtering) {
+static int ScaleARGBBilinearUp(int src_width,
+ int src_height,
+ int dst_width,
+ int dst_height,
+ int src_stride,
+ int dst_stride,
+ const uint8_t* src_argb,
+ uint8_t* dst_argb,
+ int x,
+ int dx,
+ int y,
+ int dy,
+ enum FilterMode filtering) {
int j;
void (*InterpolateRow)(uint8_t* dst_argb, const uint8_t* src_argb,
ptrdiff_t src_stride, int dst_width,
@@ -583,7 +588,7 @@ static void ScaleARGBBilinearUp(int src_width,
// Allocate 2 rows of ARGB.
const int row_size = (dst_width * 4 + 31) & ~31;
align_buffer_64(row, row_size * 2);
- if (!row) return;
+ if (!row) return 1;
uint8_t* rowptr = row;
int rowstride = row_size;
@@ -627,27 +632,28 @@ static void ScaleARGBBilinearUp(int src_width,
}
free_aligned_buffer_64(row);
}
+ return 0;
}
#ifdef YUVSCALEUP
// Scale YUV to ARGB up with bilinear interpolation.
-static void ScaleYUVToARGBBilinearUp(int src_width,
- int src_height,
- int dst_width,
- int dst_height,
- int src_stride_y,
- int src_stride_u,
- int src_stride_v,
- int dst_stride_argb,
- const uint8_t* src_y,
- const uint8_t* src_u,
- const uint8_t* src_v,
- uint8_t* dst_argb,
- int x,
- int dx,
- int y,
- int dy,
- enum FilterMode filtering) {
+static int ScaleYUVToARGBBilinearUp(int src_width,
+ int src_height,
+ int dst_width,
+ int dst_height,
+ int src_stride_y,
+ int src_stride_u,
+ int src_stride_v,
+ int dst_stride_argb,
+ const uint8_t* src_y,
+ const uint8_t* src_u,
+ const uint8_t* src_v,
+ uint8_t* dst_argb,
+ int x,
+ int dx,
+ int y,
+ int dy,
+ enum FilterMode filtering) {
int j;
void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf,
const uint8_t* v_buf, uint8_t* rgb_buf, int width) =
@@ -852,11 +858,14 @@ static void ScaleYUVToARGBBilinearUp(int src_width,
// Allocate 2 rows of ARGB.
const int row_size = (dst_width * 4 + 31) & ~31;
align_buffer_64(row, row_size * 2);
- if (!row) return;
+ if (!row) return 1;
// Allocate 1 row of ARGB for source conversion.
align_buffer_64(argb_row, src_width * 4);
- if (!argb_row) return;
+ if (!argb_row) {
+ free_aligned_buffer_64(row);
+ return 1;
+ }
uint8_t* rowptr = row;
int rowstride = row_size;
@@ -916,6 +925,7 @@ static void ScaleYUVToARGBBilinearUp(int src_width,
}
free_aligned_buffer_64(row);
free_aligned_buffer_64(row_argb);
+ return 0;
}
#endif
@@ -990,19 +1000,19 @@ static void ScaleARGBSimple(int src_width,
// ScaleARGB a ARGB.
// This function in turn calls a scaling function
// suitable for handling the desired resolutions.
-static void ScaleARGB(const uint8_t* src,
- int src_stride,
- int src_width,
- int src_height,
- uint8_t* dst,
- int dst_stride,
- int dst_width,
- int dst_height,
- int clip_x,
- int clip_y,
- int clip_width,
- int clip_height,
- enum FilterMode filtering) {
+static int ScaleARGB(const uint8_t* src,
+ int src_stride,
+ int src_width,
+ int src_height,
+ uint8_t* dst,
+ int dst_stride,
+ int dst_width,
+ int dst_height,
+ int clip_x,
+ int clip_y,
+ int clip_width,
+ int clip_height,
+ enum FilterMode filtering) {
// Initial source x/y coordinate and step values as 16.16 fixed point.
int x = 0;
int y = 0;
@@ -1047,18 +1057,18 @@ static void ScaleARGB(const uint8_t* src,
ScaleARGBDown2(src_width, src_height, clip_width, clip_height,
src_stride, dst_stride, src, dst, x, dx, y, dy,
filtering);
- return;
+ return 0;
}
if (dx == 0x40000 && filtering == kFilterBox) {
// Optimized 1/4 box downsample.
- ScaleARGBDown4Box(src_width, src_height, clip_width, clip_height,
- src_stride, dst_stride, src, dst, x, dx, y, dy);
- return;
+ return ScaleARGBDown4Box(src_width, src_height, clip_width,
+ clip_height, src_stride, dst_stride, src,
+ dst, x, dx, y, dy);
}
ScaleARGBDownEven(src_width, src_height, clip_width, clip_height,
src_stride, dst_stride, src, dst, x, dx, y, dy,
filtering);
- return;
+ return 0;
}
// Optimized odd scale down. ie 3, 5, 7, 9x.
if ((dx & 0x10000) && (dy & 0x10000)) {
@@ -1067,7 +1077,7 @@ static void ScaleARGB(const uint8_t* src,
// Straight copy.
ARGBCopy(src + (y >> 16) * (intptr_t)src_stride + (x >> 16) * 4,
src_stride, dst, dst_stride, clip_width, clip_height);
- return;
+ return 0;
}
}
}
@@ -1076,22 +1086,21 @@ static void ScaleARGB(const uint8_t* src,
// Arbitrary scale vertically, but unscaled horizontally.
ScalePlaneVertical(src_height, clip_width, clip_height, src_stride,
dst_stride, src, dst, x, y, dy, /*bpp=*/4, filtering);
- return;
+ return 0;
}
if (filtering && dy < 65536) {
- ScaleARGBBilinearUp(src_width, src_height, clip_width, clip_height,
- src_stride, dst_stride, src, dst, x, dx, y, dy,
- filtering);
- return;
+ return ScaleARGBBilinearUp(src_width, src_height, clip_width, clip_height,
+ src_stride, dst_stride, src, dst, x, dx, y, dy,
+ filtering);
}
if (filtering) {
- ScaleARGBBilinearDown(src_width, src_height, clip_width, clip_height,
- src_stride, dst_stride, src, dst, x, dx, y, dy,
- filtering);
- return;
+ return ScaleARGBBilinearDown(src_width, src_height, clip_width, clip_height,
+ src_stride, dst_stride, src, dst, x, dx, y, dy,
+ filtering);
}
ScaleARGBSimple(src_width, src_height, clip_width, clip_height, src_stride,
dst_stride, src, dst, x, dx, y, dy);
+ return 0;
}
LIBYUV_API
@@ -1115,10 +1124,9 @@ int ARGBScaleClip(const uint8_t* src_argb,
(clip_y + clip_height) > dst_height) {
return -1;
}
- ScaleARGB(src_argb, src_stride_argb, src_width, src_height, dst_argb,
- dst_stride_argb, dst_width, dst_height, clip_x, clip_y, clip_width,
- clip_height, filtering);
- return 0;
+ return ScaleARGB(src_argb, src_stride_argb, src_width, src_height, dst_argb,
+ dst_stride_argb, dst_width, dst_height, clip_x, clip_y,
+ clip_width, clip_height, filtering);
}
// Scale an ARGB image.
@@ -1136,10 +1144,9 @@ int ARGBScale(const uint8_t* src_argb,
src_height > 32768 || !dst_argb || dst_width <= 0 || dst_height <= 0) {
return -1;
}
- ScaleARGB(src_argb, src_stride_argb, src_width, src_height, dst_argb,
- dst_stride_argb, dst_width, dst_height, 0, 0, dst_width, dst_height,
- filtering);
- return 0;
+ return ScaleARGB(src_argb, src_stride_argb, src_width, src_height, dst_argb,
+ dst_stride_argb, dst_width, dst_height, 0, 0, dst_width,
+ dst_height, filtering);
}
// Scale with YUV conversion to ARGB and clipping.