From fb6341d326846fbbe669ad5173e520f66b339621 Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Fri, 3 Nov 2023 14:23:15 -0700 Subject: 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 Reviewed-by: Frank Barchard --- README.chromium | 2 +- include/libyuv/scale.h | 55 +++--- include/libyuv/version.h | 2 +- source/convert.cc | 102 +++++++---- source/convert_from.cc | 90 ++++++---- source/rotate.cc | 58 ++++-- source/scale.cc | 455 +++++++++++++++++++++++++++-------------------- source/scale_argb.cc | 199 +++++++++++---------- source/scale_uv.cc | 150 ++++++++-------- 9 files changed, 640 insertions(+), 473 deletions(-) diff --git a/README.chromium b/README.chromium index 1c41d7d0..92fc2f84 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: https://chromium.googlesource.com/libyuv/libyuv/ -Version: 1879 +Version: 1880 License: BSD License File: LICENSE Shipped: yes diff --git a/include/libyuv/scale.h b/include/libyuv/scale.h index 443f89c2..bfe4a344 100644 --- a/include/libyuv/scale.h +++ b/include/libyuv/scale.h @@ -27,39 +27,40 @@ typedef enum FilterMode { } FilterModeEnum; // Scale a YUV plane. +// Returns 0 if successful. LIBYUV_API -void ScalePlane(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, - enum FilterMode filtering); +int ScalePlane(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, + enum FilterMode filtering); LIBYUV_API -void ScalePlane_16(const uint16_t* src, - int src_stride, - int src_width, - int src_height, - uint16_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering); +int ScalePlane_16(const uint16_t* src, + int src_stride, + int src_width, + int src_height, + uint16_t* dst, + int dst_stride, + int dst_width, + int dst_height, + enum FilterMode filtering); // Sample is expected to be in the low 12 bits. LIBYUV_API -void ScalePlane_12(const uint16_t* src, - int src_stride, - int src_width, - int src_height, - uint16_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering); +int ScalePlane_12(const uint16_t* src, + int src_stride, + int src_width, + int src_height, + uint16_t* dst, + int dst_stride, + int dst_width, + int dst_height, + enum FilterMode filtering); // Scales a YUV 4:2:0 image from the src width and height to the // dst width and height. diff --git a/include/libyuv/version.h b/include/libyuv/version.h index 569cb49b..bcea000d 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1879 +#define LIBYUV_VERSION 1880 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/source/convert.cc b/source/convert.cc index 0f48572d..5f779a81 100644 --- a/source/convert.cc +++ b/source/convert.cc @@ -54,18 +54,25 @@ static int I4xxToI420(const uint8_t* src_y, const int dst_y_height = Abs(src_y_height); const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); + int r; if (src_uv_width <= 0 || src_uv_height == 0) { return -1; } if (dst_y) { - ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y, - dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear); + r = ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y, + dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear); + if (r != 0) { + return r; + } } - ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, - dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); - ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, - dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); - return 0; + r = ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, + dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); + if (r != 0) { + return r; + } + r = ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, + dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); + return r; } // Copy I420 with optional flipping. @@ -526,18 +533,25 @@ static int Ix10ToI010(const uint16_t* src_y, const int src_uv_height = SUBSAMPLE(height, subsample_y, subsample_y); const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); + int r; if (width <= 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane_12(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - dst_y_width, dst_y_height, kFilterBilinear); + r = ScalePlane_12(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + dst_y_width, dst_y_height, kFilterBilinear); + if (r != 0) { + return r; + } } - ScalePlane_12(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, - dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); - ScalePlane_12(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, - dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); - return 0; + r = ScalePlane_12(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, + dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, + dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); + return r; } LIBYUV_API @@ -1333,18 +1347,22 @@ int NV12ToNV24(const uint8_t* src_y, int dst_stride_uv, int width, int height) { + int r; if (width <= 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - Abs(width), Abs(height), kFilterBilinear); + r = ScalePlane(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } } - UVScale(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), - SUBSAMPLE(height, 1, 1), dst_uv, dst_stride_uv, Abs(width), - Abs(height), kFilterBilinear); - return 0; + r = UVScale(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), + SUBSAMPLE(height, 1, 1), dst_uv, dst_stride_uv, Abs(width), + Abs(height), kFilterBilinear); + return r; } LIBYUV_API @@ -1358,17 +1376,21 @@ int NV16ToNV24(const uint8_t* src_y, int dst_stride_uv, int width, int height) { + int r; if (width <= 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - Abs(width), Abs(height), kFilterBilinear); + r = ScalePlane(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } } - UVScale(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), height, dst_uv, - dst_stride_uv, Abs(width), Abs(height), kFilterBilinear); - return 0; + r = UVScale(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), height, dst_uv, + dst_stride_uv, Abs(width), Abs(height), kFilterBilinear); + return r; } // Any P[420]1[02] to I[420]1[02] format with mirroring. @@ -1446,18 +1468,22 @@ int P010ToP410(const uint16_t* src_y, int dst_stride_uv, int width, int height) { + int r; if (width <= 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane_16(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - Abs(width), Abs(height), kFilterBilinear); + r = ScalePlane_16(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } } - UVScale_16(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), - SUBSAMPLE(height, 1, 1), dst_uv, dst_stride_uv, Abs(width), - Abs(height), kFilterBilinear); - return 0; + r = UVScale_16(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), + SUBSAMPLE(height, 1, 1), dst_uv, dst_stride_uv, Abs(width), + Abs(height), kFilterBilinear); + return r; } LIBYUV_API @@ -1471,17 +1497,21 @@ int P210ToP410(const uint16_t* src_y, int dst_stride_uv, int width, int height) { + int r; if (width <= 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane_16(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - Abs(width), Abs(height), kFilterBilinear); + r = ScalePlane_16(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } } - UVScale_16(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), height, dst_uv, - dst_stride_uv, Abs(width), Abs(height), kFilterBilinear); - return 0; + r = UVScale_16(src_uv, src_stride_uv, SUBSAMPLE(width, 1, 1), height, dst_uv, + dst_stride_uv, Abs(width), Abs(height), kFilterBilinear); + return r; } // Convert YUY2 to I420. diff --git a/source/convert_from.cc b/source/convert_from.cc index 4102d610..e69da9e9 100644 --- a/source/convert_from.cc +++ b/source/convert_from.cc @@ -52,19 +52,26 @@ static int I420ToI4xx(const uint8_t* src_y, const int dst_y_height = Abs(src_y_height); const int src_uv_width = SUBSAMPLE(src_y_width, 1, 1); const int src_uv_height = SUBSAMPLE(src_y_height, 1, 1); + int r; if (src_y_width == 0 || src_y_height == 0 || dst_uv_width <= 0 || dst_uv_height <= 0) { return -1; } if (dst_y) { - ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y, - dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear); + r = ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y, + dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear); + if (r != 0) { + return r; + } } - ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, - dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); - ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, - dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); - return 0; + r = ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, + dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); + if (r != 0) { + return r; + } + r = ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, + dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); + return r; } // Convert 8 bit YUV to 10 bit. @@ -223,21 +230,28 @@ int I010ToI410(const uint16_t* src_y, int dst_stride_v, int width, int height) { + int r; if (width == 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane_12(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - Abs(width), Abs(height), kFilterBilinear); - } - ScalePlane_12(src_u, src_stride_u, SUBSAMPLE(width, 1, 1), - SUBSAMPLE(height, 1, 1), dst_u, dst_stride_u, Abs(width), - Abs(height), kFilterBilinear); - ScalePlane_12(src_v, src_stride_v, SUBSAMPLE(width, 1, 1), - SUBSAMPLE(height, 1, 1), dst_v, dst_stride_v, Abs(width), - Abs(height), kFilterBilinear); - return 0; + r = ScalePlane_12(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } + } + r = ScalePlane_12(src_u, src_stride_u, SUBSAMPLE(width, 1, 1), + SUBSAMPLE(height, 1, 1), dst_u, dst_stride_u, Abs(width), + Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_v, src_stride_v, SUBSAMPLE(width, 1, 1), + SUBSAMPLE(height, 1, 1), dst_v, dst_stride_v, Abs(width), + Abs(height), kFilterBilinear); + return r; } // 422 chroma to 444 chroma, 10/12 bit version @@ -256,19 +270,26 @@ int I210ToI410(const uint16_t* src_y, int dst_stride_v, int width, int height) { + int r; if (width == 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane_12(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - Abs(width), Abs(height), kFilterBilinear); + r = ScalePlane_12(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } } - ScalePlane_12(src_u, src_stride_u, SUBSAMPLE(width, 1, 1), height, dst_u, - dst_stride_u, Abs(width), Abs(height), kFilterBilinear); - ScalePlane_12(src_v, src_stride_v, SUBSAMPLE(width, 1, 1), height, dst_v, - dst_stride_v, Abs(width), Abs(height), kFilterBilinear); - return 0; + r = ScalePlane_12(src_u, src_stride_u, SUBSAMPLE(width, 1, 1), height, dst_u, + dst_stride_u, Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_v, src_stride_v, SUBSAMPLE(width, 1, 1), height, dst_v, + dst_stride_v, Abs(width), Abs(height), kFilterBilinear); + return r; } // 422 chroma is 1/2 width, 1x height @@ -288,19 +309,26 @@ int I422ToI444(const uint8_t* src_y, int dst_stride_v, int width, int height) { + int r; if (width == 0 || height == 0) { return -1; } if (dst_y) { - ScalePlane(src_y, src_stride_y, width, height, dst_y, dst_stride_y, - Abs(width), Abs(height), kFilterBilinear); + r = ScalePlane(src_y, src_stride_y, width, height, dst_y, dst_stride_y, + Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } } - ScalePlane(src_u, src_stride_u, SUBSAMPLE(width, 1, 1), height, dst_u, - dst_stride_u, Abs(width), Abs(height), kFilterBilinear); - ScalePlane(src_v, src_stride_v, SUBSAMPLE(width, 1, 1), height, dst_v, - dst_stride_v, Abs(width), Abs(height), kFilterBilinear); - return 0; + r = ScalePlane(src_u, src_stride_u, SUBSAMPLE(width, 1, 1), height, dst_u, + dst_stride_u, Abs(width), Abs(height), kFilterBilinear); + if (r != 0) { + return r; + } + r = ScalePlane(src_v, src_stride_v, SUBSAMPLE(width, 1, 1), height, dst_v, + dst_stride_v, Abs(width), Abs(height), kFilterBilinear); + return r; } // Copy to I400. Source can be I420,422,444,400,NV12,NV21 diff --git a/source/rotate.cc b/source/rotate.cc index 0ee453c1..09ba2106 100644 --- a/source/rotate.cc +++ b/source/rotate.cc @@ -693,6 +693,7 @@ int I422Rotate(const uint8_t* src_y, enum RotationMode mode) { int halfwidth = (width + 1) >> 1; int halfheight = (height + 1) >> 1; + int r; if (!src_y || !src_u || !src_v || width <= 0 || height == 0 || !dst_y || !dst_u || !dst_v) { return -1; @@ -728,23 +729,35 @@ int I422Rotate(const uint8_t* src_y, case kRotate90: RotatePlane90(src_u, src_stride_u, dst_y, dst_stride_y, halfwidth, height); - ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_u, dst_stride_u, - halfheight, width, kFilterBilinear); + r = ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_u, + dst_stride_u, halfheight, width, kFilterBilinear); + if (r != 0) { + return r; + } RotatePlane90(src_v, src_stride_v, dst_y, dst_stride_y, halfwidth, height); - ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_v, dst_stride_v, - halfheight, width, kFilterLinear); + r = ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_v, + dst_stride_v, halfheight, width, kFilterLinear); + if (r != 0) { + return r; + } RotatePlane90(src_y, src_stride_y, dst_y, dst_stride_y, width, height); return 0; case kRotate270: RotatePlane270(src_u, src_stride_u, dst_y, dst_stride_y, halfwidth, height); - ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_u, dst_stride_u, - halfheight, width, kFilterBilinear); + r = ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_u, + dst_stride_u, halfheight, width, kFilterBilinear); + if (r != 0) { + return r; + } RotatePlane270(src_v, src_stride_v, dst_y, dst_stride_y, halfwidth, height); - ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_v, dst_stride_v, - halfheight, width, kFilterLinear); + r = ScalePlane(dst_y, dst_stride_y, height, halfwidth, dst_v, + dst_stride_v, halfheight, width, kFilterLinear); + if (r != 0) { + return r; + } RotatePlane270(src_y, src_stride_y, dst_y, dst_stride_y, width, height); return 0; case kRotate180: @@ -1058,6 +1071,7 @@ int I210Rotate(const uint16_t* src_y, enum RotationMode mode) { int halfwidth = (width + 1) >> 1; int halfheight = (height + 1) >> 1; + int r; if (!src_y || !src_u || !src_v || width <= 0 || height == 0 || !dst_y || !dst_u || !dst_v) { return -1; @@ -1093,23 +1107,35 @@ int I210Rotate(const uint16_t* src_y, case kRotate90: RotatePlane90_16(src_u, src_stride_u, dst_y, dst_stride_y, halfwidth, height); - ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_u, dst_stride_u, - halfheight, width, kFilterBilinear); + r = ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_u, + dst_stride_u, halfheight, width, kFilterBilinear); + if (r != 0) { + return r; + } RotatePlane90_16(src_v, src_stride_v, dst_y, dst_stride_y, halfwidth, height); - ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_v, dst_stride_v, - halfheight, width, kFilterLinear); + r = ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_v, + dst_stride_v, halfheight, width, kFilterLinear); + if (r != 0) { + return r; + } RotatePlane90_16(src_y, src_stride_y, dst_y, dst_stride_y, width, height); return 0; case kRotate270: RotatePlane270_16(src_u, src_stride_u, dst_y, dst_stride_y, halfwidth, height); - ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_u, dst_stride_u, - halfheight, width, kFilterBilinear); + r = ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_u, + dst_stride_u, halfheight, width, kFilterBilinear); + if (r != 0) { + return r; + } RotatePlane270_16(src_v, src_stride_v, dst_y, dst_stride_y, halfwidth, height); - ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_v, dst_stride_v, - halfheight, width, kFilterLinear); + r = ScalePlane_16(dst_y, dst_stride_y, height, halfwidth, dst_v, + dst_stride_v, halfheight, width, kFilterLinear); + if (r != 0) { + return r; + } RotatePlane270_16(src_y, src_stride_y, dst_y, dst_stride_y, width, height); return 0; diff --git a/source/scale.cc b/source/scale.cc index ac6a3bad..b518a39d 100644 --- a/source/scale.cc +++ b/source/scale.cc @@ -939,14 +939,14 @@ static void ScaleAddCols1_16_C(int dst_width, // one pixel of destination using fixed point (16.16) to step // through source, sampling a box of pixel with simple // averaging. -static void ScalePlaneBox(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr) { +static int ScalePlaneBox(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_ptr, + uint8_t* dst_ptr) { int j, k; // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; @@ -960,7 +960,7 @@ static void ScalePlaneBox(int src_width, { // Allocate a row buffer of uint16_t. align_buffer_64(row16, src_width * 2); - if (!row16) return; + if (!row16) return 1; void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, const uint16_t* src_ptr, uint8_t* dst_ptr) = (dx & 0xffff) ? ScaleAddCols2_C @@ -1032,16 +1032,17 @@ static void ScalePlaneBox(int src_width, } free_aligned_buffer_64(row16); } + return 0; } -static void ScalePlaneBox_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr) { +static int ScalePlaneBox_16(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint16_t* src_ptr, + uint16_t* dst_ptr) { int j, k; // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; @@ -1055,7 +1056,7 @@ static void ScalePlaneBox_16(int src_width, { // Allocate a row buffer of uint32_t. align_buffer_64(row32, src_width * 4); - if (!row32) return; + if (!row32) return 1; void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, const uint32_t* src_ptr, uint16_t* dst_ptr) = (dx & 0xffff) ? ScaleAddCols2_16_C : ScaleAddCols1_16_C; @@ -1087,18 +1088,19 @@ static void ScalePlaneBox_16(int src_width, } free_aligned_buffer_64(row32); } + return 0; } // Scale plane down with bilinear interpolation. -static void ScalePlaneBilinearDown(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { +static int ScalePlaneBilinearDown(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_ptr, + uint8_t* dst_ptr, + enum FilterMode filtering) { // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; int y = 0; @@ -1107,7 +1109,7 @@ static void ScalePlaneBilinearDown(int src_width, // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. // Allocate a row buffer. align_buffer_64(row, src_width); - if (!row) return; + if (!row) return 1; const int max_y = (src_height - 1) << 16; int j; @@ -1217,17 +1219,18 @@ static void ScalePlaneBilinearDown(int src_width, } } free_aligned_buffer_64(row); + return 0; } -static void ScalePlaneBilinearDown_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { +static int ScalePlaneBilinearDown_16(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint16_t* src_ptr, + uint16_t* dst_ptr, + enum FilterMode filtering) { // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; int y = 0; @@ -1236,7 +1239,7 @@ static void ScalePlaneBilinearDown_16(int src_width, // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. // Allocate a row buffer. align_buffer_64(row, src_width * 2); - if (!row) return; + if (!row) return 1; const int max_y = (src_height - 1) << 16; int j; @@ -1309,18 +1312,19 @@ static void ScalePlaneBilinearDown_16(int src_width, } } free_aligned_buffer_64(row); + return 0; } // Scale up down with bilinear interpolation. -static void ScalePlaneBilinearUp(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { +static int ScalePlaneBilinearUp(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_ptr, + uint8_t* dst_ptr, + enum FilterMode filtering) { int j; // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; @@ -1419,7 +1423,7 @@ static void ScalePlaneBilinearUp(int src_width, // Allocate 2 row buffers. const int row_size = (dst_width + 31) & ~31; align_buffer_64(row, row_size * 2); - if (!row) return; + if (!row) return 1; uint8_t* rowptr = row; int rowstride = row_size; @@ -1463,6 +1467,7 @@ static void ScalePlaneBilinearUp(int src_width, } free_aligned_buffer_64(row); } + return 0; } // Scale plane, horizontally up by 2 times. @@ -1802,15 +1807,15 @@ static void ScalePlaneUp2_16_Bilinear(int src_width, } } -static void ScalePlaneBilinearUp_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { +static int ScalePlaneBilinearUp_16(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint16_t* src_ptr, + uint16_t* dst_ptr, + enum FilterMode filtering) { int j; // Initial source x/y coordinate and step values as 16.16 fixed point. int x = 0; @@ -1887,7 +1892,7 @@ static void ScalePlaneBilinearUp_16(int src_width, // Allocate 2 row buffers. const int row_size = (dst_width + 31) & ~31; align_buffer_64(row, row_size * 4); - if (!row) return; + if (!row) return 1; uint16_t* rowptr = (uint16_t*)row; int rowstride = row_size; @@ -1931,6 +1936,7 @@ static void ScalePlaneBilinearUp_16(int src_width, } free_aligned_buffer_64(row); } + return 0; } // Scale Plane to/from any dimensions, without interpolation. @@ -2015,15 +2021,15 @@ static void ScalePlaneSimple_16(int src_width, // Scale a plane. // This function dispatches to a specialized scaler based on scale factor. LIBYUV_API -void ScalePlane(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, - enum FilterMode filtering) { +int ScalePlane(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, + enum FilterMode filtering) { // Simplify filtering when possible. filtering = ScaleFilterReduce(src_width, src_height, dst_width, dst_height, filtering); @@ -2039,7 +2045,7 @@ void ScalePlane(const uint8_t* src, if (dst_width == src_width && dst_height == src_height) { // Straight copy. CopyPlane(src, src_stride, dst, dst_stride, dst_width, dst_height); - return; + return 0; } if (dst_width == src_width && filtering != kFilterBox) { int dy = 0; @@ -2055,7 +2061,7 @@ void ScalePlane(const uint8_t* src, // Arbitrary scale vertically, but unscaled horizontally. ScalePlaneVertical(src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, 0, y, dy, /*bpp=*/1, filtering); - return; + return 0; } if (dst_width <= Abs(src_width) && dst_height <= src_height) { // Scale down. @@ -2063,69 +2069,67 @@ void ScalePlane(const uint8_t* src, // optimized, 3/4 ScalePlaneDown34(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } if (2 * dst_width == src_width && 2 * dst_height == src_height) { // optimized, 1/2 ScalePlaneDown2(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } // 3/8 rounded up for odd sized chroma height. if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) { // optimized, 3/8 ScalePlaneDown38(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } if (4 * dst_width == src_width && 4 * dst_height == src_height && (filtering == kFilterBox || filtering == kFilterNone)) { // optimized, 1/4 ScalePlaneDown4(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } } if (filtering == kFilterBox && dst_height * 2 < src_height) { - ScalePlaneBox(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst); - return; + return ScalePlaneBox(src_width, src_height, dst_width, dst_height, + src_stride, dst_stride, src, dst); } if ((dst_width + 1) / 2 == src_width && filtering == kFilterLinear) { ScalePlaneUp2_Linear(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); - return; + return 0; } if ((dst_height + 1) / 2 == src_height && (dst_width + 1) / 2 == src_width && (filtering == kFilterBilinear || filtering == kFilterBox)) { ScalePlaneUp2_Bilinear(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); - return; + return 0; } if (filtering && dst_height > src_height) { - ScalePlaneBilinearUp(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; + return ScalePlaneBilinearUp(src_width, src_height, dst_width, dst_height, + src_stride, dst_stride, src, dst, filtering); } if (filtering) { - ScalePlaneBilinearDown(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; + return ScalePlaneBilinearDown(src_width, src_height, dst_width, dst_height, + src_stride, dst_stride, src, dst, filtering); } ScalePlaneSimple(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); + return 0; } LIBYUV_API -void ScalePlane_16(const uint16_t* src, - int src_stride, - int src_width, - int src_height, - uint16_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering) { +int ScalePlane_16(const uint16_t* src, + int src_stride, + int src_width, + int src_height, + uint16_t* dst, + int dst_stride, + int dst_width, + int dst_height, + enum FilterMode filtering) { // Simplify filtering when possible. filtering = ScaleFilterReduce(src_width, src_height, dst_width, dst_height, filtering); @@ -2141,7 +2145,7 @@ void ScalePlane_16(const uint16_t* src, if (dst_width == src_width && dst_height == src_height) { // Straight copy. CopyPlane_16(src, src_stride, dst, dst_stride, dst_width, dst_height); - return; + return 0; } if (dst_width == src_width && filtering != kFilterBox) { int dy = 0; @@ -2160,7 +2164,7 @@ void ScalePlane_16(const uint16_t* src, // Arbitrary scale vertically, but unscaled horizontally. ScalePlaneVertical_16(src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, 0, y, dy, /*bpp=*/1, filtering); - return; + return 0; } if (dst_width <= Abs(src_width) && dst_height <= src_height) { // Scale down. @@ -2168,69 +2172,68 @@ void ScalePlane_16(const uint16_t* src, // optimized, 3/4 ScalePlaneDown34_16(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } if (2 * dst_width == src_width && 2 * dst_height == src_height) { // optimized, 1/2 ScalePlaneDown2_16(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } // 3/8 rounded up for odd sized chroma height. if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) { // optimized, 3/8 ScalePlaneDown38_16(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } if (4 * dst_width == src_width && 4 * dst_height == src_height && (filtering == kFilterBox || filtering == kFilterNone)) { // optimized, 1/4 ScalePlaneDown4_16(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst, filtering); - return; + return 0; } } if (filtering == kFilterBox && dst_height * 2 < src_height) { - ScalePlaneBox_16(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst); - return; + return ScalePlaneBox_16(src_width, src_height, dst_width, dst_height, + src_stride, dst_stride, src, dst); } if ((dst_width + 1) / 2 == src_width && filtering == kFilterLinear) { ScalePlaneUp2_16_Linear(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); - return; + return 0; } if ((dst_height + 1) / 2 == src_height && (dst_width + 1) / 2 == src_width && (filtering == kFilterBilinear || filtering == kFilterBox)) { ScalePlaneUp2_16_Bilinear(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); - return; + return 0; } if (filtering && dst_height > src_height) { - ScalePlaneBilinearUp_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; + return ScalePlaneBilinearUp_16(src_width, src_height, dst_width, dst_height, + src_stride, dst_stride, src, dst, filtering); } if (filtering) { - ScalePlaneBilinearDown_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; + return ScalePlaneBilinearDown_16(src_width, src_height, dst_width, + dst_height, src_stride, dst_stride, src, + dst, filtering); } ScalePlaneSimple_16(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); + return 0; } LIBYUV_API -void ScalePlane_12(const uint16_t* src, - int src_stride, - int src_width, - int src_height, - uint16_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering) { +int ScalePlane_12(const uint16_t* src, + int src_stride, + int src_width, + int src_height, + uint16_t* dst, + int dst_stride, + int dst_width, + int dst_height, + enum FilterMode filtering) { // Simplify filtering when possible. filtering = ScaleFilterReduce(src_width, src_height, dst_width, dst_height, filtering); @@ -2245,17 +2248,17 @@ void ScalePlane_12(const uint16_t* src, if ((dst_width + 1) / 2 == src_width && filtering == kFilterLinear) { ScalePlaneUp2_12_Linear(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); - return; + return 0; } if ((dst_height + 1) / 2 == src_height && (dst_width + 1) / 2 == src_width && (filtering == kFilterBilinear || filtering == kFilterBox)) { ScalePlaneUp2_12_Bilinear(src_width, src_height, dst_width, dst_height, src_stride, dst_stride, src, dst); - return; + return 0; } - ScalePlane_16(src, src_stride, src_width, src_height, dst, dst_stride, - dst_width, dst_height, filtering); + return ScalePlane_16(src, src_stride, src_width, src_height, dst, dst_stride, + dst_width, dst_height, filtering); } // Scale an I420 image. @@ -2283,6 +2286,7 @@ int I420Scale(const uint8_t* src_y, int src_halfheight = SUBSAMPLE(src_height, 1, 1); int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); + int r; if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || @@ -2290,13 +2294,19 @@ int I420Scale(const uint8_t* src_y, return -1; } - ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, - dst_stride_u, dst_halfwidth, dst_halfheight, filtering); - ScalePlane(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, - dst_stride_v, dst_halfwidth, dst_halfheight, filtering); - return 0; + r = ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, + dst_stride_u, dst_halfwidth, dst_halfheight, filtering); + if (r != 0) { + return r; + } + r = ScalePlane(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, + dst_stride_v, dst_halfwidth, dst_halfheight, filtering); + return r; } LIBYUV_API @@ -2321,6 +2331,7 @@ int I420Scale_16(const uint16_t* src_y, int src_halfheight = SUBSAMPLE(src_height, 1, 1); int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); + int r; if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || @@ -2328,13 +2339,19 @@ int I420Scale_16(const uint16_t* src_y, return -1; } - ScalePlane_16(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane_16(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, - dst_stride_u, dst_halfwidth, dst_halfheight, filtering); - ScalePlane_16(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, - dst_stride_v, dst_halfwidth, dst_halfheight, filtering); - return 0; + r = ScalePlane_16(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_16(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, + dst_stride_u, dst_halfwidth, dst_halfheight, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_16(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, + dst_stride_v, dst_halfwidth, dst_halfheight, filtering); + return r; } LIBYUV_API @@ -2359,6 +2376,7 @@ int I420Scale_12(const uint16_t* src_y, int src_halfheight = SUBSAMPLE(src_height, 1, 1); int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); + int r; if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || @@ -2366,13 +2384,19 @@ int I420Scale_12(const uint16_t* src_y, return -1; } - ScalePlane_12(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane_12(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, - dst_stride_u, dst_halfwidth, dst_halfheight, filtering); - ScalePlane_12(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, - dst_stride_v, dst_halfwidth, dst_halfheight, filtering); - return 0; + r = ScalePlane_12(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, + dst_stride_u, dst_halfwidth, dst_halfheight, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, + dst_stride_v, dst_halfwidth, dst_halfheight, filtering); + return r; } // Scale an I444 image. @@ -2396,19 +2420,27 @@ int I444Scale(const uint8_t* src_y, int dst_width, int dst_height, enum FilterMode filtering) { + int r; + if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || dst_width <= 0 || dst_height <= 0) { return -1; } - ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane(src_u, src_stride_u, src_width, src_height, dst_u, dst_stride_u, - dst_width, dst_height, filtering); - ScalePlane(src_v, src_stride_v, src_width, src_height, dst_v, dst_stride_v, - dst_width, dst_height, filtering); - return 0; + r = ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane(src_u, src_stride_u, src_width, src_height, dst_u, + dst_stride_u, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane(src_v, src_stride_v, src_width, src_height, dst_v, + dst_stride_v, dst_width, dst_height, filtering); + return r; } LIBYUV_API @@ -2429,19 +2461,27 @@ int I444Scale_16(const uint16_t* src_y, int dst_width, int dst_height, enum FilterMode filtering) { + int r; + if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || dst_width <= 0 || dst_height <= 0) { return -1; } - ScalePlane_16(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane_16(src_u, src_stride_u, src_width, src_height, dst_u, dst_stride_u, - dst_width, dst_height, filtering); - ScalePlane_16(src_v, src_stride_v, src_width, src_height, dst_v, dst_stride_v, - dst_width, dst_height, filtering); - return 0; + r = ScalePlane_16(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_16(src_u, src_stride_u, src_width, src_height, dst_u, + dst_stride_u, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_16(src_v, src_stride_v, src_width, src_height, dst_v, + dst_stride_v, dst_width, dst_height, filtering); + return r; } LIBYUV_API @@ -2462,19 +2502,27 @@ int I444Scale_12(const uint16_t* src_y, int dst_width, int dst_height, enum FilterMode filtering) { + int r; + if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || dst_width <= 0 || dst_height <= 0) { return -1; } - ScalePlane_12(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane_12(src_u, src_stride_u, src_width, src_height, dst_u, dst_stride_u, - dst_width, dst_height, filtering); - ScalePlane_12(src_v, src_stride_v, src_width, src_height, dst_v, dst_stride_v, - dst_width, dst_height, filtering); - return 0; + r = ScalePlane_12(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_u, src_stride_u, src_width, src_height, dst_u, + dst_stride_u, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_v, src_stride_v, src_width, src_height, dst_v, + dst_stride_v, dst_width, dst_height, filtering); + return r; } // Scale an I422 image. @@ -2500,6 +2548,7 @@ int I422Scale(const uint8_t* src_y, enum FilterMode filtering) { int src_halfwidth = SUBSAMPLE(src_width, 1, 1); int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); + int r; if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || @@ -2507,13 +2556,19 @@ int I422Scale(const uint8_t* src_y, return -1; } - ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane(src_u, src_stride_u, src_halfwidth, src_height, dst_u, - dst_stride_u, dst_halfwidth, dst_height, filtering); - ScalePlane(src_v, src_stride_v, src_halfwidth, src_height, dst_v, - dst_stride_v, dst_halfwidth, dst_height, filtering); - return 0; + r = ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane(src_u, src_stride_u, src_halfwidth, src_height, dst_u, + dst_stride_u, dst_halfwidth, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane(src_v, src_stride_v, src_halfwidth, src_height, dst_v, + dst_stride_v, dst_halfwidth, dst_height, filtering); + return r; } LIBYUV_API @@ -2536,6 +2591,7 @@ int I422Scale_16(const uint16_t* src_y, enum FilterMode filtering) { int src_halfwidth = SUBSAMPLE(src_width, 1, 1); int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); + int r; if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || @@ -2543,13 +2599,19 @@ int I422Scale_16(const uint16_t* src_y, return -1; } - ScalePlane_16(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane_16(src_u, src_stride_u, src_halfwidth, src_height, dst_u, - dst_stride_u, dst_halfwidth, dst_height, filtering); - ScalePlane_16(src_v, src_stride_v, src_halfwidth, src_height, dst_v, - dst_stride_v, dst_halfwidth, dst_height, filtering); - return 0; + r = ScalePlane_16(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_16(src_u, src_stride_u, src_halfwidth, src_height, dst_u, + dst_stride_u, dst_halfwidth, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_16(src_v, src_stride_v, src_halfwidth, src_height, dst_v, + dst_stride_v, dst_halfwidth, dst_height, filtering); + return r; } LIBYUV_API @@ -2572,6 +2634,7 @@ int I422Scale_12(const uint16_t* src_y, enum FilterMode filtering) { int src_halfwidth = SUBSAMPLE(src_width, 1, 1); int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); + int r; if (!src_y || !src_u || !src_v || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || @@ -2579,13 +2642,19 @@ int I422Scale_12(const uint16_t* src_y, return -1; } - ScalePlane_12(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane_12(src_u, src_stride_u, src_halfwidth, src_height, dst_u, - dst_stride_u, dst_halfwidth, dst_height, filtering); - ScalePlane_12(src_v, src_stride_v, src_halfwidth, src_height, dst_v, - dst_stride_v, dst_halfwidth, dst_height, filtering); - return 0; + r = ScalePlane_12(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_u, src_stride_u, src_halfwidth, src_height, dst_u, + dst_stride_u, dst_halfwidth, dst_height, filtering); + if (r != 0) { + return r; + } + r = ScalePlane_12(src_v, src_stride_v, src_halfwidth, src_height, dst_v, + dst_stride_v, dst_halfwidth, dst_height, filtering); + return r; } // Scale an NV12 image. @@ -2609,6 +2678,7 @@ int NV12Scale(const uint8_t* src_y, int src_halfheight = SUBSAMPLE(src_height, 1, 1); int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); + int r; if (!src_y || !src_uv || src_width <= 0 || src_height == 0 || src_width > 32768 || src_height > 32768 || !dst_y || !dst_uv || @@ -2616,11 +2686,14 @@ int NV12Scale(const uint8_t* src_y, return -1; } - ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - UVScale(src_uv, src_stride_uv, src_halfwidth, src_halfheight, dst_uv, - dst_stride_uv, dst_halfwidth, dst_halfheight, filtering); - return 0; + r = ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, + dst_stride_y, dst_width, dst_height, filtering); + if (r != 0) { + return r; + } + r = UVScale(src_uv, src_stride_uv, src_halfwidth, src_halfheight, dst_uv, + dst_stride_uv, dst_halfwidth, dst_halfheight, filtering); + return r; } // Deprecated api 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. diff --git a/source/scale_uv.cc b/source/scale_uv.cc index 1c37be4f..b006d657 100644 --- a/source/scale_uv.cc +++ b/source/scale_uv.cc @@ -188,23 +188,23 @@ static void ScaleUVDown2(int src_width, // This is an optimized version for scaling down a UV to 1/4 of // its original size. #if HAS_SCALEUVDOWN4BOX -static void ScaleUVDown4Box(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_uv, - uint8_t* dst_uv, - int x, - int dx, - int y, - int dy) { +static int ScaleUVDown4Box(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy) { int j; // Allocate 2 rows of UV. const int row_size = (dst_width * 2 * 2 + 15) & ~15; align_buffer_64(row, row_size * 2); - if (!row) return; + if (!row) return 1; int row_stride = src_stride * (dy >> 16); void (*ScaleUVRowDown2)(const uint8_t* src_uv, ptrdiff_t src_stride, uint8_t* dst_uv, int dst_width) = @@ -256,6 +256,7 @@ static void ScaleUVDown4Box(int src_width, dst_uv += dst_stride; } free_aligned_buffer_64(row); + return 0; } #endif // HAS_SCALEUVDOWN4BOX @@ -345,19 +346,19 @@ static void ScaleUVDownEven(int src_width, // Scale UV down with bilinear interpolation. #if HAS_SCALEUVBILINEARDOWN -static void ScaleUVBilinearDown(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_uv, - uint8_t* dst_uv, - int x, - int dx, - int y, - int dy, - enum FilterMode filtering) { +static int ScaleUVBilinearDown(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy, + enum FilterMode filtering) { int j; void (*InterpolateRow)(uint8_t* dst_uv, const uint8_t* src_uv, ptrdiff_t src_stride, int dst_width, @@ -448,7 +449,7 @@ static void ScaleUVBilinearDown(int src_width, // Allocate a row of UV. { align_buffer_64(row, clip_src_width * 2); - if (!row) return; + if (!row) return 1; const int max_y = (src_height - 1) << 16; if (y > max_y) { @@ -472,24 +473,25 @@ static void ScaleUVBilinearDown(int src_width, } free_aligned_buffer_64(row); } + return 0; } #endif // Scale UV up with bilinear interpolation. #if HAS_SCALEUVBILINEARUP -static void ScaleUVBilinearUp(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_uv, - uint8_t* dst_uv, - int x, - int dx, - int y, - int dy, - enum FilterMode filtering) { +static int ScaleUVBilinearUp(int src_width, + int src_height, + int dst_width, + int dst_height, + int src_stride, + int dst_stride, + const uint8_t* src_uv, + uint8_t* dst_uv, + int x, + int dx, + int y, + int dy, + enum FilterMode filtering) { int j; void (*InterpolateRow)(uint8_t* dst_uv, const uint8_t* src_uv, ptrdiff_t src_stride, int dst_width, @@ -608,7 +610,7 @@ static void ScaleUVBilinearUp(int src_width, // Allocate 2 rows of UV. const int row_size = (dst_width * 2 + 15) & ~15; align_buffer_64(row, row_size * 2); - if (!row) return; + if (!row) return 1; uint8_t* rowptr = row; int rowstride = row_size; @@ -652,6 +654,7 @@ static void ScaleUVBilinearUp(int src_width, } free_aligned_buffer_64(row); } + return 0; } #endif // HAS_SCALEUVBILINEARUP @@ -987,19 +990,19 @@ static int UVCopy_16(const uint16_t* src_uv, // Scale a UV plane (from NV12) // This function in turn calls a scaling function // suitable for handling the desired resolutions. -static void ScaleUV(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 ScaleUV(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; @@ -1045,22 +1048,22 @@ static void ScaleUV(const uint8_t* src, ScaleUVDown2(src_width, src_height, clip_width, clip_height, src_stride, dst_stride, src, dst, x, dx, y, dy, filtering); - return; + return 0; } #endif #if HAS_SCALEUVDOWN4BOX if (dx == 0x40000 && filtering == kFilterBox) { // Optimized 1/4 box downsample. - ScaleUVDown4Box(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy); - return; + return ScaleUVDown4Box(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, + dy); } #endif #if HAS_SCALEUVDOWNEVEN ScaleUVDownEven(src_width, src_height, clip_width, clip_height, src_stride, dst_stride, src, dst, x, dx, y, dy, filtering); - return; + return 0; #endif } // Optimized odd scale down. ie 3, 5, 7, 9x. @@ -1071,7 +1074,7 @@ static void ScaleUV(const uint8_t* src, // Straight copy. UVCopy(src + (y >> 16) * (intptr_t)src_stride + (x >> 16) * 2, src_stride, dst, dst_stride, clip_width, clip_height); - return; + return 0; } #endif } @@ -1082,38 +1085,37 @@ static void ScaleUV(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=*/2, filtering); - return; + return 0; } if ((filtering == kFilterLinear) && ((dst_width + 1) / 2 == src_width)) { ScaleUVLinearUp2(src_width, src_height, clip_width, clip_height, src_stride, dst_stride, src, dst); - return; + return 0; } if ((clip_height + 1) / 2 == src_height && (clip_width + 1) / 2 == src_width && (filtering == kFilterBilinear || filtering == kFilterBox)) { ScaleUVBilinearUp2(src_width, src_height, clip_width, clip_height, src_stride, dst_stride, src, dst); - return; + return 0; } #if HAS_SCALEUVBILINEARUP if (filtering && dy < 65536) { - ScaleUVBilinearUp(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy, - filtering); - return; + return ScaleUVBilinearUp(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, dy, + filtering); } #endif #if HAS_SCALEUVBILINEARDOWN if (filtering) { - ScaleUVBilinearDown(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy, - filtering); - return; + return ScaleUVBilinearDown(src_width, src_height, clip_width, clip_height, + src_stride, dst_stride, src, dst, x, dx, y, dy, + filtering); } #endif ScaleUVSimple(src_width, src_height, clip_width, clip_height, src_stride, dst_stride, src, dst, x, dx, y, dy); + return 0; } // Scale an UV image. @@ -1131,9 +1133,9 @@ int UVScale(const uint8_t* src_uv, src_height > 32768 || !dst_uv || dst_width <= 0 || dst_height <= 0) { return -1; } - ScaleUV(src_uv, src_stride_uv, src_width, src_height, dst_uv, dst_stride_uv, - dst_width, dst_height, 0, 0, dst_width, dst_height, filtering); - return 0; + return ScaleUV(src_uv, src_stride_uv, src_width, src_height, dst_uv, + dst_stride_uv, dst_width, dst_height, 0, 0, dst_width, + dst_height, filtering); } // Scale a 16 bit UV image. -- cgit v1.2.3