1f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang/* 2f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * Copyright 2013 The LibYuv Project Authors. All rights reserved. 3f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * 4f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * Use of this source code is governed by a BSD-style license 5f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * that can be found in the LICENSE file in the root of the source 6f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * tree. An additional intellectual property rights grant can be found 7f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * in the file PATENTS. All contributing project authors may 8f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang * be found in the AUTHORS file in the root of the source tree. 9f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang */ 10f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 11f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/scale.h" 12f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 13f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include <assert.h> 14f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include <string.h> 15f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 16f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/cpu_id.h" 17f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/planar_functions.h" // For CopyARGB 18f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/row.h" 19f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#include "libyuv/scale_row.h" 20f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 21f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#ifdef __cplusplus 22f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangnamespace libyuv { 23f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangextern "C" { 24f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 25f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 26f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangstatic __inline int Abs(int v) { 27f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return v >= 0 ? v : -v; 28f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 29f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 30f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// CPU agnostic row functions 31f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown2_C(const uint8* src_ptr, ptrdiff_t src_stride, 32f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 33f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 34f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 35f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[1]; 36f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[3]; 37f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 38f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 4; 39f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 40f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 41f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[1]; 42f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 43f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 44f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 45f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown2_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 46f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst, int dst_width) { 47f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 48f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 49f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[1]; 50f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[3]; 51f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 52f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 4; 53f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 54f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 55f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[1]; 56f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 57f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 58f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 59f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown2Linear_C(const uint8* src_ptr, ptrdiff_t src_stride, 60f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 61f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* s = src_ptr; 62f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 63f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 64f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + 1) >> 1; 65f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = (s[2] + s[3] + 1) >> 1; 66f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 67f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 68f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 69f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 70f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + 1) >> 1; 71f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 72f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 73f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 74f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown2Linear_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 75f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst, int dst_width) { 76f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* s = src_ptr; 77f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 78f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 79f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + 1) >> 1; 80f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = (s[2] + s[3] + 1) >> 1; 81f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 82f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 83f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 84f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 85f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + 1) >> 1; 86f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 87f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 88f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 89f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown2Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 90f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 91f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* s = src_ptr; 92f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* t = src_ptr + src_stride; 93f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 94f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 95f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 96f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; 97f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 98f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 99f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 4; 100f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 101f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 102f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 103f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 104f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 105f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 106f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown2Box_Odd_C(const uint8* src_ptr, ptrdiff_t src_stride, 107f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 108f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* s = src_ptr; 109f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* t = src_ptr + src_stride; 110f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 111f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_width -= 1; 112f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 113f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 114f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; 115f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 116f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 117f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 4; 118f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 119f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 120f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 121f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 1; 122f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 2; 123f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 2; 124f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 125f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + t[0] + 1) >> 1; 126f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 127f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 128f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown2Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 129f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst, int dst_width) { 130f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* s = src_ptr; 131f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* t = src_ptr + src_stride; 132f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 133f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 134f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 135f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; 136f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 137f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 138f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 4; 139f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 140f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 141f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 142f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 143f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 144f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 145f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown4_C(const uint8* src_ptr, ptrdiff_t src_stride, 146f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 147f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 148f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 149f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[2]; 150f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[6]; 151f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 152f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 153f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 154f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 155f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[2]; 156f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 157f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 158f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 159f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown4_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 160f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst, int dst_width) { 161f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 162f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 163f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[2]; 164f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[6]; 165f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 166f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 167f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 168f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 169f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[2]; 170f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 171f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 172f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 173f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown4Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 174f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 175f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang intptr_t stride = src_stride; 176f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 177f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 178f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 179f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 180f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2] + src_ptr[stride + 3] + 181f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 182f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 183f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 184f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 185f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 8) >> 4; 186f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + 187f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 4] + src_ptr[stride + 5] + 188f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 6] + src_ptr[stride + 7] + 189f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + 190f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + 191f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + 192f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 193f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 8) >> 4; 194f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 195f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 196f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 197f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 198f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 199f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 200f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2] + src_ptr[stride + 3] + 201f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 202f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 203f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 204f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 205f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 8) >> 4; 206f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 207f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 208f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 209f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown4Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 210f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst, int dst_width) { 211f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang intptr_t stride = src_stride; 212f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 213f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 214f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 215f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 216f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2] + src_ptr[stride + 3] + 217f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 218f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 219f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 220f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 221f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 8) >> 4; 222f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + 223f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 4] + src_ptr[stride + 5] + 224f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 6] + src_ptr[stride + 7] + 225f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + 226f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + 227f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + 228f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 229f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 8) >> 4; 230f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 231f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 232f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 233f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 234f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 235f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 236f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2] + src_ptr[stride + 3] + 237f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 238f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 239f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 240f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 241f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 8) >> 4; 242f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 243f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 244f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 245f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown34_C(const uint8* src_ptr, ptrdiff_t src_stride, 246f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 247f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 248f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 249f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 250f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[0]; 251f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[1]; 252f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[2] = src_ptr[3]; 253f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 3; 254f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 4; 255f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 256f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 257f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 258f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown34_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 259f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst, int dst_width) { 260f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 261f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 262f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 263f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[0]; 264f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[1]; 265f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[2] = src_ptr[3]; 266f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 3; 267f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 4; 268f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 269f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 270f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 271f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Filter rows 0 and 1 together, 3 : 1 272f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown34_0_Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 273f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* d, int dst_width) { 274f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* s = src_ptr; 275f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* t = src_ptr + src_stride; 276f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 277f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 278f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 279f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 280f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 281f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 282f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 283f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 284f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 285f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[0] = (a0 * 3 + b0 + 2) >> 2; 286f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[1] = (a1 * 3 + b1 + 2) >> 2; 287f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[2] = (a2 * 3 + b2 + 2) >> 2; 288f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d += 3; 289f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 290f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 4; 291f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 292f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 293f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 294f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown34_0_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 295f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* d, int dst_width) { 296f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* s = src_ptr; 297f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* t = src_ptr + src_stride; 298f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 299f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 300f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 301f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 302f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 303f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 304f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 305f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 306f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 307f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[0] = (a0 * 3 + b0 + 2) >> 2; 308f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[1] = (a1 * 3 + b1 + 2) >> 2; 309f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[2] = (a2 * 3 + b2 + 2) >> 2; 310f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d += 3; 311f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 312f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 4; 313f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 314f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 315f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 316f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Filter rows 1 and 2 together, 1 : 1 317f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown34_1_Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 318f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* d, int dst_width) { 319f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* s = src_ptr; 320f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* t = src_ptr + src_stride; 321f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 322f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 323f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 324f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 325f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 326f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 327f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 328f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 329f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 330f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[0] = (a0 + b0 + 1) >> 1; 331f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[1] = (a1 + b1 + 1) >> 1; 332f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[2] = (a2 + b2 + 1) >> 1; 333f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d += 3; 334f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 335f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 4; 336f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 337f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 338f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 339f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown34_1_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 340f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* d, int dst_width) { 341f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* s = src_ptr; 342f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* t = src_ptr + src_stride; 343f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 344f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 345f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 346f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 347f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 348f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 349f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 350f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 351f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 352f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[0] = (a0 + b0 + 1) >> 1; 353f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[1] = (a1 + b1 + 1) >> 1; 354f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d[2] = (a2 + b2 + 1) >> 1; 355f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang d += 3; 356f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang s += 4; 357f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang t += 4; 358f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 359f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 360f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 361f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Scales a single row of pixels using point sampling. 362f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleCols_C(uint8* dst_ptr, const uint8* src_ptr, 363f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 364f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 365f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 366f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = src_ptr[x >> 16]; 367f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 368f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = src_ptr[x >> 16]; 369f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 370f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 371f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 372f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 373f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = src_ptr[x >> 16]; 374f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 375f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 376f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 377f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleCols_16_C(uint16* dst_ptr, const uint16* src_ptr, 378f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 379f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 380f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 381f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = src_ptr[x >> 16]; 382f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 383f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = src_ptr[x >> 16]; 384f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 385f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 386f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 387f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 388f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = src_ptr[x >> 16]; 389f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 390f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 391f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 392f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Scales a single row of pixels up by 2x using point sampling. 393f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleColsUp2_C(uint8* dst_ptr, const uint8* src_ptr, 394f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 395f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 396f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 397f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = dst_ptr[0] = src_ptr[0]; 398f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 1; 399f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 400f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 401f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 402f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = src_ptr[0]; 403f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 404f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 405f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 406f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleColsUp2_16_C(uint16* dst_ptr, const uint16* src_ptr, 407f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 408f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 409f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 410f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = dst_ptr[0] = src_ptr[0]; 411f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 1; 412f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 413f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 414f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 415f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = src_ptr[0]; 416f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 417f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 418f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 419f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// (1-f)a + fb can be replaced with a + f(b-a) 420f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(__arm__) || defined(__aarch64__) 421f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define BLENDER(a, b, f) (uint8)((int)(a) + \ 422f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) 423f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#else 424f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// inteluses 7 bit math with rounding. 425f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define BLENDER(a, b, f) (uint8)((int)(a) + \ 426f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7)) 427f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 428f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 429f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleFilterCols_C(uint8* dst_ptr, const uint8* src_ptr, 430f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 431f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 432f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 433f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xi = x >> 16; 434f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 435f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 436f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 437f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 438f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xi = x >> 16; 439f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang a = src_ptr[xi]; 440f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang b = src_ptr[xi + 1]; 441f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = BLENDER(a, b, x & 0xffff); 442f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 443f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 444f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 445f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 446f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xi = x >> 16; 447f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 448f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 449f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 450f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 451f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 452f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 453f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleFilterCols64_C(uint8* dst_ptr, const uint8* src_ptr, 454f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x32, int dx) { 455f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 x = (int64)(x32); 456f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 457f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 458f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 xi = x >> 16; 459f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 460f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 461f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 462f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 463f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xi = x >> 16; 464f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang a = src_ptr[xi]; 465f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang b = src_ptr[xi + 1]; 466f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = BLENDER(a, b, x & 0xffff); 467f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 468f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 469f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 470f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 471f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 xi = x >> 16; 472f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 473f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 474f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 475f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 476f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 477f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef BLENDER 478f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 479f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Same as 8 bit arm blender but return is cast to uint16 480f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define BLENDER(a, b, f) (uint16)((int)(a) + \ 481f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) 482f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 483f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleFilterCols_16_C(uint16* dst_ptr, const uint16* src_ptr, 484f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 485f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 486f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 487f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xi = x >> 16; 488f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 489f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 490f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 491f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 492f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xi = x >> 16; 493f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang a = src_ptr[xi]; 494f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang b = src_ptr[xi + 1]; 495f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = BLENDER(a, b, x & 0xffff); 496f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 497f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 498f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 499f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 500f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xi = x >> 16; 501f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 502f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 503f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 504f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 505f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 506f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 507f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleFilterCols64_16_C(uint16* dst_ptr, const uint16* src_ptr, 508f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x32, int dx) { 509f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 x = (int64)(x32); 510f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 511f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 512f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 xi = x >> 16; 513f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 514f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 515f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 516f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 517f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xi = x >> 16; 518f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang a = src_ptr[xi]; 519f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang b = src_ptr[xi + 1]; 520f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = BLENDER(a, b, x & 0xffff); 521f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 522f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 523f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 524f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 525f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 xi = x >> 16; 526f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int a = src_ptr[xi]; 527f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int b = src_ptr[xi + 1]; 528f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = BLENDER(a, b, x & 0xffff); 529f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 530f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 531f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef BLENDER 532f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 533f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown38_C(const uint8* src_ptr, ptrdiff_t src_stride, 534f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst, int dst_width) { 535f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 536f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_width % 3 == 0); 537f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 538f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[0]; 539f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[3]; 540f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[2] = src_ptr[6]; 541f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 3; 542f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 543f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 544f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 545f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 546f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown38_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 547f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst, int dst_width) { 548f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 549f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_width % 3 == 0); 550f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; x += 3) { 551f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src_ptr[0]; 552f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src_ptr[3]; 553f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[2] = src_ptr[6]; 554f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 3; 555f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 556f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 557f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 558f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 559f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// 8x3 -> 3x1 560f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown38_3_Box_C(const uint8* src_ptr, 561f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ptrdiff_t src_stride, 562f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst_ptr, int dst_width) { 563f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang intptr_t stride = src_stride; 564f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int i; 565f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 566f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (i = 0; i < dst_width; i += 3) { 567f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 568f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 569f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2] + src_ptr[stride * 2 + 0] + 570f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) * 571f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 9) >> 16; 572f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 573f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 3] + src_ptr[stride + 4] + 574f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 5] + src_ptr[stride * 2 + 3] + 575f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) * 576f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 9) >> 16; 577f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 578f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 6] + src_ptr[stride + 7] + 579f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) * 580f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 6) >> 16; 581f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 582f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 3; 583f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 584f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 585f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 586f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown38_3_Box_16_C(const uint16* src_ptr, 587f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ptrdiff_t src_stride, 588f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst_ptr, int dst_width) { 589f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang intptr_t stride = src_stride; 590f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int i; 591f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 592f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (i = 0; i < dst_width; i += 3) { 593f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 594f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 595f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2] + src_ptr[stride * 2 + 0] + 596f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) * 597f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 9) >> 16; 598f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 599f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 3] + src_ptr[stride + 4] + 600f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 5] + src_ptr[stride * 2 + 3] + 601f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) * 602f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 9) >> 16; 603f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 604f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 6] + src_ptr[stride + 7] + 605f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) * 606f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 6) >> 16; 607f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 608f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 3; 609f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 610f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 611f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 612f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// 8x2 -> 3x1 613f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown38_2_Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 614f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst_ptr, int dst_width) { 615f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang intptr_t stride = src_stride; 616f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int i; 617f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 618f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (i = 0; i < dst_width; i += 3) { 619f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 620f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 621f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2]) * (65536 / 6) >> 16; 622f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 623f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 3] + src_ptr[stride + 4] + 624f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 5]) * (65536 / 6) >> 16; 625f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 626f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 6] + src_ptr[stride + 7]) * 627f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 4) >> 16; 628f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 629f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 3; 630f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 631f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 632f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 633f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleRowDown38_2_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 634f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint16* dst_ptr, int dst_width) { 635f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang intptr_t stride = src_stride; 636f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int i; 637f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert((dst_width % 3 == 0) && (dst_width > 0)); 638f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (i = 0; i < dst_width; i += 3) { 639f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 640f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 0] + src_ptr[stride + 1] + 641f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 2]) * (65536 / 6) >> 16; 642f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 643f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 3] + src_ptr[stride + 4] + 644f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 5]) * (65536 / 6) >> 16; 645f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 646f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr[stride + 6] + src_ptr[stride + 7]) * 647f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (65536 / 4) >> 16; 648f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 8; 649f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 3; 650f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 651f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 652f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 653f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleAddRow_C(const uint8* src_ptr, uint16* dst_ptr, int src_width) { 654f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 655f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(src_width > 0); 656f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < src_width - 1; x += 2) { 657f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] += src_ptr[0]; 658f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] += src_ptr[1]; 659f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 2; 660f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 661f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 662f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_width & 1) { 663f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] += src_ptr[0]; 664f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 665f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 666f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 667f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleAddRow_16_C(const uint16* src_ptr, uint32* dst_ptr, int src_width) { 668f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 669f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(src_width > 0); 670f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < src_width - 1; x += 2) { 671f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] += src_ptr[0]; 672f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[1] += src_ptr[1]; 673f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_ptr += 2; 674f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr += 2; 675f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 676f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_width & 1) { 677f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_ptr[0] += src_ptr[0]; 678f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 679f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 680f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 681f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBRowDown2_C(const uint8* src_argb, 682f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ptrdiff_t src_stride, 683f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst_argb, int dst_width) { 684f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint32* src = (const uint32*)(src_argb); 685f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32* dst = (uint32*)(dst_argb); 686f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 687f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 688f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 689f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[1]; 690f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src[3]; 691f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src += 4; 692f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 693f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 694f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 695f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[1]; 696f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 697f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 698f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 699f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBRowDown2Linear_C(const uint8* src_argb, 700f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ptrdiff_t src_stride, 701f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst_argb, int dst_width) { 702f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 703f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; ++x) { 704f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[0] = (src_argb[0] + src_argb[4] + 1) >> 1; 705f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[1] = (src_argb[1] + src_argb[5] + 1) >> 1; 706f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[2] = (src_argb[2] + src_argb[6] + 1) >> 1; 707f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[3] = (src_argb[3] + src_argb[7] + 1) >> 1; 708f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb += 8; 709f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb += 4; 710f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 711f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 712f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 713f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBRowDown2Box_C(const uint8* src_argb, ptrdiff_t src_stride, 714f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst_argb, int dst_width) { 715f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 716f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; ++x) { 717f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[0] = (src_argb[0] + src_argb[4] + 718f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride] + src_argb[src_stride + 4] + 2) >> 2; 719f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[1] = (src_argb[1] + src_argb[5] + 720f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride + 1] + src_argb[src_stride + 5] + 2) >> 2; 721f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[2] = (src_argb[2] + src_argb[6] + 722f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride + 2] + src_argb[src_stride + 6] + 2) >> 2; 723f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[3] = (src_argb[3] + src_argb[7] + 724f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride + 3] + src_argb[src_stride + 7] + 2) >> 2; 725f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb += 8; 726f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb += 4; 727f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 728f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 729f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 730f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBRowDownEven_C(const uint8* src_argb, ptrdiff_t src_stride, 731f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stepx, 732f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst_argb, int dst_width) { 733f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint32* src = (const uint32*)(src_argb); 734f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32* dst = (uint32*)(dst_argb); 735f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 736f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 737f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width - 1; x += 2) { 738f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[0]; 739f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src[src_stepx]; 740f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src += src_stepx * 2; 741f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 742f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 743f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 744f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[0]; 745f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 746f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 747f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 748f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBRowDownEvenBox_C(const uint8* src_argb, 749f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ptrdiff_t src_stride, 750f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stepx, 751f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint8* dst_argb, int dst_width) { 752f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x; 753f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (x = 0; x < dst_width; ++x) { 754f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[0] = (src_argb[0] + src_argb[4] + 755f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride] + src_argb[src_stride + 4] + 2) >> 2; 756f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[1] = (src_argb[1] + src_argb[5] + 757f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride + 1] + src_argb[src_stride + 5] + 2) >> 2; 758f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[2] = (src_argb[2] + src_argb[6] + 759f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride + 2] + src_argb[src_stride + 6] + 2) >> 2; 760f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb[3] = (src_argb[3] + src_argb[7] + 761f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb[src_stride + 3] + src_argb[src_stride + 7] + 2) >> 2; 762f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb += src_stepx * 4; 763f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb += 4; 764f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 765f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 766f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 767f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Scales a single row of pixels using point sampling. 768f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBCols_C(uint8* dst_argb, const uint8* src_argb, 769f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 770f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint32* src = (const uint32*)(src_argb); 771f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32* dst = (uint32*)(dst_argb); 772f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 773f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 774f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[x >> 16]; 775f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 776f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src[x >> 16]; 777f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 778f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 779f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 780f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 781f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[x >> 16]; 782f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 783f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 784f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 785f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBCols64_C(uint8* dst_argb, const uint8* src_argb, 786f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x32, int dx) { 787f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 x = (int64)(x32); 788f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint32* src = (const uint32*)(src_argb); 789f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32* dst = (uint32*)(dst_argb); 790f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 791f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 792f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[x >> 16]; 793f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 794f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = src[x >> 16]; 795f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 796f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 797f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 798f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 799f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[x >> 16]; 800f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 801f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 802f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 803f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Scales a single row of pixels up by 2x using point sampling. 804f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBColsUp2_C(uint8* dst_argb, const uint8* src_argb, 805f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 806f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint32* src = (const uint32*)(src_argb); 807f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32* dst = (uint32*)(dst_argb); 808f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 809f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 810f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = dst[0] = src[0]; 811f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src += 1; 812f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 813f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 814f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 815f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = src[0]; 816f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 817f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 818f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 819f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// TODO(fbarchard): Replace 0x7f ^ f with 128-f. bug=607. 820f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Mimics SSSE3 blender 821f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b) * f) >> 7 822f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define BLENDERC(a, b, f, s) (uint32)( \ 823f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang BLENDER1(((a) >> s) & 255, ((b) >> s) & 255, f) << s) 824f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define BLENDER(a, b, f) \ 825f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang BLENDERC(a, b, f, 24) | BLENDERC(a, b, f, 16) | \ 826f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang BLENDERC(a, b, f, 8) | BLENDERC(a, b, f, 0) 827f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 828f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBFilterCols_C(uint8* dst_argb, const uint8* src_argb, 829f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x, int dx) { 830f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint32* src = (const uint32*)(src_argb); 831f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32* dst = (uint32*)(dst_argb); 832f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 833f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 834f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xi = x >> 16; 835f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xf = (x >> 9) & 0x7f; 836f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 a = src[xi]; 837f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 b = src[xi + 1]; 838f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = BLENDER(a, b, xf); 839f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 840f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xi = x >> 16; 841f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xf = (x >> 9) & 0x7f; 842f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang a = src[xi]; 843f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang b = src[xi + 1]; 844f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = BLENDER(a, b, xf); 845f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 846f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 847f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 848f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 849f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xi = x >> 16; 850f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xf = (x >> 9) & 0x7f; 851f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 a = src[xi]; 852f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 b = src[xi + 1]; 853f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = BLENDER(a, b, xf); 854f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 855f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 856f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 857f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleARGBFilterCols64_C(uint8* dst_argb, const uint8* src_argb, 858f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int x32, int dx) { 859f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 x = (int64)(x32); 860f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint32* src = (const uint32*)(src_argb); 861f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32* dst = (uint32*)(dst_argb); 862f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 863f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_width - 1; j += 2) { 864f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 xi = x >> 16; 865f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xf = (x >> 9) & 0x7f; 866f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 a = src[xi]; 867f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 b = src[xi + 1]; 868f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = BLENDER(a, b, xf); 869f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 870f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xi = x >> 16; 871f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang xf = (x >> 9) & 0x7f; 872f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang a = src[xi]; 873f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang b = src[xi + 1]; 874f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[1] = BLENDER(a, b, xf); 875f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang x += dx; 876f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst += 2; 877f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 878f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width & 1) { 879f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int64 xi = x >> 16; 880f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int xf = (x >> 9) & 0x7f; 881f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 a = src[xi]; 882f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang uint32 b = src[xi + 1]; 883f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst[0] = BLENDER(a, b, xf); 884f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 885f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 886f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef BLENDER1 887f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef BLENDERC 888f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef BLENDER 889f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 890f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Scale plane vertically with bilinear interpolation. 891f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScalePlaneVertical(int src_height, 892f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int dst_height, 893f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stride, int dst_stride, 894f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint8* src_argb, uint8* dst_argb, 895f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x, int y, int dy, 896f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int bpp, enum FilterMode filtering) { 897f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // TODO(fbarchard): Allow higher bpp. 898f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width_bytes = dst_width * bpp; 899f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb, 900f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ptrdiff_t src_stride, int dst_width, int source_y_fraction) = 901f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow_C; 902f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; 903f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 904f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(bpp >= 1 && bpp <= 4); 905f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(src_height != 0); 906f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_width > 0); 907f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_height > 0); 908f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb += (x >> 16) * bpp; 909f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_SSSE3) 910f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasSSSE3)) { 911f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_SSSE3; 912f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 16)) { 913f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_SSSE3; 914f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 915f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 916f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 917f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_AVX2) 918f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasAVX2)) { 919f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_AVX2; 920f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 32)) { 921f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_AVX2; 922f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 923f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 924f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 925f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_NEON) 926f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasNEON)) { 927f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_NEON; 928f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 16)) { 929f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_NEON; 930f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 931f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 932f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 933f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_DSPR2) 934f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasDSPR2) && 935f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) && 936f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) { 937f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_DSPR2; 938f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 4)) { 939f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_DSPR2; 940f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 941f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 942f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 943f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_height; ++j) { 944f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int yi; 945f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int yf; 946f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (y > max_y) { 947f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang y = max_y; 948f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 949f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang yi = y >> 16; 950f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang yf = filtering ? ((y >> 8) & 255) : 0; 951f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow(dst_argb, src_argb + yi * src_stride, 952f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_stride, dst_width_bytes, yf); 953f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb += dst_stride; 954f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang y += dy; 955f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 956f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 957f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScalePlaneVertical_16(int src_height, 958f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int dst_height, 959f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int src_stride, int dst_stride, 960f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const uint16* src_argb, uint16* dst_argb, 961f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int x, int y, int dy, 962f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int wpp, enum FilterMode filtering) { 963f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // TODO(fbarchard): Allow higher wpp. 964f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width_words = dst_width * wpp; 965f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang void (*InterpolateRow)(uint16* dst_argb, const uint16* src_argb, 966f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang ptrdiff_t src_stride, int dst_width, int source_y_fraction) = 967f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow_16_C; 968f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; 969f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int j; 970f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(wpp >= 1 && wpp <= 2); 971f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(src_height != 0); 972f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_width > 0); 973f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_height > 0); 974f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_argb += (x >> 16) * wpp; 975f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_16_SSE2) 976f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasSSE2)) { 977f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_16_SSE2; 978f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 16)) { 979f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_16_SSE2; 980f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 981f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 982f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 983f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_16_SSSE3) 984f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasSSSE3)) { 985f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_16_SSSE3; 986f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 16)) { 987f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_16_SSSE3; 988f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 989f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 990f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 991f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_16_AVX2) 992f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasAVX2)) { 993f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_16_AVX2; 994f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 32)) { 995f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_16_AVX2; 996f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 997f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 998f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 999f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_16_NEON) 1000f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasNEON)) { 1001f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_16_NEON; 1002f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 16)) { 1003f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_16_NEON; 1004f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1005f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1006f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 1007f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#if defined(HAS_INTERPOLATEROW_16_DSPR2) 1008f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (TestCpuFlag(kCpuHasDSPR2) && 1009f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) && 1010f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) { 1011f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_Any_16_DSPR2; 1012f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (IS_ALIGNED(dst_width_bytes, 4)) { 1013f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow = InterpolateRow_16_DSPR2; 1014f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1015f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1016f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 1017f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang for (j = 0; j < dst_height; ++j) { 1018f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int yi; 1019f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int yf; 1020f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (y > max_y) { 1021f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang y = max_y; 1022f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1023f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang yi = y >> 16; 1024f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang yf = filtering ? ((y >> 8) & 255) : 0; 1025f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang InterpolateRow(dst_argb, src_argb + yi * src_stride, 1026f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_stride, dst_width_words, yf); 1027f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_argb += dst_stride; 1028f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang y += dy; 1029f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1030f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 1031f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 1032f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Simplify the filtering based on scale factors. 1033f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangenum FilterMode ScaleFilterReduce(int src_width, int src_height, 1034f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int dst_height, 1035f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang enum FilterMode filtering) { 1036f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_width < 0) { 1037f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_width = -src_width; 1038f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1039f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_height < 0) { 1040f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang src_height = -src_height; 1041f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1042f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (filtering == kFilterBox) { 1043f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // If scaling both axis to 0.5 or larger, switch from Box to Bilinear. 1044f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width * 2 >= src_width && dst_height * 2 >= src_height) { 1045f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang filtering = kFilterBilinear; 1046f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1047f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1048f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (filtering == kFilterBilinear) { 1049f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_height == 1) { 1050f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang filtering = kFilterLinear; 1051f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1052f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // TODO(fbarchard): Detect any odd scale factor and reduce to Linear. 1053f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_height == src_height || dst_height * 3 == src_height) { 1054f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang filtering = kFilterLinear; 1055f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1056f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // TODO(fbarchard): Remove 1 pixel wide filter restriction, which is to 1057f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // avoid reading 2 pixels horizontally that causes memory exception. 1058f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_width == 1) { 1059f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang filtering = kFilterNone; 1060f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1061f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1062f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (filtering == kFilterLinear) { 1063f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_width == 1) { 1064f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang filtering = kFilterNone; 1065f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1066f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // TODO(fbarchard): Detect any odd scale factor and reduce to None. 1067f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width == src_width || dst_width * 3 == src_width) { 1068f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang filtering = kFilterNone; 1069f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1070f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1071f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return filtering; 1072f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 1073f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 1074f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Divide num by div and return as 16.16 fixed point result. 1075f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangint FixedDiv_C(int num, int div) { 1076f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return (int)(((int64)(num) << 16) / div); 1077f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 1078f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 1079f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Divide num by div and return as 16.16 fixed point result. 1080f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangint FixedDiv1_C(int num, int div) { 1081f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang return (int)((((int64)(num) << 16) - 0x00010001) / 1082f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang (div - 1)); 1083f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 1084f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 1085f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#define CENTERSTART(dx, s) (dx < 0) ? -((-dx >> 1) + s) : ((dx >> 1) + s) 1086f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 1087f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang// Compute slope values for stepping. 1088f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuangvoid ScaleSlope(int src_width, int src_height, 1089f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int dst_width, int dst_height, 1090f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang enum FilterMode filtering, 1091f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang int* x, int* y, int* dx, int* dy) { 1092f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(x != NULL); 1093f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(y != NULL); 1094f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dx != NULL); 1095f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dy != NULL); 1096f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(src_width != 0); 1097f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(src_height != 0); 1098f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_width > 0); 1099f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang assert(dst_height > 0); 1100f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Check for 1 pixel and avoid FixedDiv overflow. 1101f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width == 1 && src_width >= 32768) { 1102f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_width = src_width; 1103f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1104f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_height == 1 && src_height >= 32768) { 1105f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang dst_height = src_height; 1106f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1107f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (filtering == kFilterBox) { 1108f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Scale step for point sampling duplicates all pixels equally. 1109f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dx = FixedDiv(Abs(src_width), dst_width); 1110f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dy = FixedDiv(src_height, dst_height); 1111f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *x = 0; 1112f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *y = 0; 1113f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else if (filtering == kFilterBilinear) { 1114f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Scale step for bilinear sampling renders last pixel once for upsample. 1115f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width <= Abs(src_width)) { 1116f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dx = FixedDiv(Abs(src_width), dst_width); 1117f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *x = CENTERSTART(*dx, -32768); // Subtract 0.5 (32768) to center filter. 1118f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else if (dst_width > 1) { 1119f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dx = FixedDiv1(Abs(src_width), dst_width); 1120f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *x = 0; 1121f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1122f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_height <= src_height) { 1123f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dy = FixedDiv(src_height, dst_height); 1124f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *y = CENTERSTART(*dy, -32768); // Subtract 0.5 (32768) to center filter. 1125f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else if (dst_height > 1) { 1126f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dy = FixedDiv1(src_height, dst_height); 1127f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *y = 0; 1128f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1129f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else if (filtering == kFilterLinear) { 1130f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Scale step for bilinear sampling renders last pixel once for upsample. 1131f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (dst_width <= Abs(src_width)) { 1132f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dx = FixedDiv(Abs(src_width), dst_width); 1133f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *x = CENTERSTART(*dx, -32768); // Subtract 0.5 (32768) to center filter. 1134f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else if (dst_width > 1) { 1135f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dx = FixedDiv1(Abs(src_width), dst_width); 1136f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *x = 0; 1137f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1138f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dy = FixedDiv(src_height, dst_height); 1139f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *y = *dy >> 1; 1140f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } else { 1141f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Scale step for point sampling duplicates all pixels equally. 1142f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dx = FixedDiv(Abs(src_width), dst_width); 1143f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dy = FixedDiv(src_height, dst_height); 1144f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *x = CENTERSTART(*dx, 0); 1145f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *y = CENTERSTART(*dy, 0); 1146f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1147f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // Negative src_width means horizontally mirror. 1148f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang if (src_width < 0) { 1149f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *x += (dst_width - 1) * *dx; 1150f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang *dx = -*dx; 1151f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang // src_width = -src_width; // Caller must do this. 1152f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang } 1153f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} 1154f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#undef CENTERSTART 1155f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang 1156f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#ifdef __cplusplus 1157f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} // extern "C" 1158f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang} // namespace libyuv 1159f047e7ca6983218eed7703c7afd51fed7bd3b5c9Hangyu Kuang#endif 1160