149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com/* 25fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.com * Copyright 2013 The LibYuv Project Authors. All rights reserved. 349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com * 449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com * Use of this source code is governed by a BSD-style license 549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com * that can be found in the LICENSE file in the root of the source 649bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com * tree. An additional intellectual property rights grant can be found 749bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com * in the file PATENTS. All contributing project authors may 849bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com * be found in the AUTHORS file in the root of the source tree. 949bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com */ 1049bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com 1149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#include "libyuv/scale.h" 1249bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com 1349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#include <assert.h> 1449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#include <string.h> 1549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com 1649bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#include "libyuv/cpu_id.h" 1749bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#include "libyuv/planar_functions.h" // For CopyARGB 1849bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#include "libyuv/row.h" 195fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.com#include "libyuv/scale_row.h" 2049bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com 2149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#ifdef __cplusplus 2249bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.comnamespace libyuv { 2349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.comextern "C" { 2449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#endif 2549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com 265e24e55f980cedec6ea37b184f28b33b7e918922fbarchard@google.comstatic __inline int Abs(int v) { 275e24e55f980cedec6ea37b184f28b33b7e918922fbarchard@google.com return v >= 0 ? v : -v; 285e24e55f980cedec6ea37b184f28b33b7e918922fbarchard@google.com} 295e24e55f980cedec6ea37b184f28b33b7e918922fbarchard@google.com 30dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// CPU agnostic row functions 311f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.comvoid ScaleRowDown2_C(const uint8* src_ptr, ptrdiff_t src_stride, 32dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst, int dst_width) { 33ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 34ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 35dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src_ptr[1]; 36dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = src_ptr[3]; 37dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 38dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 4; 3906f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 40dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 41dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src_ptr[1]; 42dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 43dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 44dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 45b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown2_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 46b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst, int dst_width) { 47b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 48b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 49b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = src_ptr[1]; 50b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[1] = src_ptr[3]; 51b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst += 2; 52b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 4; 53b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 54b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 55b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = src_ptr[1]; 56b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 57b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 58b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 59dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleRowDown2Linear_C(const uint8* src_ptr, ptrdiff_t src_stride, 60dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst, int dst_width) { 61dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* s = src_ptr; 62ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 63ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 64dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = (s[0] + s[1] + 1) >> 1; 65dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = (s[2] + s[3] + 1) >> 1; 66dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 67dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com s += 4; 6806f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 69dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 70dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = (s[0] + s[1] + 1) >> 1; 71dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 72dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 73dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 74b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown2Linear_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 75b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst, int dst_width) { 76b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* s = src_ptr; 77b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 78b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 79b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = (s[0] + s[1] + 1) >> 1; 80b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[1] = (s[2] + s[3] + 1) >> 1; 81b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst += 2; 82b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com s += 4; 83b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 84b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 85b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = (s[0] + s[1] + 1) >> 1; 86b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 87b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 88b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 89dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleRowDown2Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 90dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst, int dst_width) { 91dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* s = src_ptr; 92dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* t = src_ptr + src_stride; 93ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 94ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 95dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 96dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; 97dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 98dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com s += 4; 99dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com t += 4; 10006f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 101dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 102dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 103dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 104dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 105dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 106b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown2Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 107b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst, int dst_width) { 108b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* s = src_ptr; 109b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* t = src_ptr + src_stride; 110b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 111b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 112b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 113b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[1] = (s[2] + s[3] + t[2] + t[3] + 2) >> 2; 114b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst += 2; 115b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com s += 4; 116b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com t += 4; 117b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 118b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 119b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = (s[0] + s[1] + t[0] + t[1] + 2) >> 2; 120b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 121b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 122b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 1231f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.comvoid ScaleRowDown4_C(const uint8* src_ptr, ptrdiff_t src_stride, 124dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst, int dst_width) { 125ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 126ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 127dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src_ptr[2]; 128dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = src_ptr[6]; 129dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 130dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 8; 13106f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 132dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 133dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src_ptr[2]; 134dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 135dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 136dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 137b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown4_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 138b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst, int dst_width) { 139b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 140b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 141b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = src_ptr[2]; 142b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[1] = src_ptr[6]; 143b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst += 2; 144b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 8; 145b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 146b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 147b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = src_ptr[2]; 148b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 149b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 150b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 151dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleRowDown4Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 152dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst, int dst_width) { 153dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com intptr_t stride = src_stride; 154ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 155ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 156dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 157dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 158dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 2] + src_ptr[stride + 3] + 159dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 160dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 161dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 162dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 163dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 8) >> 4; 164dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + 165dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 4] + src_ptr[stride + 5] + 166dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 6] + src_ptr[stride + 7] + 167dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + 168dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + 169dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + 170dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 171dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 8) >> 4; 172dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 173dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 8; 17406f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 175dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 176dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 177dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 178dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 2] + src_ptr[stride + 3] + 179dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 180dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 181dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 182dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 183dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 8) >> 4; 184dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 185dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 186dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 187b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown4Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 188b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst, int dst_width) { 189b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com intptr_t stride = src_stride; 190b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 191b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 192b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 193b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 194b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 2] + src_ptr[stride + 3] + 195b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 196b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 197b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 198b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 199b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 8) >> 4; 200b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + 201b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 4] + src_ptr[stride + 5] + 202b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 6] + src_ptr[stride + 7] + 203b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5] + 204b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7] + 205b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 3 + 4] + src_ptr[stride * 3 + 5] + 206b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 3 + 6] + src_ptr[stride * 3 + 7] + 207b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 8) >> 4; 208b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst += 2; 209b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 8; 210b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 211b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 212b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + 213b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 214b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 2] + src_ptr[stride + 3] + 215b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 0] + src_ptr[stride * 2 + 1] + 216b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 2] + src_ptr[stride * 2 + 3] + 217b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 3 + 0] + src_ptr[stride * 3 + 1] + 218b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 3 + 2] + src_ptr[stride * 3 + 3] + 219b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 8) >> 4; 220b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 221b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 222b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 2231f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.comvoid ScaleRowDown34_C(const uint8* src_ptr, ptrdiff_t src_stride, 224dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst, int dst_width) { 225ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 226dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 227ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 228dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src_ptr[0]; 229dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = src_ptr[1]; 230dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[2] = src_ptr[3]; 231dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 3; 232dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 4; 23306f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 234dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 235dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 236b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown34_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 237b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst, int dst_width) { 238b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 239b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 240b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 241b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = src_ptr[0]; 242b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[1] = src_ptr[1]; 243b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[2] = src_ptr[3]; 244b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst += 3; 245b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 4; 246b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 247b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 248b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 249dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// Filter rows 0 and 1 together, 3 : 1 250dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleRowDown34_0_Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 251dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* d, int dst_width) { 252dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* s = src_ptr; 253dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* t = src_ptr + src_stride; 254ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 255ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 256ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 257dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 258dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 259dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 260dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 261dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 262dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 263dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d[0] = (a0 * 3 + b0 + 2) >> 2; 264dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d[1] = (a1 * 3 + b1 + 2) >> 2; 265dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d[2] = (a2 * 3 + b2 + 2) >> 2; 266dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d += 3; 267dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com s += 4; 268dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com t += 4; 26906f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 270dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 271dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 272b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown34_0_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 273b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* d, int dst_width) { 274b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* s = src_ptr; 275b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* t = src_ptr + src_stride; 276b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 277b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 278b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 279b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 280b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 281b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 282b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 283b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 284b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 285b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d[0] = (a0 * 3 + b0 + 2) >> 2; 286b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d[1] = (a1 * 3 + b1 + 2) >> 2; 287b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d[2] = (a2 * 3 + b2 + 2) >> 2; 288b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d += 3; 289b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com s += 4; 290b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com t += 4; 291b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 292b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 293b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 294dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// Filter rows 1 and 2 together, 1 : 1 295dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleRowDown34_1_Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 296dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* d, int dst_width) { 297dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* s = src_ptr; 298dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* t = src_ptr + src_stride; 299ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 300ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 301ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 302dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 303dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 304dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 305dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 306dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 307dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 308dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d[0] = (a0 + b0 + 1) >> 1; 309dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d[1] = (a1 + b1 + 1) >> 1; 310dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d[2] = (a2 + b2 + 1) >> 1; 311dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com d += 3; 312dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com s += 4; 313dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com t += 4; 31406f730d8a64e1a3095347eb2eb68dc69e1626e03fbarchard@google.com } 315dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 316dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 317b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown34_1_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 318b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* d, int dst_width) { 319b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* s = src_ptr; 320b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* t = src_ptr + src_stride; 321b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 322b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 323b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 324b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; 325b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; 326b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; 327b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; 328b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; 329b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16 b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; 330b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d[0] = (a0 + b0 + 1) >> 1; 331b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d[1] = (a1 + b1 + 1) >> 1; 332b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d[2] = (a2 + b2 + 1) >> 1; 333b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com d += 3; 334b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com s += 4; 335b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com t += 4; 336b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 337b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 338b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 339dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// Scales a single row of pixels using point sampling. 340dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleCols_C(uint8* dst_ptr, const uint8* src_ptr, 341dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int dst_width, int x, int dx) { 342ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 343ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 344dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[0] = src_ptr[x >> 16]; 345dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 346dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[1] = src_ptr[x >> 16]; 347dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 348dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr += 2; 349dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 350dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 351dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[0] = src_ptr[x >> 16]; 352dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 353dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 354dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 355b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleCols_16_C(uint16* dst_ptr, const uint16* src_ptr, 356b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int dst_width, int x, int dx) { 357b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int j; 358b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 359b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = src_ptr[x >> 16]; 360b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com x += dx; 361b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[1] = src_ptr[x >> 16]; 362b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com x += dx; 363b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr += 2; 364b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 365b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 366b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = src_ptr[x >> 16]; 367b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 368b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 369b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 370dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// Scales a single row of pixels up by 2x using point sampling. 371dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleColsUp2_C(uint8* dst_ptr, const uint8* src_ptr, 3721f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.com int dst_width, int x, int dx) { 373ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 374ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 375dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[1] = dst_ptr[0] = src_ptr[0]; 376dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 1; 377dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr += 2; 378dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 379dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 380dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[0] = src_ptr[0]; 381dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 382dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 383dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 384b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleColsUp2_16_C(uint16* dst_ptr, const uint16* src_ptr, 385b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int dst_width, int x, int dx) { 386b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int j; 387b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 388b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[1] = dst_ptr[0] = src_ptr[0]; 389b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 1; 390b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr += 2; 391b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 392b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 393b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = src_ptr[0]; 394b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 395b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 396b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 397dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// (1-f)a + fb can be replaced with a + f(b-a) 398a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com#define BLENDER(a, b, f) (uint8)((int)(a) + \ 399a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com ((int)(f) * ((int)(b) - (int)(a)) >> 16)) 400dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 401dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleFilterCols_C(uint8* dst_ptr, const uint8* src_ptr, 402dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int dst_width, int x, int dx) { 403ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 404ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 405dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int xi = x >> 16; 406dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int a = src_ptr[xi]; 407dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int b = src_ptr[xi + 1]; 408dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 409dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 410dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com xi = x >> 16; 411dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com a = src_ptr[xi]; 412dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com b = src_ptr[xi + 1]; 413dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[1] = BLENDER(a, b, x & 0xffff); 414dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 415dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr += 2; 416dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 417dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 418dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int xi = x >> 16; 419dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int a = src_ptr[xi]; 420dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int b = src_ptr[xi + 1]; 421dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 422dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 423dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 42490a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com 42590a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.comvoid ScaleFilterCols64_C(uint8* dst_ptr, const uint8* src_ptr, 42690a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com int dst_width, int x32, int dx) { 427a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com int64 x = (int64)(x32); 428ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 429ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 43090a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com int64 xi = x >> 16; 43190a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com int a = src_ptr[xi]; 43290a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com int b = src_ptr[xi + 1]; 43390a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 43490a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com x += dx; 43590a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com xi = x >> 16; 43690a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com a = src_ptr[xi]; 43790a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com b = src_ptr[xi + 1]; 43890a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com dst_ptr[1] = BLENDER(a, b, x & 0xffff); 43990a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com x += dx; 44090a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com dst_ptr += 2; 44190a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com } 44290a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com if (dst_width & 1) { 44390a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com int64 xi = x >> 16; 44490a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com int a = src_ptr[xi]; 44590a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com int b = src_ptr[xi + 1]; 44690a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 44790a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com } 44890a36b29d3ffac9ecaa239191c7106c9993dc093fbarchard@google.com} 449dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com#undef BLENDER 450dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 451b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#define BLENDER(a, b, f) (uint16)((int)(a) + \ 452b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com ((int)(f) * ((int)(b) - (int)(a)) >> 16)) 453b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 454b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleFilterCols_16_C(uint16* dst_ptr, const uint16* src_ptr, 455b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int dst_width, int x, int dx) { 456b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int j; 457b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 458b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int xi = x >> 16; 459b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int a = src_ptr[xi]; 460b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int b = src_ptr[xi + 1]; 461b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 462b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com x += dx; 463b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com xi = x >> 16; 464b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com a = src_ptr[xi]; 465b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com b = src_ptr[xi + 1]; 466b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[1] = BLENDER(a, b, x & 0xffff); 467b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com x += dx; 468b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr += 2; 469b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 470b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 471b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int xi = x >> 16; 472b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int a = src_ptr[xi]; 473b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int b = src_ptr[xi + 1]; 474b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 475b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 476b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 477b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 478b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleFilterCols64_16_C(uint16* dst_ptr, const uint16* src_ptr, 479b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int dst_width, int x32, int dx) { 480b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int64 x = (int64)(x32); 481b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int j; 482b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 483b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int64 xi = x >> 16; 484b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int a = src_ptr[xi]; 485b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int b = src_ptr[xi + 1]; 486b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 487b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com x += dx; 488b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com xi = x >> 16; 489b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com a = src_ptr[xi]; 490b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com b = src_ptr[xi + 1]; 491b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[1] = BLENDER(a, b, x & 0xffff); 492b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com x += dx; 493b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr += 2; 494b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 495b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (dst_width & 1) { 496b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int64 xi = x >> 16; 497b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int a = src_ptr[xi]; 498b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int b = src_ptr[xi + 1]; 499b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = BLENDER(a, b, x & 0xffff); 500b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 501b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 502b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#undef BLENDER 503b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 5041f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.comvoid ScaleRowDown38_C(const uint8* src_ptr, ptrdiff_t src_stride, 505dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst, int dst_width) { 506ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 507dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com assert(dst_width % 3 == 0); 508ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 509dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src_ptr[0]; 510dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = src_ptr[3]; 511dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[2] = src_ptr[6]; 512dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 3; 513dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 8; 514dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 515dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 516dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 517b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown38_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 518b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst, int dst_width) { 519b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 520b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert(dst_width % 3 == 0); 521b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < dst_width; x += 3) { 522b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[0] = src_ptr[0]; 523b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[1] = src_ptr[3]; 524b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst[2] = src_ptr[6]; 525b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst += 3; 526b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 8; 527b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 528b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 529b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 530dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// 8x3 -> 3x1 531dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleRowDown38_3_Box_C(const uint8* src_ptr, 532dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com ptrdiff_t src_stride, 533dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst_ptr, int dst_width) { 534dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com intptr_t stride = src_stride; 535ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int i; 536ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 537ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (i = 0; i < dst_width; i += 3) { 538dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 539dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 540dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 2] + src_ptr[stride * 2 + 0] + 541dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) * 542dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com (65536 / 9) >> 16; 543dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 544dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 3] + src_ptr[stride + 4] + 545dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 5] + src_ptr[stride * 2 + 3] + 546dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) * 547dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com (65536 / 9) >> 16; 548dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 549dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 6] + src_ptr[stride + 7] + 550dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) * 551dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com (65536 / 6) >> 16; 552dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 8; 553dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr += 3; 554dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 555dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 556dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 557b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown38_3_Box_16_C(const uint16* src_ptr, 558b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com ptrdiff_t src_stride, 559b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst_ptr, int dst_width) { 560b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com intptr_t stride = src_stride; 561b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int i; 562b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 563b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (i = 0; i < dst_width; i += 3) { 564b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 565b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 566b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 2] + src_ptr[stride * 2 + 0] + 567b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) * 568b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com (65536 / 9) >> 16; 569b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 570b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 3] + src_ptr[stride + 4] + 571b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 5] + src_ptr[stride * 2 + 3] + 572b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) * 573b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com (65536 / 9) >> 16; 574b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 575b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 6] + src_ptr[stride + 7] + 576b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) * 577b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com (65536 / 6) >> 16; 578b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 8; 579b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr += 3; 580b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 581b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 582b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 583dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// 8x2 -> 3x1 584dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleRowDown38_2_Box_C(const uint8* src_ptr, ptrdiff_t src_stride, 585dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst_ptr, int dst_width) { 586dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com intptr_t stride = src_stride; 587ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int i; 588ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 589ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (i = 0; i < dst_width; i += 3) { 590dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 591dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 592dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 2]) * (65536 / 6) >> 16; 593dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 594dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 3] + src_ptr[stride + 4] + 595dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 5]) * (65536 / 6) >> 16; 596dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 597dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr[stride + 6] + src_ptr[stride + 7]) * 598dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com (65536 / 4) >> 16; 599dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_ptr += 8; 600dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr += 3; 601dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 602dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 603dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 604b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleRowDown38_2_Box_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 605b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint16* dst_ptr, int dst_width) { 606b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com intptr_t stride = src_stride; 607b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int i; 608b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert((dst_width % 3 == 0) && (dst_width > 0)); 609b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (i = 0; i < dst_width; i += 3) { 610b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + 611b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 0] + src_ptr[stride + 1] + 612b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 2]) * (65536 / 6) >> 16; 613b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + 614b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 3] + src_ptr[stride + 4] + 615b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 5]) * (65536 / 6) >> 16; 616b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[2] = (src_ptr[6] + src_ptr[7] + 617b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr[stride + 6] + src_ptr[stride + 7]) * 618b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com (65536 / 4) >> 16; 619b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_ptr += 8; 620b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr += 3; 621b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 622b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 623b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 624dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleAddRows_C(const uint8* src_ptr, ptrdiff_t src_stride, 625dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint16* dst_ptr, int src_width, int src_height) { 626ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 627dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com assert(src_width > 0); 628dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com assert(src_height > 0); 629ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < src_width; ++x) { 630dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com const uint8* s = src_ptr + x; 631dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com unsigned int sum = 0u; 632ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int y; 633ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (y = 0; y < src_height; ++y) { 634dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com sum += s[0]; 635dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com s += src_stride; 636dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 637dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com // TODO(fbarchard): Consider limitting height to 256 to avoid overflow. 638dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_ptr[x] = sum < 65535u ? sum : 65535u; 639dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 640dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 641dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 642b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScaleAddRows_16_C(const uint16* src_ptr, ptrdiff_t src_stride, 643b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com uint32* dst_ptr, int src_width, int src_height) { 644b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x; 645b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert(src_width > 0); 646b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert(src_height > 0); 647b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (x = 0; x < src_width; ++x) { 648b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* s = src_ptr + x; 649b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com unsigned int sum = 0u; 650b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int y; 651b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (y = 0; y < src_height; ++y) { 652b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com sum += s[0]; 653b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com s += src_stride; 654b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 655b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com // No risk of overflow here now 656b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_ptr[x] = sum; 657b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 658b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 659b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com 660dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleARGBRowDown2_C(const uint8* src_argb, 6611f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.com ptrdiff_t src_stride, 662dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst_argb, int dst_width) { 663a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com const uint32* src = (const uint32*)(src_argb); 664a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com uint32* dst = (uint32*)(dst_argb); 665dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 666ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 667ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 668dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src[1]; 669dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = src[3]; 670dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src += 4; 671dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 672dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 673dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 674dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src[1]; 675dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 676dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 677dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 678dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleARGBRowDown2Linear_C(const uint8* src_argb, 6791f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.com ptrdiff_t src_stride, 680dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst_argb, int dst_width) { 681ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 682ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width; ++x) { 683dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[0] = (src_argb[0] + src_argb[4] + 1) >> 1; 684dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[1] = (src_argb[1] + src_argb[5] + 1) >> 1; 685dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[2] = (src_argb[2] + src_argb[6] + 1) >> 1; 686dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[3] = (src_argb[3] + src_argb[7] + 1) >> 1; 687dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb += 8; 688dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb += 4; 689dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 690dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 691dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 692dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleARGBRowDown2Box_C(const uint8* src_argb, ptrdiff_t src_stride, 693dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst_argb, int dst_width) { 694ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 695ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width; ++x) { 696dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[0] = (src_argb[0] + src_argb[4] + 697dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride] + src_argb[src_stride + 4] + 2) >> 2; 698dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[1] = (src_argb[1] + src_argb[5] + 699dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride + 1] + src_argb[src_stride + 5] + 2) >> 2; 700dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[2] = (src_argb[2] + src_argb[6] + 701dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride + 2] + src_argb[src_stride + 6] + 2) >> 2; 702dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[3] = (src_argb[3] + src_argb[7] + 703dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride + 3] + src_argb[src_stride + 7] + 2) >> 2; 704dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb += 8; 705dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb += 4; 706dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 707dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 708dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 7091f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.comvoid ScaleARGBRowDownEven_C(const uint8* src_argb, ptrdiff_t src_stride, 710dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int src_stepx, 711dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst_argb, int dst_width) { 712a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com const uint32* src = (const uint32*)(src_argb); 713a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com uint32* dst = (uint32*)(dst_argb); 714dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 715ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 716ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width - 1; x += 2) { 717dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src[0]; 718dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = src[src_stepx]; 719dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src += src_stepx * 2; 720dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 721dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 722dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 723dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src[0]; 724dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 725dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 726dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 727dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleARGBRowDownEvenBox_C(const uint8* src_argb, 728dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com ptrdiff_t src_stride, 729dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int src_stepx, 730dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint8* dst_argb, int dst_width) { 731ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int x; 732ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (x = 0; x < dst_width; ++x) { 733dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[0] = (src_argb[0] + src_argb[4] + 734dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride] + src_argb[src_stride + 4] + 2) >> 2; 735dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[1] = (src_argb[1] + src_argb[5] + 736dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride + 1] + src_argb[src_stride + 5] + 2) >> 2; 737dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[2] = (src_argb[2] + src_argb[6] + 738dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride + 2] + src_argb[src_stride + 6] + 2) >> 2; 739dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb[3] = (src_argb[3] + src_argb[7] + 740dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb[src_stride + 3] + src_argb[src_stride + 7] + 2) >> 2; 741dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src_argb += src_stepx * 4; 742dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst_argb += 4; 743dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 744dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 745dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 746dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// Scales a single row of pixels using point sampling. 747dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleARGBCols_C(uint8* dst_argb, const uint8* src_argb, 748dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int dst_width, int x, int dx) { 749a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com const uint32* src = (const uint32*)(src_argb); 750a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com uint32* dst = (uint32*)(dst_argb); 751ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 752ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 753dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src[x >> 16]; 754dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 755dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = src[x >> 16]; 756dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 757dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 758dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 759dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 760dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src[x >> 16]; 761dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 762dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 763dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 764909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.comvoid ScaleARGBCols64_C(uint8* dst_argb, const uint8* src_argb, 765909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com int dst_width, int x32, int dx) { 766a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com int64 x = (int64)(x32); 767a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com const uint32* src = (const uint32*)(src_argb); 768a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com uint32* dst = (uint32*)(dst_argb); 769ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 770ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 771909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com dst[0] = src[x >> 16]; 772909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com x += dx; 773909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com dst[1] = src[x >> 16]; 774909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com x += dx; 775909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com dst += 2; 776909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com } 777909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com if (dst_width & 1) { 778909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com dst[0] = src[x >> 16]; 779909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com } 780909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com} 781909c76e317028a21db491413b2c5d1a05c1fde5bfbarchard@google.com 782dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// Scales a single row of pixels up by 2x using point sampling. 783dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleARGBColsUp2_C(uint8* dst_argb, const uint8* src_argb, 7841f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.com int dst_width, int x, int dx) { 785a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com const uint32* src = (const uint32*)(src_argb); 786a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com uint32* dst = (uint32*)(dst_argb); 787ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 788ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 789dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = dst[0] = src[0]; 790dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com src += 1; 791dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 792dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 793dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 794dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = src[0]; 795dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 796dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 797dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 798dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com// Mimics SSSE3 blender 799dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com#define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b) * f) >> 7 800a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com#define BLENDERC(a, b, f, s) (uint32)( \ 801dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com BLENDER1(((a) >> s) & 255, ((b) >> s) & 255, f) << s) 802dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com#define BLENDER(a, b, f) \ 803dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com BLENDERC(a, b, f, 24) | BLENDERC(a, b, f, 16) | \ 804dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com BLENDERC(a, b, f, 8) | BLENDERC(a, b, f, 0) 805dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 806dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.comvoid ScaleARGBFilterCols_C(uint8* dst_argb, const uint8* src_argb, 807dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int dst_width, int x, int dx) { 808a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com const uint32* src = (const uint32*)(src_argb); 809a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com uint32* dst = (uint32*)(dst_argb); 810ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 811ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 812dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int xi = x >> 16; 813dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int xf = (x >> 9) & 0x7f; 814dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint32 a = src[xi]; 815dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint32 b = src[xi + 1]; 816dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = BLENDER(a, b, xf); 817dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 818dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com xi = x >> 16; 819dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com xf = (x >> 9) & 0x7f; 820dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com a = src[xi]; 821dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com b = src[xi + 1]; 822dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[1] = BLENDER(a, b, xf); 823dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com x += dx; 824dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst += 2; 825dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 826dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com if (dst_width & 1) { 827dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int xi = x >> 16; 828dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com int xf = (x >> 9) & 0x7f; 829dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint32 a = src[xi]; 830dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com uint32 b = src[xi + 1]; 831dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com dst[0] = BLENDER(a, b, xf); 832dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com } 833dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com} 8346dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com 8356dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.comvoid ScaleARGBFilterCols64_C(uint8* dst_argb, const uint8* src_argb, 8366dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com int dst_width, int x32, int dx) { 837a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com int64 x = (int64)(x32); 838a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com const uint32* src = (const uint32*)(src_argb); 839a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com uint32* dst = (uint32*)(dst_argb); 840ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 841ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_width - 1; j += 2) { 8426dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com int64 xi = x >> 16; 8436dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com int xf = (x >> 9) & 0x7f; 8446dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com uint32 a = src[xi]; 8456dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com uint32 b = src[xi + 1]; 8466dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com dst[0] = BLENDER(a, b, xf); 8476dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com x += dx; 8486dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com xi = x >> 16; 8496dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com xf = (x >> 9) & 0x7f; 8506dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com a = src[xi]; 8516dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com b = src[xi + 1]; 8526dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com dst[1] = BLENDER(a, b, xf); 8536dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com x += dx; 8546dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com dst += 2; 8556dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com } 8566dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com if (dst_width & 1) { 8576dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com int64 xi = x >> 16; 8586dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com int xf = (x >> 9) & 0x7f; 8596dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com uint32 a = src[xi]; 8606dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com uint32 b = src[xi + 1]; 8616dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com dst[0] = BLENDER(a, b, xf); 8626dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com } 8636dc80ab585de785ea3492ac3f8a66f2252edb9f8fbarchard@google.com} 864dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com#undef BLENDER1 865dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com#undef BLENDERC 866dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com#undef BLENDER 867dbe4814361fb8fcbc462bbe45a2f39360e14a982fbarchard@google.com 8685fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.com// Scale plane vertically with bilinear interpolation. 8695fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.comvoid ScalePlaneVertical(int src_height, 8705fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.com int dst_width, int dst_height, 8715fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.com int src_stride, int dst_stride, 8725fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.com const uint8* src_argb, uint8* dst_argb, 8735fcf38cfc8b262f667933492a14b423a341d3795fbarchard@google.com int x, int y, int dy, 874db73518b19f73a3975b4fd58e9d17c8215a39d98fbarchard@google.com int bpp, enum FilterMode filtering) { 875ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com // TODO(fbarchard): Allow higher bpp. 876ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int dst_width_bytes = dst_width * bpp; 877ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb, 878ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com ptrdiff_t src_stride, int dst_width, int source_y_fraction) = 879ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com InterpolateRow_C; 880ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; 881ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int j; 882ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com assert(bpp >= 1 && bpp <= 4); 88399a1298c54dc35348295165745521120818263b8fbarchard@google.com assert(src_height != 0); 88449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com assert(dst_width > 0); 88549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com assert(dst_height > 0); 886ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com src_argb += (x >> 16) * bpp; 88749bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#if defined(HAS_INTERPOLATEROW_SSE2) 888ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && dst_width_bytes >= 16) { 88949bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_Any_SSE2; 890ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 16)) { 89149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_Unaligned_SSE2; 89249bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && 89349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 89449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_SSE2; 89549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 89649bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 89749bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 89849bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#endif 89949bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#if defined(HAS_INTERPOLATEROW_SSSE3) 900ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && dst_width_bytes >= 16) { 90149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_Any_SSSE3; 902ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 16)) { 90349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_Unaligned_SSSE3; 90449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && 90549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 90649bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_SSSE3; 90749bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 90849bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 90949bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 91049bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#endif 9112154de414c1ac41fb434348964c728ccc077ffd3fbarchard@google.com#if defined(HAS_INTERPOLATEROW_AVX2) 912ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && dst_width_bytes >= 32) { 9132154de414c1ac41fb434348964c728ccc077ffd3fbarchard@google.com InterpolateRow = InterpolateRow_Any_AVX2; 914ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 32)) { 9152154de414c1ac41fb434348964c728ccc077ffd3fbarchard@google.com InterpolateRow = InterpolateRow_AVX2; 9162154de414c1ac41fb434348964c728ccc077ffd3fbarchard@google.com } 9172154de414c1ac41fb434348964c728ccc077ffd3fbarchard@google.com } 9182154de414c1ac41fb434348964c728ccc077ffd3fbarchard@google.com#endif 91949bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#if defined(HAS_INTERPOLATEROW_NEON) 920ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && dst_width_bytes >= 16) { 92149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_Any_NEON; 922ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 16)) { 92349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_NEON; 92449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 92549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 92649bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#endif 92749bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#if defined(HAS_INTERPOLATEROWS_MIPS_DSPR2) 928ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (TestCpuFlag(kCpuHasMIPS_DSPR2) && dst_width_bytes >= 4 && 92949bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) && 93049bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) { 93149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_Any_MIPS_DSPR2; 932ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 4)) { 93349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com InterpolateRow = InterpolateRow_MIPS_DSPR2; 93449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 93549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 93649bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#endif 937ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com for (j = 0; j < dst_height; ++j) { 938ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int yi; 939ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com int yf; 94049bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com if (y > max_y) { 94149bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com y = max_y; 94249bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 943ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com yi = y >> 16; 944ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com yf = filtering ? ((y >> 8) & 255) : 0; 945ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com InterpolateRow(dst_argb, src_argb + yi * src_stride, 946ecf5a1446eca7ce9f66600cb08ad7a6e032eac91fbarchard@google.com src_stride, dst_width_bytes, yf); 94749bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com dst_argb += dst_stride; 94849bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com y += dy; 94949bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com } 95049bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com} 951b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.comvoid ScalePlaneVertical_16(int src_height, 952b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int dst_width, int dst_height, 953b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int src_stride, int dst_stride, 954b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const uint16* src_argb, uint16* dst_argb, 955b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int x, int y, int dy, 956b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int wpp, enum FilterMode filtering) { 957b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com // TODO(fbarchard): Allow higher wpp. 958b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int dst_width_words = dst_width * wpp; 959b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com void (*InterpolateRow)(uint16* dst_argb, const uint16* src_argb, 960b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com ptrdiff_t src_stride, int dst_width, int source_y_fraction) = 961b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow_16_C; 962b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; 963b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int j; 964b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert(wpp >= 1 && wpp <= 2); 965b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert(src_height != 0); 966b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert(dst_width > 0); 967b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com assert(dst_height > 0); 968b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_argb += (x >> 16) * wpp; 969b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#if defined(HAS_INTERPOLATEROW_16_SSE2) 970b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && dst_width_bytes >= 16) { 971b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_Any_16_SSE2; 972b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 16)) { 973b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_Unaligned_16_SSE2; 974b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && 975b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 976b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_16_SSE2; 977b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 978b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 979b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 980b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#endif 981b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#if defined(HAS_INTERPOLATEROW_16_SSSE3) 982b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && dst_width_bytes >= 16) { 983b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_Any_16_SSSE3; 984b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 16)) { 985b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_Unaligned_16_SSSE3; 986b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && 987b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 988b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_16_SSSE3; 989b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 990b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 991b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 992b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#endif 993b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#if defined(HAS_INTERPOLATEROW_16_AVX2) 994b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && dst_width_bytes >= 32) { 995b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_Any_16_AVX2; 996b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 32)) { 997b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_16_AVX2; 998b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 999b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 1000b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#endif 1001b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#if defined(HAS_INTERPOLATEROW_16_NEON) 1002b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && dst_width_bytes >= 16) { 1003b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_Any_16_NEON; 1004b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 16)) { 1005b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_16_NEON; 1006b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 1007b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 1008b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#endif 1009b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#if defined(HAS_INTERPOLATEROWS_16_MIPS_DSPR2) 1010b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (TestCpuFlag(kCpuHasMIPS_DSPR2) && dst_width_bytes >= 4 && 1011b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4) && 1012b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) { 1013b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_Any_16_MIPS_DSPR2; 1014b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (IS_ALIGNED(dst_width_bytes, 4)) { 1015b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow = InterpolateRow_16_MIPS_DSPR2; 1016b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 1017b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 1018b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com#endif 1019b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com for (j = 0; j < dst_height; ++j) { 1020b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int yi; 1021b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com int yf; 1022b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com if (y > max_y) { 1023b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com y = max_y; 1024b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 1025b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com yi = y >> 16; 1026b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com yf = filtering ? ((y >> 8) & 255) : 0; 1027b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com InterpolateRow(dst_argb, src_argb + yi * src_stride, 1028b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com src_stride, dst_width_words, yf); 1029b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com dst_argb += dst_stride; 1030b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com y += dy; 1031b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com } 1032b18413e568ae742114eabb8450b180db98a83be0fbarchard@google.com} 103349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com 1034980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com// Simplify the filtering based on scale factors. 1035db73518b19f73a3975b4fd58e9d17c8215a39d98fbarchard@google.comenum FilterMode ScaleFilterReduce(int src_width, int src_height, 1036db73518b19f73a3975b4fd58e9d17c8215a39d98fbarchard@google.com int dst_width, int dst_height, 1037db73518b19f73a3975b4fd58e9d17c8215a39d98fbarchard@google.com enum FilterMode filtering) { 1038ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (src_width < 0) { 1039ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com src_width = -src_width; 1040ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1041ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (src_height < 0) { 1042ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com src_height = -src_height; 1043ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1044ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (filtering == kFilterBox) { 1045ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com // If scaling both axis to 0.5 or larger, switch from Box to Bilinear. 1046ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (dst_width * 2 >= src_width && dst_height * 2 >= src_height) { 1047ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com filtering = kFilterBilinear; 1048ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1049ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com // If scaling to larger, switch from Box to Bilinear. 1050ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (dst_width >= src_width || dst_height >= src_height) { 1051ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com filtering = kFilterBilinear; 1052ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1053ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1054ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (filtering == kFilterBilinear) { 1055ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (src_height == 1) { 1056ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com filtering = kFilterLinear; 1057ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1058ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com // TODO(fbarchard): Detect any odd scale factor and reduce to Linear. 1059ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (dst_height == src_height || dst_height * 3 == src_height) { 1060ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com filtering = kFilterLinear; 1061ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1062a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com // TODO(fbarchard): Remove 1 pixel wide filter restriction, which is to 1063a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com // avoid reading 2 pixels horizontally that causes memory exception. 1064a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com if (src_width == 1) { 1065a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com filtering = kFilterNone; 1066a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com } 1067ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1068ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (filtering == kFilterLinear) { 1069ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (src_width == 1) { 1070ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com filtering = kFilterNone; 1071ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1072ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com // TODO(fbarchard): Detect any odd scale factor and reduce to None. 1073ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com if (dst_width == src_width || dst_width * 3 == src_width) { 1074ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com filtering = kFilterNone; 1075ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1076ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com } 1077ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com return filtering; 1078ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com} 1079ec0cc5bb2dc308a69f870adfbe019d5e5eea9f9ffbarchard@google.com 10805dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com// Divide num by div and return as 16.16 fixed point result. 10815dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.comint FixedDiv_C(int num, int div) { 1082a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com return (int)(((int64)(num) << 16) / div); 10835dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com} 10845dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com 10855dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com// Divide num by div and return as 16.16 fixed point result. 10865dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.comint FixedDiv1_C(int num, int div) { 1087a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com return (int)((((int64)(num) << 16) - 0x00010001) / 10885dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com (div - 1)); 10895dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com} 10905dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com 1091980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com#define CENTERSTART(dx, s) (dx < 0) ? -((-dx >> 1) + s) : ((dx >> 1) + s) 1092980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com 1093980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com// Compute slope values for stepping. 1094980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.comvoid ScaleSlope(int src_width, int src_height, 10955e24e55f980cedec6ea37b184f28b33b7e918922fbarchard@google.com int dst_width, int dst_height, 1096db73518b19f73a3975b4fd58e9d17c8215a39d98fbarchard@google.com enum FilterMode filtering, 1097980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com int* x, int* y, int* dx, int* dy) { 1098980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(x != NULL); 1099980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(y != NULL); 1100980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(dx != NULL); 1101980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(dy != NULL); 1102980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(src_width != 0); 1103980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(src_height != 0); 1104980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(dst_width > 0); 1105980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com assert(dst_height > 0); 1106ac9b96c076f1d62f34fbc9182d1aca46d2f0b75afbarchard@google.com // Check for 1 pixel and avoid FixedDiv overflow. 1107dd4995805827539ee2c5b4b65c7514e62df2d358fbarchard@google.com if (dst_width == 1 && src_width >= 32768) { 1108ac9b96c076f1d62f34fbc9182d1aca46d2f0b75afbarchard@google.com dst_width = src_width; 1109ac9b96c076f1d62f34fbc9182d1aca46d2f0b75afbarchard@google.com } 1110dd4995805827539ee2c5b4b65c7514e62df2d358fbarchard@google.com if (dst_height == 1 && src_height >= 32768) { 1111ac9b96c076f1d62f34fbc9182d1aca46d2f0b75afbarchard@google.com dst_height = src_height; 1112ac9b96c076f1d62f34fbc9182d1aca46d2f0b75afbarchard@google.com } 1113980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com if (filtering == kFilterBox) { 1114980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com // Scale step for point sampling duplicates all pixels equally. 1115980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dx = FixedDiv(Abs(src_width), dst_width); 1116980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dy = FixedDiv(src_height, dst_height); 1117980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *x = 0; 1118980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *y = 0; 1119980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } else if (filtering == kFilterBilinear) { 1120980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com // Scale step for bilinear sampling renders last pixel once for upsample. 1121980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com if (dst_width <= Abs(src_width)) { 1122980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dx = FixedDiv(Abs(src_width), dst_width); 1123a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com *x = CENTERSTART(*dx, -32768); // Subtract 0.5 (32768) to center filter. 1124980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } else if (dst_width > 1) { 11255dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com *dx = FixedDiv1(Abs(src_width), dst_width); 1126980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *x = 0; 1127980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } 1128980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com if (dst_height <= src_height) { 1129980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dy = FixedDiv(src_height, dst_height); 1130a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com *y = CENTERSTART(*dy, -32768); // Subtract 0.5 (32768) to center filter. 1131980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } else if (dst_height > 1) { 11325dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com *dy = FixedDiv1(src_height, dst_height); 1133980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *y = 0; 1134980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } 1135980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } else if (filtering == kFilterLinear) { 1136980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com // Scale step for bilinear sampling renders last pixel once for upsample. 1137980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com if (dst_width <= Abs(src_width)) { 1138980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dx = FixedDiv(Abs(src_width), dst_width); 1139a6b8e0da516350c5395ffcfebd5c49f717c84bddfbarchard@google.com *x = CENTERSTART(*dx, -32768); // Subtract 0.5 (32768) to center filter. 1140980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } else if (dst_width > 1) { 11415dba58cb1ed4117f491267f68351a6079eaed667fbarchard@google.com *dx = FixedDiv1(Abs(src_width), dst_width); 1142980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *x = 0; 1143980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } 1144980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dy = FixedDiv(src_height, dst_height); 1145980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *y = *dy >> 1; 1146980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } else { 1147980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com // Scale step for point sampling duplicates all pixels equally. 1148980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dx = FixedDiv(Abs(src_width), dst_width); 1149980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dy = FixedDiv(src_height, dst_height); 1150980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *x = CENTERSTART(*dx, 0); 1151980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *y = CENTERSTART(*dy, 0); 1152980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } 1153980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com // Negative src_width means horizontally mirror. 1154980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com if (src_width < 0) { 11555e24e55f980cedec6ea37b184f28b33b7e918922fbarchard@google.com *x += (dst_width - 1) * *dx; 1156980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com *dx = -*dx; 11576700a27c97a046d08386dfc7e4486ec285782007fbarchard@google.com // src_width = -src_width; // Caller must do this. 1158980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com } 1159980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com} 1160980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com#undef CENTERSTART 1161980150f7f1c9cf99b1729d0274b46092a47449bdfbarchard@google.com 116249bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#ifdef __cplusplus 116349bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com} // extern "C" 116449bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com} // namespace libyuv 116549bbc1b4f368e7e30fe5f12663b2334a5213752efbarchard@google.com#endif 1166