diff options
Diffstat (limited to 'source/scale_argb.cc')
-rw-r--r-- | source/scale_argb.cc | 219 |
1 files changed, 118 insertions, 101 deletions
diff --git a/source/scale_argb.cc b/source/scale_argb.cc index 1d5c1b60..18bdeb86 100644 --- a/source/scale_argb.cc +++ b/source/scale_argb.cc @@ -151,22 +151,27 @@ 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 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) = @@ -209,6 +214,7 @@ static void ScaleARGBDown4Box(int src_width, dst_argb += dst_stride; } free_aligned_buffer_64(row); + return 0; } // ScaleARGB ARGB Even @@ -278,10 +284,14 @@ static void ScaleARGBDownEven(int src_width, } } #endif +#if defined(HAS_SCALEARGBROWDOWNEVENBOX_RVV) + if (filtering && TestCpuFlag(kCpuHasRVV)) { + ScaleARGBRowDownEven = ScaleARGBRowDownEvenBox_RVV; + } +#endif #if defined(HAS_SCALEARGBROWDOWNEVEN_RVV) - if (TestCpuFlag(kCpuHasRVV)) { - ScaleARGBRowDownEven = - filtering ? ScaleARGBRowDownEvenBox_RVV : ScaleARGBRowDownEven_RVV; + if (!filtering && TestCpuFlag(kCpuHasRVV)) { + ScaleARGBRowDownEven = ScaleARGBRowDownEven_RVV; } #endif @@ -296,19 +306,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, @@ -407,6 +417,8 @@ static void ScaleARGBBilinearDown(int src_width, // Allocate a row of ARGB. { align_buffer_64(row, clip_src_width * 4); + if (!row) + return 1; const int max_y = (src_height - 1) << 16; if (y > max_y) { @@ -430,22 +442,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, @@ -581,6 +594,8 @@ 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 1; uint8_t* rowptr = row; int rowstride = row_size; @@ -624,27 +639,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) = @@ -846,16 +862,17 @@ static void ScaleYUVToARGBBilinearUp(int src_width, const uint8_t* src_row_u = src_u + uv_yi * (intptr_t)src_stride_u; const uint8_t* src_row_v = src_v + uv_yi * (intptr_t)src_stride_v; - // Allocate 2 rows of ARGB. + // Allocate 1 row of ARGB for source conversion and 2 rows of ARGB + // scaled horizontally to the destination width. const int row_size = (dst_width * 4 + 31) & ~31; - align_buffer_64(row, row_size * 2); - - // Allocate 1 row of ARGB for source conversion. - align_buffer_64(argb_row, src_width * 4); + align_buffer_64(row, row_size * 2 + src_width * 4); + uint8_t* argb_row = row + row_size * 2; uint8_t* rowptr = row; int rowstride = row_size; int lasty = yi; + if (!row) + return 1; // TODO(fbarchard): Convert first 2 rows of YUV to ARGB. ScaleARGBFilterCols(rowptr, src_row_y, dst_width, x, dx); @@ -910,7 +927,7 @@ static void ScaleYUVToARGBBilinearUp(int src_width, y += dy; } free_aligned_buffer_64(row); - free_aligned_buffer_64(row_argb); + return 0; } #endif @@ -985,19 +1002,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; @@ -1042,18 +1059,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)) { @@ -1062,7 +1079,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; } } } @@ -1071,22 +1088,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 @@ -1110,10 +1126,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. @@ -1131,10 +1146,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. @@ -1158,8 +1172,11 @@ int YUVToARGBScaleClip(const uint8_t* src_y, int clip_width, int clip_height, enum FilterMode filtering) { - uint8_t* argb_buffer = (uint8_t*)malloc(src_width * src_height * 4); int r; + uint8_t* argb_buffer = (uint8_t*)malloc(src_width * src_height * 4); + if (!argb_buffer) { + return 1; // Out of memory runtime error. + } (void)src_fourcc; // TODO(fbarchard): implement and/or assert. (void)dst_fourcc; I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, |