/* * Copyright 2013 The LibYuv Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "libyuv/scale.h" #include <assert.h>#include <string.h> #include "libyuv/cpu_id.h"#include "libyuv/planar_functions.h" // For CopyARGB#include "libyuv/row.h"#include "libyuv/scale_row.h" #ifdef __cplusplusnamespace libyuv {extern "C" {#endif static __inline int Abs(int v) { return v >= 0 ? v : -v;} // CPU agnostic row functionsvoid ScaleRowDown2_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[1]; dst[1] = src_ptr[3]; dst += 2; src_ptr += 4; } if (dst_width & 1) { dst[0] = src_ptr[1]; }} void ScaleRowDown2_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[1]; dst[1] = src_ptr[3]; dst += 2; src_ptr += 4; } if (dst_width & 1) { dst[0] = src_ptr[1]; }} void ScaleRowDown2Linear_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { const uint8_t* s = src_ptr; int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + 1) >> 1; dst[1] = (s[2] + s[3] + 1) >> 1; dst += 2; s += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + 1) >> 1; }} void ScaleRowDown2Linear_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { const uint16_t* s = src_ptr; int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + 1) >> 1; dst[1] = (s[2] + s[3] + 1) >> 1; dst += 2; s += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + 1) >> 1; }} void ScaleRowDown2Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; dst += 2; s += 4; t += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; }} void ScaleRowDown2Box_Odd_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; dst_width -= 1; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; dst += 2; s += 4; t += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst += 1; s += 2; t += 2; } dst[0] = (s[0] + t[0] + 1) >> 1;} void ScaleRowDown2Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { const uint16_t* s = src_ptr; const uint16_t* t = src_ptr + src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; dst += 2; s += 4; t += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; }} void ScaleRowDown4_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[2]; dst[1] = src_ptr[6]; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = src_ptr[2]; }} void ScaleRowDown4_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[2]; dst[1] = src_ptr[6]; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = src_ptr[2]; }} void ScaleRowDown4Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { intptr_t stride = src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride + 6] + src_ptr[stride + 7] + src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 8) >> 4; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; }} void ScaleRowDown4Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { intptr_t stride = src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride + 6] + src_ptr[stride + 7] + src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 8) >> 4; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; }} void ScaleRowDown34_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { int x; (void)src_stride; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { dst[0] = src_ptr[0]; dst[1] = src_ptr[1]; dst[2] = src_ptr[3]; dst += 3; src_ptr += 4; }} void ScaleRowDown34_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { int x; (void)src_stride; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { dst[0] = src_ptr[0]; dst[1] = src_ptr[1]; dst[2] = src_ptr[3]; dst += 3; src_ptr += 4; }} // Filter rows 0 and 1 together, 3 : 1void ScaleRowDown34_0_Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* d, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 * 3 + b0 + 2) >> 2; d[1] = (a1 * 3 + b1 + 2) >> 2; d[2] = (a2 * 3 + b2 + 2) >> 2; d += 3; s += 4; t += 4; }} void ScaleRowDown34_0_Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* d, int dst_width) { const uint16_t* s = src_ptr; const uint16_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 * 3 + b0 + 2) >> 2; d[1] = (a1 * 3 + b1 + 2) >> 2; d[2] = (a2 * 3 + b2 + 2) >> 2; d += 3; s += 4; t += 4; }} // Filter rows 1 and 2 together, 1 : 1void ScaleRowDown34_1_Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* d, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 + b0 + 1) >> 1; d[1] = (a1 + b1 + 1) >> 1; d[2] = (a2 + b2 + 1) >> 1; d += 3; s += 4; t += 4; }} void ScaleRowDown34_1_Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* d, int dst_width) { const uint16_t* s = src_ptr; const uint16_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 + b0 + 1) >> 1; d[1] = (a1 + b1 + 1) >> 1; d[2] = (a2 + b2 + 1) >> 1; d += 3; s += 4; t += 4; }} // Scales a single row of pixels using point sampling.void ScaleCols_C(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, int dx) { int j; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[0] = src_ptr[x >> 16]; x += dx; dst_ptr[1] = src_ptr[x >> 16]; x += dx; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[x >> 16]; }} void ScaleCols_16_C(uint16_t* dst_ptr, const uint16_t* src_ptr, int dst_width, int x, int dx) { int j; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[0] = src_ptr[x >> 16]; x += dx; dst_ptr[1] = src_ptr[x >> 16]; x += dx; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[x >> 16]; }} // Scales a single row of pixels up by 2x using point sampling.void ScaleColsUp2_C(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, int dx) { int j; (void)x; (void)dx; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[1] = dst_ptr[0] = src_ptr[0]; src_ptr += 1; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[0]; }} void ScaleColsUp2_16_C(uint16_t* dst_ptr, const uint16_t* src_ptr, int dst_width, int x, int dx) { int j; (void)x; (void)dx; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[1] = dst_ptr[0] = src_ptr[0]; src_ptr += 1; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[0]; }} // (1-f)a + fb can be replaced with a + f(b-a)#if defined(__arm__) || defined(__aarch64__)#define BLENDER(a, b, f) \ (uint8_t)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))#else// Intel uses 7 bit math with rounding.#define BLENDER(a, b, f) \ (uint8_t)((int)(a) + (((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7))#endif void ScaleFilterCols_C(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, int dx) { int j; for (j = 0; j < dst_width - 1; j += 2) { int xi = x >> 16; int a = src_ptr[xi]; int b = src_ptr[xi + 1]; dst_ptr[0] = BLENDER(a, b, x & 0xffff); x += dx; xi = x >> 16; a = src_ptr[xi];Lines 1–500 of 1323. Load more
/* * Copyright 2013 The LibYuv Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "libyuv/scale.h" #include <assert.h> #include <string.h> #include "libyuv/cpu_id.h" #include "libyuv/planar_functions.h" // For CopyARGB #include "libyuv/row.h" #include "libyuv/scale_row.h" #ifdef __cplusplus namespace libyuv { extern "C" { #endif static __inline int Abs(int v) { return v >= 0 ? v : -v; } // CPU agnostic row functions void ScaleRowDown2_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[1]; dst[1] = src_ptr[3]; dst += 2; src_ptr += 4; } if (dst_width & 1) { dst[0] = src_ptr[1]; } } void ScaleRowDown2_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[1]; dst[1] = src_ptr[3]; dst += 2; src_ptr += 4; } if (dst_width & 1) { dst[0] = src_ptr[1]; } } void ScaleRowDown2Linear_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { const uint8_t* s = src_ptr; int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + 1) >> 1; dst[1] = (s[2] + s[3] + 1) >> 1; dst += 2; s += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + 1) >> 1; } } void ScaleRowDown2Linear_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { const uint16_t* s = src_ptr; int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + 1) >> 1; dst[1] = (s[2] + s[3] + 1) >> 1; dst += 2; s += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + 1) >> 1; } } void ScaleRowDown2Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; dst += 2; s += 4; t += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; } } void ScaleRowDown2Box_Odd_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; dst_width -= 1; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; dst += 2; s += 4; t += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst += 1; s += 2; t += 2; } dst[0] = (s[0] + t[0] + 1) >> 1; } void ScaleRowDown2Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { const uint16_t* s = src_ptr; const uint16_t* t = src_ptr + src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; dst += 2; s += 4; t += 4; } if (dst_width & 1) { dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; } } void ScaleRowDown4_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[2]; dst[1] = src_ptr[6]; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = src_ptr[2]; } } void ScaleRowDown4_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { int x; (void)src_stride; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = src_ptr[2]; dst[1] = src_ptr[6]; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = src_ptr[2]; } } void ScaleRowDown4Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { intptr_t stride = src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride + 6] + src_ptr[stride + 7] + src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 8) >> 4; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; } } void ScaleRowDown4Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { intptr_t stride = src_stride; int x; for (x = 0; x < dst_width - 1; x += 2) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride + 6] + src_ptr[stride + 7] + src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 8) >> 4; dst += 2; src_ptr += 8; } if (dst_width & 1) { dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 8) >> 4; } } void ScaleRowDown34_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst, int dst_width) { int x; (void)src_stride; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { dst[0] = src_ptr[0]; dst[1] = src_ptr[1]; dst[2] = src_ptr[3]; dst += 3; src_ptr += 4; } } void ScaleRowDown34_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* dst, int dst_width) { int x; (void)src_stride; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { dst[0] = src_ptr[0]; dst[1] = src_ptr[1]; dst[2] = src_ptr[3]; dst += 3; src_ptr += 4; } } // Filter rows 0 and 1 together, 3 : 1 void ScaleRowDown34_0_Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* d, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 * 3 + b0 + 2) >> 2; d[1] = (a1 * 3 + b1 + 2) >> 2; d[2] = (a2 * 3 + b2 + 2) >> 2; d += 3; s += 4; t += 4; } } void ScaleRowDown34_0_Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* d, int dst_width) { const uint16_t* s = src_ptr; const uint16_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 * 3 + b0 + 2) >> 2; d[1] = (a1 * 3 + b1 + 2) >> 2; d[2] = (a2 * 3 + b2 + 2) >> 2; d += 3; s += 4; t += 4; } } // Filter rows 1 and 2 together, 1 : 1 void ScaleRowDown34_1_Box_C(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* d, int dst_width) { const uint8_t* s = src_ptr; const uint8_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 + b0 + 1) >> 1; d[1] = (a1 + b1 + 1) >> 1; d[2] = (a2 + b2 + 1) >> 1; d += 3; s += 4; t += 4; } } void ScaleRowDown34_1_Box_16_C(const uint16_t* src_ptr, ptrdiff_t src_stride, uint16_t* d, int dst_width) { const uint16_t* s = src_ptr; const uint16_t* t = src_ptr + src_stride; int x; assert((dst_width % 3 == 0) && (dst_width > 0)); for (x = 0; x < dst_width; x += 3) { uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; d[0] = (a0 + b0 + 1) >> 1; d[1] = (a1 + b1 + 1) >> 1; d[2] = (a2 + b2 + 1) >> 1; d += 3; s += 4; t += 4; } } // Scales a single row of pixels using point sampling. void ScaleCols_C(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, int dx) { int j; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[0] = src_ptr[x >> 16]; x += dx; dst_ptr[1] = src_ptr[x >> 16]; x += dx; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[x >> 16]; } } void ScaleCols_16_C(uint16_t* dst_ptr, const uint16_t* src_ptr, int dst_width, int x, int dx) { int j; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[0] = src_ptr[x >> 16]; x += dx; dst_ptr[1] = src_ptr[x >> 16]; x += dx; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[x >> 16]; } } // Scales a single row of pixels up by 2x using point sampling. void ScaleColsUp2_C(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, int dx) { int j; (void)x; (void)dx; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[1] = dst_ptr[0] = src_ptr[0]; src_ptr += 1; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[0]; } } void ScaleColsUp2_16_C(uint16_t* dst_ptr, const uint16_t* src_ptr, int dst_width, int x, int dx) { int j; (void)x; (void)dx; for (j = 0; j < dst_width - 1; j += 2) { dst_ptr[1] = dst_ptr[0] = src_ptr[0]; src_ptr += 1; dst_ptr += 2; } if (dst_width & 1) { dst_ptr[0] = src_ptr[0]; } } // (1-f)a + fb can be replaced with a + f(b-a) #if defined(__arm__) || defined(__aarch64__) #define BLENDER(a, b, f) \ (uint8_t)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) #else // Intel uses 7 bit math with rounding. #define BLENDER(a, b, f) \ (uint8_t)((int)(a) + (((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7)) #endif void ScaleFilterCols_C(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, int dx) { int j; for (j = 0; j < dst_width - 1; j += 2) { int xi = x >> 16; int a = src_ptr[xi]; int b = src_ptr[xi + 1]; dst_ptr[0] = BLENDER(a, b, x & 0xffff); x += dx; xi = x >> 16; a = src_ptr[xi];