1ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian/* 2ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * 4ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 5ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 6ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 7ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 8ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 9ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian */ 10ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 11ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/scale.h" 12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <assert.h> 14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <string.h> 15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/cpu_id.h" 17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/planar_functions.h" // For CopyARGB 18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/row.h" 19ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/scale_row.h" 20ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace libyuv { 23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianextern "C" { 24ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 26ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int Abs(int v) { 27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return v >= 0 ? v : -v; 28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// ScaleARGB ARGB, 1/2 31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// This is an optimized version for scaling down a ARGB to 1/2 of 32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// its original size. 33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleARGBDown2(int src_width, int src_height, 34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride, int dst_stride, 36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb, uint8* dst_argb, 37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int dx, int y, int dy, 38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int j; 40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int row_stride = src_stride * (dy >> 16); 41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride, 42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_width) = 43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering == kFilterNone ? ScaleARGBRowDown2_C : 44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_C : 45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2Box_C); 46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(dx == 65536 * 2); // Test scale factor of 2. 47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((dy & 0x1ffff) == 0); // Test vertical scale is multiple of 2. 48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Advance to odd row, even column. 49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering == kFilterBilinear) { 50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += (y >> 16) * src_stride + (x >> 16) * 4; 51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += (y >> 16) * src_stride + ((x >> 16) - 1) * 4; 53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBROWDOWN2_SSE2) 56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 4) && 57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 16) && IS_ALIGNED(row_stride, 16) && 58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2 = filtering == kFilterNone ? ScaleARGBRowDown2_SSE2 : 60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_SSE2 : 61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2Box_SSE2); 62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#elif defined(HAS_SCALEARGBROWDOWN2_NEON) 64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 8) && 65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 4) && IS_ALIGNED(row_stride, 4)) { 66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2 = filtering ? ScaleARGBRowDown2Box_NEON : 67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2_NEON; 68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering == kFilterLinear) { 72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride = 0; 73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < dst_height; ++j) { 75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2(src_argb, src_stride, dst_argb, dst_width); 76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += row_stride; 77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride; 78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// ScaleARGB ARGB, 1/4 82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// This is an optimized version for scaling down a ARGB to 1/4 of 83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// its original size. 84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleARGBDown4Box(int src_width, int src_height, 85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride, int dst_stride, 87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb, uint8* dst_argb, 88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int dx, int y, int dy) { 89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int j; 90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (dst_width * 2 * 4 + 15) & ~15; 92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int row_stride = src_stride * (dy >> 16); 94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride, 95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_width) = ScaleARGBRowDown2Box_C; 96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Advance to odd row, even column. 97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += (y >> 16) * src_stride + (x >> 16) * 4; 98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(dx == 65536 * 4); // Test scale factor of 4. 99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert((dy & 0x3ffff) == 0); // Test vertical scale is multiple of 4. 100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBROWDOWN2_SSE2) 101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 4) && 102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 16) && IS_ALIGNED(row_stride, 16) && 103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2 = ScaleARGBRowDown2Box_SSE2; 105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#elif defined(HAS_SCALEARGBROWDOWN2_NEON) 107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 8) && 108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 4) && IS_ALIGNED(row_stride, 4)) { 109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2 = ScaleARGBRowDown2Box_NEON; 110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < dst_height; ++j) { 113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2(src_argb, src_stride, row, dst_width * 2); 114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2(src_argb + src_stride * 2, src_stride, 115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row + kRowSize, dst_width * 2); 116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDown2(row, kRowSize, dst_argb, dst_width); 117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += row_stride; 118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride; 119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// ScaleARGB ARGB Even 124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// This is an optimized version for scaling down a ARGB to even 125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// multiple of its original size. 126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleARGBDownEven(int src_width, int src_height, 127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride, int dst_stride, 129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb, uint8* dst_argb, 130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int dx, int y, int dy, 131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int j; 133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int col_step = dx >> 16; 134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int row_stride = (dy >> 16) * src_stride; 135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ScaleARGBRowDownEven)(const uint8* src_argb, ptrdiff_t src_stride, 136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_step, uint8* dst_argb, int dst_width) = 137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering ? ScaleARGBRowDownEvenBox_C : ScaleARGBRowDownEven_C; 138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(IS_ALIGNED(src_width, 2)); 139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian assert(IS_ALIGNED(src_height, 2)); 140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += (y >> 16) * src_stride + (x >> 16) * 4; 141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2) 142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 4) && 143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_SSE2 : 145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDownEven_SSE2; 146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#elif defined(HAS_SCALEARGBROWDOWNEVEN_NEON) 148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 4) && 149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 4)) { 150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_NEON : 151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDownEven_NEON; 152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering == kFilterLinear) { 156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride = 0; 157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < dst_height; ++j) { 159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBRowDownEven(src_argb, src_stride, col_step, dst_argb, dst_width); 160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += row_stride; 161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride; 162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scale ARGB down with bilinear interpolation. 166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleARGBBilinearDown(int src_width, int src_height, 167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride, int dst_stride, 169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb, uint8* dst_argb, 170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int dx, int y, int dy, 171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int j; 173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb, 174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ptrdiff_t src_stride, int dst_width, int source_y_fraction) = 175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow_C; 176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb, 177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int x, int dx) = 178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (src_width >= 32768) ? ScaleARGBFilterCols64_C : ScaleARGBFilterCols_C; 179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int64 xlast = x + (int64)(dst_width - 1) * dx; 180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int64 xl = (dx >= 0) ? x : xlast; 181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int64 xr = (dx >= 0) ? xlast : x; 182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int clip_src_width; 183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian xl = (xl >> 16) & ~3; // Left edge aligned. 184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian xr = (xr >> 16) + 1; // Right most pixel used. Bilinear uses 2 pixels. 185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian xr = (xr + 1 + 3) & ~3; // 1 beyond 4 pixel aligned right most pixel. 186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (xr > src_width) { 187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian xr = src_width; 188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_src_width = (int)(xr - xl) * 4; // Width aligned to 4. 190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += xl * 4; 191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x -= (int)(xl << 16); 192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSE2) 193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && clip_src_width >= 16) { 194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSE2; 195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(clip_src_width, 16)) { 196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Unaligned_SSE2; 197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16)) { 198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSE2; 199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSSE3) 204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && clip_src_width >= 16) { 205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSSE3; 206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(clip_src_width, 16)) { 207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Unaligned_SSSE3; 208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16)) { 209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSSE3; 210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_AVX2) 215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && clip_src_width >= 32) { 216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_AVX2; 217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(clip_src_width, 32)) { 218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_AVX2; 219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_NEON) 223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && clip_src_width >= 16) { 224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_NEON; 225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(clip_src_width, 16)) { 226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_NEON; 227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROWS_MIPS_DSPR2) 231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && clip_src_width >= 4 && 232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 4) && IS_ALIGNED(src_stride, 4)) { 233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_MIPS_DSPR2; 234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(clip_src_width, 4)) { 235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_MIPS_DSPR2; 236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3) 240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { 241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3; 242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. 245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate a row of ARGB. 246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, clip_src_width * 4); 248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int max_y = (src_height - 1) << 16; 250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y > max_y) { 251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y = max_y; 252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < dst_height; ++j) { 254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int yi = y >> 16; 255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src = src_argb + yi * src_stride; 256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering == kFilterLinear) { 257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(dst_argb, src, dst_width, x, dx); 258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int yf = (y >> 8) & 255; 260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow(row, src, src_stride, clip_src_width, yf); 261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(dst_argb, row, dst_width, x, dx); 262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride; 264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y += dy; 265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y > max_y) { 266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y = max_y; 267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scale ARGB up with bilinear interpolation. 274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleARGBBilinearUp(int src_width, int src_height, 275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride, int dst_stride, 277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb, uint8* dst_argb, 278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int dx, int y, int dy, 279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int j; 281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb, 282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ptrdiff_t src_stride, int dst_width, int source_y_fraction) = 283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow_C; 284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb, 285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int x, int dx) = 286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C; 287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int max_y = (src_height - 1) << 16; 288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSE2) 289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && dst_width >= 4) { 290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSE2; 291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 4)) { 292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Unaligned_SSE2; 293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSE2; 295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSSE3) 300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && dst_width >= 4) { 301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSSE3; 302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 4)) { 303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Unaligned_SSSE3; 304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSSE3; 306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_AVX2) 311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && dst_width >= 8) { 312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_AVX2; 313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 8)) { 314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_AVX2; 315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_NEON) 319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && dst_width >= 4) { 320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_NEON; 321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 4)) { 322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_NEON; 323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROWS_MIPS_DSPR2) 327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && dst_width >= 1 && 328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride, 4)) { 329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_MIPS_DSPR2; 330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_width >= 32768) { 333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = filtering ? 334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols64_C : ScaleARGBCols64_C; 335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3) 337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { 338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3; 339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBCOLS_SSE2) 342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!filtering && TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { 343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBCols_SSE2; 344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!filtering && src_width * 2 == dst_width && x < 0x8000) { 347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBColsUp2_C; 348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBCOLSUP2_SSE2) 349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8) && 350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && 351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBColsUp2_SSE2; 353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y > max_y) { 358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y = max_y; 359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int yi = y >> 16; 363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src = src_argb + yi * src_stride; 364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (dst_width * 4 + 15) & ~15; 367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rowptr = row; 370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int rowstride = kRowSize; 371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int lasty = yi; 372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(rowptr, src, dst_width, x, dx); 374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_height > 1) { 375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src += src_stride; 376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(rowptr + rowstride, src, dst_width, x, dx); 378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src += src_stride; 379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < dst_height; ++j) { 381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian yi = y >> 16; 382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (yi != lasty) { 383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y > max_y) { 384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y = max_y; 385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian yi = y >> 16; 386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = src_argb + yi * src_stride; 387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (yi != lasty) { 389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(rowptr, src, dst_width, x, dx); 390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rowptr += rowstride; 391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rowstride = -rowstride; 392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian lasty = yi; 393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src += src_stride; 394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering == kFilterLinear) { 397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow(dst_argb, rowptr, 0, dst_width * 4, 0); 398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int yf = (y >> 8) & 255; 400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow(dst_argb, rowptr, rowstride, dst_width * 4, yf); 401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 402ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride; 403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y += dy; 404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef YUVSCALEUP 410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scale YUV to ARGB up with bilinear interpolation. 411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleYUVToARGBBilinearUp(int src_width, int src_height, 412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride_y, 414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride_u, 415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride_v, 416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_stride_argb, 417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_y, 418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, 419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, 420ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, 421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int dx, int y, int dy, 422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int j; 424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*I422ToARGBRow)(const uint8* y_buf, 425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* u_buf, 426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* v_buf, 427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rgb_buf, 428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = I422ToARGBRow_C; 429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_I422TOARGBROW_SSSE3) 430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && src_width >= 8) { 431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_Any_SSSE3; 432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_width, 8)) { 433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_Unaligned_SSSE3; 434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_SSSE3; 436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_I422TOARGBROW_AVX2) 441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && src_width >= 16) { 442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_Any_AVX2; 443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_width, 16)) { 444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_AVX2; 445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_I422TOARGBROW_NEON) 449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && src_width >= 8) { 450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_Any_NEON; 451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_width, 8)) { 452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_NEON; 453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_I422TOARGBROW_MIPS_DSPR2) 457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(src_width, 4) && 458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && 459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && 460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && 461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { 462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2; 463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb, 467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ptrdiff_t src_stride, int dst_width, int source_y_fraction) = 468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow_C; 469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSE2) 470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && dst_width >= 4) { 471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSE2; 472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 4)) { 473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Unaligned_SSE2; 474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSE2; 476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSSE3) 481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && dst_width >= 4) { 482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSSE3; 483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 4)) { 484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Unaligned_SSSE3; 485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSSE3; 487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_AVX2) 492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && dst_width >= 8) { 493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_AVX2; 494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 8)) { 495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_AVX2; 496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_NEON) 500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && dst_width >= 4) { 501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_NEON; 502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_width, 4)) { 503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_NEON; 504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROWS_MIPS_DSPR2) 508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && dst_width >= 1 && 509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { 510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_MIPS_DSPR2; 511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ScaleARGBFilterCols)(uint8* dst_argb, const uint8* src_argb, 515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int x, int dx) = 516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C; 517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_width >= 32768) { 518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = filtering ? 519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols64_C : ScaleARGBCols64_C; 520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3) 522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { 523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3; 524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBCOLS_SSE2) 527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!filtering && TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { 528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBCols_SSE2; 529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!filtering && src_width * 2 == dst_width && x < 0x8000) { 532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBColsUp2_C; 533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBCOLSUP2_SSE2) 534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8) && 535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && 536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols = ScaleARGBColsUp2_SSE2; 538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int max_y = (src_height - 1) << 16; 543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y > max_y) { 544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y = max_y; 545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kYShift = 1; // Shift Y by 1 to convert Y plane to UV coordinate. 547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int yi = y >> 16; 548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int uv_yi = yi >> kYShift; 549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_row_y = src_y + yi * src_stride_y; 550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_row_u = src_u + uv_yi * src_stride_u; 551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_row_v = src_v + uv_yi * src_stride_v; 552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (dst_width * 4 + 15) & ~15; 555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 1 row of ARGB for source conversion. 558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(argb_row, src_width * 4); 559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rowptr = row; 561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int rowstride = kRowSize; 562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int lasty = yi; 563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // TODO(fbarchard): Convert first 2 rows of YUV to ARGB. 565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(rowptr, src_row_y, dst_width, x, dx); 566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_height > 1) { 567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_y += src_stride_y; 568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (yi & 1) { 569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_u += src_stride_u; 570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_v += src_stride_v; 571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(rowptr + rowstride, src_row_y, dst_width, x, dx); 574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_height > 2) { 575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_y += src_stride_y; 576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!(yi & 1)) { 577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_u += src_stride_u; 578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_v += src_stride_v; 579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < dst_height; ++j) { 583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian yi = y >> 16; 584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (yi != lasty) { 585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y > max_y) { 586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y = max_y; 587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian yi = y >> 16; 588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uv_yi = yi >> kYShift; 589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_y = src_y + yi * src_stride_y; 590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_u = src_u + uv_yi * src_stride_u; 591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_v = src_v + uv_yi * src_stride_v; 592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (yi != lasty) { 594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // TODO(fbarchard): Convert the clipped region of row. 595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToARGBRow(src_row_y, src_row_u, src_row_v, argb_row, src_width); 596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBFilterCols(rowptr, argb_row, dst_width, x, dx); 597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rowptr += rowstride; 598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rowstride = -rowstride; 599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian lasty = yi; 600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_y += src_stride_y; 601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (yi & 1) { 602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_u += src_stride_u; 603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_row_v += src_stride_v; 604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering == kFilterLinear) { 608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow(dst_argb, rowptr, 0, dst_width * 4, 0); 609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int yf = (y >> 8) & 255; 611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow(dst_argb, rowptr, rowstride, dst_width * 4, yf); 612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y += dy; 615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row_argb); 618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scale ARGB to/from any dimensions, without interpolation. 622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Fixed point math is used for performance: The upper 16 bits 623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// of x and dx is the integer part of the source position and 624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// the lower 16 bits are the fixed decimal part. 625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleARGBSimple(int src_width, int src_height, 627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride, int dst_stride, 629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb, uint8* dst_argb, 630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int dx, int y, int dy) { 631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int j; 632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ScaleARGBCols)(uint8* dst_argb, const uint8* src_argb, 633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int x, int dx) = 634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (src_width >= 32768) ? ScaleARGBCols64_C : ScaleARGBCols_C; 635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBCOLS_SSE2) 636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { 637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBCols = ScaleARGBCols_SSE2; 638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_width * 2 == dst_width && x < 0x8000) { 641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBCols = ScaleARGBColsUp2_C; 642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SCALEARGBCOLSUP2_SSE2) 643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8) && 644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride, 16) && 645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride, 16)) { 646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBCols = ScaleARGBColsUp2_SSE2; 647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < dst_height; ++j) { 652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBCols(dst_argb, src_argb + (y >> 16) * src_stride, 653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_width, x, dx); 654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride; 655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y += dy; 656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// ScaleARGB a ARGB. 660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// This function in turn calls a scaling function 661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// suitable for handling the desired resolutions. 662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void ScaleARGB(const uint8* src, int src_stride, 663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_width, int src_height, 664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst, int dst_stride, 665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int clip_x, int clip_y, int clip_width, int clip_height, 667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Initial source x/y coordinate and step values as 16.16 fixed point. 669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x = 0; 670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y = 0; 671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dx = 0; 672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dy = 0; 673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // ARGB does not support box filter yet, but allow the user to pass it. 674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Simplify filtering when possible. 675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering = ScaleFilterReduce(src_width, src_height, 676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_width, dst_height, 677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering); 678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative src_height means invert the image. 680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_height < 0) { 681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_height = -src_height; 682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = src + (src_height - 1) * src_stride; 683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride = -src_stride; 684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, 686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian &x, &y, &dx, &dy); 687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_width = Abs(src_width); 688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (clip_x) { 689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int64 clipf = (int64)(clip_x) * dx; 690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x += (clipf & 0xffff); 691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src += (clipf >> 16) * 4; 692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += clip_x * 4; 693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (clip_y) { 695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int64 clipf = (int64)(clip_y) * dy; 696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian y += (clipf & 0xffff); 697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src += (clipf >> 16) * src_stride; 698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += clip_y * dst_stride; 699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Special case for integer step values. 702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (((dx | dy) & 0xffff) == 0) { 703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dx || !dy) { // 1 pixel wide and/or tall. 704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering = kFilterNone; 705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Optimized even scale down. ie 2, 4, 6, 8, 10x. 707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!(dx & 0x10000) && !(dy & 0x10000)) { 708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dx == 0x20000) { 709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Optimized 1/2 downsample. 710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBDown2(src_width, src_height, 711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_width, clip_height, 712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride, dst_stride, src, dst, 713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x, dx, y, dy, filtering); 714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dx == 0x40000 && filtering == kFilterBox) { 717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Optimized 1/4 box downsample. 718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBDown4Box(src_width, src_height, 719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_width, clip_height, 720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride, dst_stride, src, dst, 721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x, dx, y, dy); 722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBDownEven(src_width, src_height, 725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_width, clip_height, 726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride, dst_stride, src, dst, 727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x, dx, y, dy, filtering); 728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Optimized odd scale down. ie 3, 5, 7, 9x. 731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((dx & 0x10000) && (dy & 0x10000)) { 732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian filtering = kFilterNone; 733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dx == 0x10000 && dy == 0x10000) { 734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Straight copy. 735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopy(src + (y >> 16) * src_stride + (x >> 16) * 4, src_stride, 736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst, dst_stride, clip_width, clip_height); 737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dx == 0x10000 && (x & 0xffff) == 0) { 743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Arbitrary scale vertically, but unscaled vertically. 744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScalePlaneVertical(src_height, 745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_width, clip_height, 746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride, dst_stride, src, dst, 747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x, y, dy, 4, filtering); 748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering && dy < 65536) { 751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBBilinearUp(src_width, src_height, 752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_width, clip_height, 753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride, dst_stride, src, dst, 754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x, dx, y, dy, filtering); 755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (filtering) { 758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBBilinearDown(src_width, src_height, 759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_width, clip_height, 760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride, dst_stride, src, dst, 761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x, dx, y, dy, filtering); 762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGBSimple(src_width, src_height, clip_width, clip_height, 765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride, dst_stride, src, dst, 766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x, dx, y, dy); 767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBScaleClip(const uint8* src_argb, int src_stride_argb, 771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_width, int src_height, 772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int clip_x, int clip_y, int clip_width, int clip_height, 775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || src_width == 0 || src_height == 0 || 777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_argb || dst_width <= 0 || dst_height <= 0 || 778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_x < 0 || clip_y < 0 || 779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (clip_x + clip_width) > dst_width || 780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (clip_y + clip_height) > dst_height) { 781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGB(src_argb, src_stride_argb, src_width, src_height, 784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb, dst_stride_argb, dst_width, dst_height, 785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian clip_x, clip_y, clip_width, clip_height, filtering); 786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Scale an ARGB image. 790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBScale(const uint8* src_argb, int src_stride_argb, 792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_width, int src_height, 793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_width, int dst_height, 795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum FilterMode filtering) { 796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || src_width == 0 || src_height == 0 || 797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_argb || dst_width <= 0 || dst_height <= 0) { 798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScaleARGB(src_argb, src_stride_argb, src_width, src_height, 801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb, dst_stride_argb, dst_width, dst_height, 802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 0, 0, dst_width, dst_height, filtering); 803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // extern "C" 808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // namespace libyuv 809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 810