188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org/* 288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org * Copyright 2011 The LibYuv Project Authors. All rights reserved. 388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org * 488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org * Use of this source code is governed by a BSD-style license 588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org * that can be found in the LICENSE file in the root of the source 688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org * tree. An additional intellectual property rights grant can be found 788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org * in the file PATENTS. All contributing project authors may 888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org * be found in the AUTHORS file in the root of the source tree. 988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org */ 1088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 1141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/planar_functions.h" 1288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 1388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#include <string.h> // for memset() 1488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 1541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/cpu_id.h" 1688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#ifdef HAVE_JPEG 1741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/mjpeg_decoder.h" 1888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 1941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/row.h" 2088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 2188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#ifdef __cplusplus 2288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgnamespace libyuv { 2388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgextern "C" { 2488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 2588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 2688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Copy a plane of data 2788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 2888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid CopyPlane(const uint8* src_y, int src_stride_y, 2988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 3088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 3188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 3288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; 3388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 3488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_y == width && 3588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_y == width) { 3688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 3788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 3888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = dst_stride_y = 0; 3988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 4041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Nothing to do. 4141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (src_y == dst_y && src_stride_y == dst_stride_y) { 4241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return; 4341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 4488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_X86) 4588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasX86) && IS_ALIGNED(width, 4)) { 4688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_X86; 4788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 4888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 4988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_SSE2) 5088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32) && 5188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) && 5288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 5388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_SSE2; 5488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 5588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 5688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_ERMS) 5788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasERMS)) { 5888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_ERMS; 5988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 6088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 6188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_NEON) 6288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { 6388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_NEON; 6488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 6588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 6688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_MIPS) 6788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasMIPS)) { 6888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_MIPS; 6988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 7088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 7188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 7288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Copy plane 7388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 7488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow(src_y, dst_y, width); 7588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 7688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_y += dst_stride_y; 7788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 7888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 7988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 8088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 8188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid CopyPlane_16(const uint16* src_y, int src_stride_y, 8288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint16* dst_y, int dst_stride_y, 8388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 8488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 8588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*CopyRow)(const uint16* src, uint16* dst, int width) = CopyRow_16_C; 8688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 8788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_y == width && 8888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_y == width) { 8988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 9088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 9188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = dst_stride_y = 0; 9288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 9388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_16_X86) 9488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasX86) && IS_ALIGNED(width, 4)) { 9588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_16_X86; 9688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 9788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 9888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_16_SSE2) 9988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32) && 10088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) && 10188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 10288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_16_SSE2; 10388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 10488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 10588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_16_ERMS) 10688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasERMS)) { 10788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_16_ERMS; 10888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 10988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 11088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_16_NEON) 11188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { 11288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_16_NEON; 11388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 11488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 11588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_COPYROW_16_MIPS) 11688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasMIPS)) { 11788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow = CopyRow_16_MIPS; 11888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 11988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 12088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 12188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Copy plane 12288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 12388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyRow(src_y, dst_y, width); 12488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 12588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_y += dst_stride_y; 12688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 12788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 12888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 12988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Copy I422. 13088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 13188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I422Copy(const uint8* src_y, int src_stride_y, 13288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_u, int src_stride_u, 13388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_v, int src_stride_v, 13488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 13588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, int dst_stride_u, 13688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_v, int dst_stride_v, 13788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 13888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int halfwidth = (width + 1) >> 1; 13988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_u || !src_v || 14088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org !dst_y || !dst_u || !dst_v || 14188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 14288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 14388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 14488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 14588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 14688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 14788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 14888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_u = src_u + (height - 1) * src_stride_u; 14988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_v = src_v + (height - 1) * src_stride_v; 15088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 15188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_u = -src_stride_u; 15288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_v = -src_stride_v; 15388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 15488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 15588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, height); 15688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, height); 15788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 15888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 15988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 16088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Copy I444. 16188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 16288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I444Copy(const uint8* src_y, int src_stride_y, 16388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_u, int src_stride_u, 16488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_v, int src_stride_v, 16588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 16688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, int dst_stride_u, 16788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_v, int dst_stride_v, 16888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 16988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_u || !src_v || 17088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org !dst_y || !dst_u || !dst_v || 17188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 17288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 17388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 17488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 17588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 17688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 17788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 17888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_u = src_u + (height - 1) * src_stride_u; 17988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_v = src_v + (height - 1) * src_stride_v; 18088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 18188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_u = -src_stride_u; 18288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_v = -src_stride_v; 18388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 18488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 18588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 18688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height); 18788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height); 18888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 18988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 19088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 19188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Copy I400. 19288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 19388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I400ToI400(const uint8* src_y, int src_stride_y, 19488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 19588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 19688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !dst_y || width <= 0 || height == 0) { 19788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 19888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 19988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 20088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 20188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 20288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 20388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 20488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 20588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 20688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 20788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 20888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 20988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert I420 to I400. 21088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 21188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I420ToI400(const uint8* src_y, int src_stride_y, 21288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_u, int src_stride_u, 21388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_v, int src_stride_v, 21488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 21588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 21688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !dst_y || width <= 0 || height == 0) { 21788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 21888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 21988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 22088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 22188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 22288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 22388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 22488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 22588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 22688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 22788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 22888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 22988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Mirror a plane of data. 23088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid MirrorPlane(const uint8* src_y, int src_stride_y, 23188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 23288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 23388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 23488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; 23588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 23688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 23788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 23888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 23988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 24088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 24188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_MIRRORROW_NEON) 24288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) { 24388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorRow = MirrorRow_NEON; 24488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 24588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 24688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_MIRRORROW_SSE2) 24788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16)) { 24888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorRow = MirrorRow_SSE2; 24988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 25088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 25188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_MIRRORROW_SSSE3) 25288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16) && 25388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) && 25488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 25588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorRow = MirrorRow_SSSE3; 25688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 25788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 25888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_MIRRORROW_AVX2) 25988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 32)) { 26088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorRow = MirrorRow_AVX2; 26188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 26288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 26388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 26488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Mirror plane 26588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 26688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorRow(src_y, dst_y, width); 26788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 26888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_y += dst_stride_y; 26988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 27088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 27188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 27288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert YUY2 to I422. 27388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 27488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint YUY2ToI422(const uint8* src_yuy2, int src_stride_yuy2, 27588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 27688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, int dst_stride_u, 27788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_v, int dst_stride_v, 27888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 27988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 28088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*YUY2ToUV422Row)(const uint8* src_yuy2, 28188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, uint8* dst_v, int pix) = 28288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row_C; 28388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int pix) = 28488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow_C; 28588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 28688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 28788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 28888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 28988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_yuy2 = -src_stride_yuy2; 29088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 29188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 29288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_yuy2 == width * 2 && 29388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_y == width && 29488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_u * 2 == width && 29588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_v * 2 == width) { 29688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 29788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 29888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_yuy2 = dst_stride_y = dst_stride_u = dst_stride_v = 0; 29988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 30088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_YUY2TOYROW_SSE2) 30188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 30288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row = YUY2ToUV422Row_Any_SSE2; 30388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow = YUY2ToYRow_Any_SSE2; 30488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 30588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row = YUY2ToUV422Row_Unaligned_SSE2; 30688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow = YUY2ToYRow_Unaligned_SSE2; 30788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16)) { 30888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row = YUY2ToUV422Row_SSE2; 30988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 31088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow = YUY2ToYRow_SSE2; 31188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 31288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 31388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 31488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 31588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 31688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_YUY2TOYROW_AVX2) 31788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 31888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row = YUY2ToUV422Row_Any_AVX2; 31988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow = YUY2ToYRow_Any_AVX2; 32088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 32)) { 32188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row = YUY2ToUV422Row_AVX2; 32288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow = YUY2ToYRow_AVX2; 32388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 32488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 32588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 32688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_YUY2TOYROW_NEON) 32788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 32888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow = YUY2ToYRow_Any_NEON; 32988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (width >= 16) { 33088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row = YUY2ToUV422Row_Any_NEON; 33188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 33288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 33388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow = YUY2ToYRow_NEON; 33488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row = YUY2ToUV422Row_NEON; 33588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 33688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 33788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 33888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 33988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 34088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); 34188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org YUY2ToYRow(src_yuy2, dst_y, width); 34288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_yuy2 += src_stride_yuy2; 34388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_y += dst_stride_y; 34488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_u += dst_stride_u; 34588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_v += dst_stride_v; 34688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 34788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 34888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 34988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 35088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert UYVY to I422. 35188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 35288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint UYVYToI422(const uint8* src_uyvy, int src_stride_uyvy, 35388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 35488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, int dst_stride_u, 35588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_v, int dst_stride_v, 35688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 35788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 35888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*UYVYToUV422Row)(const uint8* src_uyvy, 35988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, uint8* dst_v, int pix) = 36088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row_C; 36188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*UYVYToYRow)(const uint8* src_uyvy, 36288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int pix) = UYVYToYRow_C; 36388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 36488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 36588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 36688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 36788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_uyvy = -src_stride_uyvy; 36888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 36988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 37088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_uyvy == width * 2 && 37188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_y == width && 37288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_u * 2 == width && 37388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_v * 2 == width) { 37488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 37588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 37688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_uyvy = dst_stride_y = dst_stride_u = dst_stride_v = 0; 37788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 37888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_UYVYTOYROW_SSE2) 37988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 38088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row = UYVYToUV422Row_Any_SSE2; 38188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow = UYVYToYRow_Any_SSE2; 38288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 38388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row = UYVYToUV422Row_Unaligned_SSE2; 38488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow = UYVYToYRow_Unaligned_SSE2; 38588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16)) { 38688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row = UYVYToUV422Row_SSE2; 38788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 38888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow = UYVYToYRow_SSE2; 38988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 39088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 39188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 39288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 39388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 39488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_UYVYTOYROW_AVX2) 39588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 39688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row = UYVYToUV422Row_Any_AVX2; 39788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow = UYVYToYRow_Any_AVX2; 39888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 32)) { 39988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row = UYVYToUV422Row_AVX2; 40088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow = UYVYToYRow_AVX2; 40188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 40288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 40388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 40488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_UYVYTOYROW_NEON) 40588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 40688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow = UYVYToYRow_Any_NEON; 40788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (width >= 16) { 40888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row = UYVYToUV422Row_Any_NEON; 40988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 41088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 41188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow = UYVYToYRow_NEON; 41288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row = UYVYToUV422Row_NEON; 41388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 41488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 41588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 41688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 41788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 41888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToUV422Row(src_uyvy, dst_u, dst_v, width); 41988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org UYVYToYRow(src_uyvy, dst_y, width); 42088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_uyvy += src_stride_uyvy; 42188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_y += dst_stride_y; 42288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_u += dst_stride_u; 42388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_v += dst_stride_v; 42488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 42588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 42688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 42788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 42888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Mirror I400 with optional flipping 42988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 43088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I400Mirror(const uint8* src_y, int src_stride_y, 43188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 43288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 43388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !dst_y || 43488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 43588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 43688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 43788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 43888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 43988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 44088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 44188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 44288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 44388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 44488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 44588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 44688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 44788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 44888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Mirror I420 with optional flipping 44988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 45088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I420Mirror(const uint8* src_y, int src_stride_y, 45188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_u, int src_stride_u, 45288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_v, int src_stride_v, 45388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 45488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, int dst_stride_u, 45588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_v, int dst_stride_v, 45688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 45788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int halfwidth = (width + 1) >> 1; 45888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int halfheight = (height + 1) >> 1; 45988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_u || !src_v || !dst_y || !dst_u || !dst_v || 46088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 46188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 46288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 46388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 46488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 46588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 46688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org halfheight = (height + 1) >> 1; 46788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 46888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_u = src_u + (halfheight - 1) * src_stride_u; 46988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_v = src_v + (halfheight - 1) * src_stride_v; 47088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 47188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_u = -src_stride_u; 47288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_v = -src_stride_v; 47388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 47488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 47588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_y) { 47688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 47788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 47888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); 47988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MirrorPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); 48088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 48188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 48288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 48388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// ARGB mirror. 48488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 48588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBMirror(const uint8* src_argb, int src_stride_argb, 48688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 48788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 48888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 48988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) = 49088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMirrorRow_C; 49188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0) { 49288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 49388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 49488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 49588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 49688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 49788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 49888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 49988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 50088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 50188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBMIRRORROW_SSSE3) 50288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4) && 50388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) && 50488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 50588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMirrorRow = ARGBMirrorRow_SSSE3; 50688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 50788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 50888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBMIRRORROW_AVX2) 50988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 8)) { 51088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMirrorRow = ARGBMirrorRow_AVX2; 51188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 51288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 51388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBMIRRORROW_NEON) 51488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 4)) { 51588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMirrorRow = ARGBMirrorRow_NEON; 51688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 51788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 51888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 51988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Mirror plane 52088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 52188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMirrorRow(src_argb, dst_argb, width); 52288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 52388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 52488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 52588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 52688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 52788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 52888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Get a blender that optimized for the CPU, alignment and pixel count. 52988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// As there are 6 blenders to choose from, the caller should try to use 53088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// the same blend function for all pixels if possible. 53188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 53288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgARGBBlendRow GetARGBBlend() { 53388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1, 53488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int width) = ARGBBlendRow_C; 53588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBBLENDROW_SSSE3) 53688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3)) { 53788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBBlendRow = ARGBBlendRow_SSSE3; 53888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return ARGBBlendRow; 53988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 54088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 54188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBBLENDROW_SSE2) 54288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2)) { 54388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBBlendRow = ARGBBlendRow_SSE2; 54488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 54588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 54688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBBLENDROW_NEON) 54788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON)) { 54888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBBlendRow = ARGBBlendRow_NEON; 54988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 55088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 55188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return ARGBBlendRow; 55288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 55388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 55488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Alpha Blend 2 ARGB images and store to destination. 55588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 55688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBBlend(const uint8* src_argb0, int src_stride_argb0, 55788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_argb1, int src_stride_argb1, 55888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 55988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 56088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 56188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1, 56288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int width) = GetARGBBlend(); 56388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 56488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 56588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 56688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 56788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 56888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 56988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb = dst_argb + (height - 1) * dst_stride_argb; 57088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = -dst_stride_argb; 57188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 57288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 57388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb0 == width * 4 && 57488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb1 == width * 4 && 57588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 57688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 57788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 57888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 57988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 58088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 58188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 58288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBBlendRow(src_argb0, src_argb1, dst_argb, width); 58388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb0 += src_stride_argb0; 58488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb1 += src_stride_argb1; 58588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 58688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 58788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 58888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 58988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 59088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Multiply 2 ARGB images and store to destination. 59188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 59288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBMultiply(const uint8* src_argb0, int src_stride_argb0, 59388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_argb1, int src_stride_argb1, 59488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 59588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 59688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 59788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBMultiplyRow)(const uint8* src0, const uint8* src1, uint8* dst, 59888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBMultiplyRow_C; 59988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 60088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 60188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 60288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 60388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 60488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 60588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb = dst_argb + (height - 1) * dst_stride_argb; 60688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = -dst_stride_argb; 60788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 60888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 60988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb0 == width * 4 && 61088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb1 == width * 4 && 61188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 61288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 61388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 61488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 61588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 61688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBMULTIPLYROW_SSE2) 61788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 4) { 61888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMultiplyRow = ARGBMultiplyRow_Any_SSE2; 61988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 62088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMultiplyRow = ARGBMultiplyRow_SSE2; 62188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 62288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 62388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 62488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBMULTIPLYROW_AVX2) 62588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 8) { 62688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMultiplyRow = ARGBMultiplyRow_Any_AVX2; 62788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 62888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMultiplyRow = ARGBMultiplyRow_AVX2; 62988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 63088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 63188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 63288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBMULTIPLYROW_NEON) 63388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 63488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMultiplyRow = ARGBMultiplyRow_Any_NEON; 63588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 63688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMultiplyRow = ARGBMultiplyRow_NEON; 63788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 63888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 63988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 64088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 64188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Multiply plane 64288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 64388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBMultiplyRow(src_argb0, src_argb1, dst_argb, width); 64488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb0 += src_stride_argb0; 64588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb1 += src_stride_argb1; 64688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 64788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 64888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 64988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 65088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 65188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Add 2 ARGB images and store to destination. 65288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 65388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBAdd(const uint8* src_argb0, int src_stride_argb0, 65488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_argb1, int src_stride_argb1, 65588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 65688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 65788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 65888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBAddRow)(const uint8* src0, const uint8* src1, uint8* dst, 65988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBAddRow_C; 66088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 66188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 66288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 66388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 66488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 66588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 66688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb = dst_argb + (height - 1) * dst_stride_argb; 66788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = -dst_stride_argb; 66888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 66988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 67088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb0 == width * 4 && 67188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb1 == width * 4 && 67288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 67388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 67488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 67588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 67688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 67788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBADDROW_SSE2) && defined(_MSC_VER) 67888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2)) { 67988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow = ARGBAddRow_SSE2; 68088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 68188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 68288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBADDROW_SSE2) && !defined(_MSC_VER) 68388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 4) { 68488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow = ARGBAddRow_Any_SSE2; 68588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 68688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow = ARGBAddRow_SSE2; 68788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 68888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 68988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 69088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBADDROW_AVX2) 69188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 8) { 69288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow = ARGBAddRow_Any_AVX2; 69388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 69488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow = ARGBAddRow_AVX2; 69588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 69688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 69788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 69888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBADDROW_NEON) 69988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 70088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow = ARGBAddRow_Any_NEON; 70188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 70288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow = ARGBAddRow_NEON; 70388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 70488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 70588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 70688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 70788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Add plane 70888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 70988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAddRow(src_argb0, src_argb1, dst_argb, width); 71088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb0 += src_stride_argb0; 71188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb1 += src_stride_argb1; 71288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 71388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 71488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 71588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 71688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 71788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Subtract 2 ARGB images and store to destination. 71888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 71988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBSubtract(const uint8* src_argb0, int src_stride_argb0, 72088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_argb1, int src_stride_argb1, 72188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 72288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 72388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 72488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBSubtractRow)(const uint8* src0, const uint8* src1, uint8* dst, 72588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBSubtractRow_C; 72688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 72788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 72888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 72988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 73088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 73188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 73288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb = dst_argb + (height - 1) * dst_stride_argb; 73388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = -dst_stride_argb; 73488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 73588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 73688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb0 == width * 4 && 73788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb1 == width * 4 && 73888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 73988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 74088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 74188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 74288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 74388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSUBTRACTROW_SSE2) 74488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 4) { 74588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSubtractRow = ARGBSubtractRow_Any_SSE2; 74688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 74788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSubtractRow = ARGBSubtractRow_SSE2; 74888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 74988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 75088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 75188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSUBTRACTROW_AVX2) 75288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 8) { 75388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSubtractRow = ARGBSubtractRow_Any_AVX2; 75488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 75588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSubtractRow = ARGBSubtractRow_AVX2; 75688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 75788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 75888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 75988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSUBTRACTROW_NEON) 76088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 76188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSubtractRow = ARGBSubtractRow_Any_NEON; 76288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 76388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSubtractRow = ARGBSubtractRow_NEON; 76488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 76588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 76688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 76788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 76888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Subtract plane 76988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 77088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSubtractRow(src_argb0, src_argb1, dst_argb, width); 77188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb0 += src_stride_argb0; 77288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb1 += src_stride_argb1; 77388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 77488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 77588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 77688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 77788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 77888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert I422 to BGRA. 77988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 78088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I422ToBGRA(const uint8* src_y, int src_stride_y, 78188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_u, int src_stride_u, 78288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_v, int src_stride_v, 78388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_bgra, int dst_stride_bgra, 78488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 78588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 78688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*I422ToBGRARow)(const uint8* y_buf, 78788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* u_buf, 78888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* v_buf, 78988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* rgb_buf, 79088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = I422ToBGRARow_C; 79188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_u || !src_v || 79288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org !dst_bgra || 79388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 79488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 79588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 79688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 79788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 79888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 79988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_bgra = dst_bgra + (height - 1) * dst_stride_bgra; 80088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_bgra = -dst_stride_bgra; 80188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 80288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 80388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_y == width && 80488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_u * 2 == width && 80588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_v * 2 == width && 80688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_bgra == width * 4) { 80788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 80888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 80988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = src_stride_u = src_stride_v = dst_stride_bgra = 0; 81088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 81188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_I422TOBGRAROW_NEON) 81288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON)) { 81388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToBGRARow = I422ToBGRARow_Any_NEON; 81488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 81588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToBGRARow = I422ToBGRARow_NEON; 81688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 81788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 81888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_I422TOBGRAROW_SSSE3) 81988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 82088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToBGRARow = I422ToBGRARow_Any_SSSE3; 82188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 82288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToBGRARow = I422ToBGRARow_Unaligned_SSSE3; 82388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(dst_bgra, 16) && IS_ALIGNED(dst_stride_bgra, 16)) { 82488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToBGRARow = I422ToBGRARow_SSSE3; 82588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 82688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 82788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 82888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_I422TOBGRAROW_MIPS_DSPR2) 82988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) && 83088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && 83188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && 83288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && 83388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_bgra, 4) && IS_ALIGNED(dst_stride_bgra, 4)) { 83488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToBGRARow = I422ToBGRARow_MIPS_DSPR2; 83588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 83688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 83788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 83888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 83988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToBGRARow(src_y, src_u, src_v, dst_bgra, width); 84088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_bgra += dst_stride_bgra; 84188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 84288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_u += src_stride_u; 84388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_v += src_stride_v; 84488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 84588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 84688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 84788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 84888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert I422 to ABGR. 84988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 85088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I422ToABGR(const uint8* src_y, int src_stride_y, 85188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_u, int src_stride_u, 85288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_v, int src_stride_v, 85388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_abgr, int dst_stride_abgr, 85488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 85588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 85688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*I422ToABGRRow)(const uint8* y_buf, 85788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* u_buf, 85888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* v_buf, 85988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* rgb_buf, 86088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = I422ToABGRRow_C; 86188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_u || !src_v || 86288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org !dst_abgr || 86388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 86488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 86588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 86688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 86788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 86888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 86988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_abgr = dst_abgr + (height - 1) * dst_stride_abgr; 87088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_abgr = -dst_stride_abgr; 87188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 87288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 87388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_y == width && 87488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_u * 2 == width && 87588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_v * 2 == width && 87688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_abgr == width * 4) { 87788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 87888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 87988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = src_stride_u = src_stride_v = dst_stride_abgr = 0; 88088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 88188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_I422TOABGRROW_NEON) 88288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON)) { 88388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToABGRRow = I422ToABGRRow_Any_NEON; 88488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 88588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToABGRRow = I422ToABGRRow_NEON; 88688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 88788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 88888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_I422TOABGRROW_SSSE3) 88988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 89088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToABGRRow = I422ToABGRRow_Any_SSSE3; 89188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 89288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToABGRRow = I422ToABGRRow_Unaligned_SSSE3; 89388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(dst_abgr, 16) && IS_ALIGNED(dst_stride_abgr, 16)) { 89488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToABGRRow = I422ToABGRRow_SSSE3; 89588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 89688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 89788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 89888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 89988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 90088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 90188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToABGRRow(src_y, src_u, src_v, dst_abgr, width); 90288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_abgr += dst_stride_abgr; 90388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 90488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_u += src_stride_u; 90588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_v += src_stride_v; 90688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 90788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 90888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 90988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 91088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert I422 to RGBA. 91188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 91288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I422ToRGBA(const uint8* src_y, int src_stride_y, 91388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_u, int src_stride_u, 91488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_v, int src_stride_v, 91588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_rgba, int dst_stride_rgba, 91688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 91788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 91888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*I422ToRGBARow)(const uint8* y_buf, 91988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* u_buf, 92088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* v_buf, 92188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* rgb_buf, 92288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = I422ToRGBARow_C; 92388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_u || !src_v || 92488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org !dst_rgba || 92588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 92688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 92788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 92888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 92988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 93088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 93188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; 93288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_rgba = -dst_stride_rgba; 93388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 93488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 93588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_y == width && 93688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_u * 2 == width && 93788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_v * 2 == width && 93888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_rgba == width * 4) { 93988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 94088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 94188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = src_stride_u = src_stride_v = dst_stride_rgba = 0; 94288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 94388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_I422TORGBAROW_NEON) 94488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON)) { 94588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToRGBARow = I422ToRGBARow_Any_NEON; 94688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 94788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToRGBARow = I422ToRGBARow_NEON; 94888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 94988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 95088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_I422TORGBAROW_SSSE3) 95188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 95288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToRGBARow = I422ToRGBARow_Any_SSSE3; 95388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 95488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToRGBARow = I422ToRGBARow_Unaligned_SSSE3; 95588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(dst_rgba, 16) && IS_ALIGNED(dst_stride_rgba, 16)) { 95688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToRGBARow = I422ToRGBARow_SSSE3; 95788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 95888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 95988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 96088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 96188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 96288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 96388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org I422ToRGBARow(src_y, src_u, src_v, dst_rgba, width); 96488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_rgba += dst_stride_rgba; 96588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 96688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_u += src_stride_u; 96788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_v += src_stride_v; 96888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 96988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 97088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 97188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 97288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert NV12 to RGB565. 97388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 97488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint NV12ToRGB565(const uint8* src_y, int src_stride_y, 97588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_uv, int src_stride_uv, 97688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_rgb565, int dst_stride_rgb565, 97788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 97888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 97988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*NV12ToRGB565Row)(const uint8* y_buf, 98088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* uv_buf, 98188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* rgb_buf, 98288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = NV12ToRGB565Row_C; 98388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_uv || !dst_rgb565 || 98488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 98588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 98688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 98788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 98888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 98988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 99088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; 99188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_rgb565 = -dst_stride_rgb565; 99288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 99388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_NV12TORGB565ROW_SSSE3) 99488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 99588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV12ToRGB565Row = NV12ToRGB565Row_Any_SSSE3; 99688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 99788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV12ToRGB565Row = NV12ToRGB565Row_SSSE3; 99888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 99988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 100088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_NV12TORGB565ROW_NEON) 100188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 100288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV12ToRGB565Row = NV12ToRGB565Row_Any_NEON; 100388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 100488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV12ToRGB565Row = NV12ToRGB565Row_NEON; 100588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 100688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 100788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 100888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 100988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 101088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV12ToRGB565Row(src_y, src_uv, dst_rgb565, width); 101188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_rgb565 += dst_stride_rgb565; 101288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 101388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (y & 1) { 101488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_uv += src_stride_uv; 101588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 101688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 101788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 101888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 101988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 102088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert NV21 to RGB565. 102188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 102288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint NV21ToRGB565(const uint8* src_y, int src_stride_y, 102388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_vu, int src_stride_vu, 102488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_rgb565, int dst_stride_rgb565, 102588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 102688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 102788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*NV21ToRGB565Row)(const uint8* y_buf, 102888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_vu, 102988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* rgb_buf, 103088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = NV21ToRGB565Row_C; 103188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !src_vu || !dst_rgb565 || 103288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 103388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 103488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 103588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 103688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 103788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 103888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; 103988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_rgb565 = -dst_stride_rgb565; 104088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 104188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_NV21TORGB565ROW_SSSE3) 104288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 104388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV21ToRGB565Row = NV21ToRGB565Row_Any_SSSE3; 104488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 104588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV21ToRGB565Row = NV21ToRGB565Row_SSSE3; 104688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 104788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 104888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_NV21TORGB565ROW_NEON) 104988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 105088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV21ToRGB565Row = NV21ToRGB565Row_Any_NEON; 105188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 105288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV21ToRGB565Row = NV21ToRGB565Row_NEON; 105388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 105488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 105588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 105688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 105788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 105888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org NV21ToRGB565Row(src_y, src_vu, dst_rgb565, width); 105988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_rgb565 += dst_stride_rgb565; 106088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 106188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (y & 1) { 106288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_vu += src_stride_vu; 106388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 106488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 106588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 106688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 106788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 106888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 106988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgvoid SetPlane(uint8* dst_y, int dst_stride_y, 107088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height, 107188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint32 value) { 107288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 107388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint32 v32 = value | (value << 8) | (value << 16) | (value << 24); 107488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*SetRow)(uint8* dst, uint32 value, int pix) = SetRow_C; 107588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 107688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_stride_y == width) { 107788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 107888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 107988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_y = 0; 108088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 108188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SETROW_NEON) 108288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && 108388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(width, 16) && 108488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 108588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SetRow = SetRow_NEON; 108688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 108788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 108888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SETROW_X86) 108988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasX86) && IS_ALIGNED(width, 4)) { 109088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SetRow = SetRow_X86; 109188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 109288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 109388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 109488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Set plane 109588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 109688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SetRow(dst_y, v32, width); 109788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_y += dst_stride_y; 109888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 109988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 110088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 110188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Draw a rectangle into I420 110288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 110388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint I420Rect(uint8* dst_y, int dst_stride_y, 110488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_u, int dst_stride_u, 110588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_v, int dst_stride_v, 110688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int x, int y, 110788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height, 110888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int value_y, int value_u, int value_v) { 110988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int halfwidth = (width + 1) >> 1; 111088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int halfheight = (height + 1) >> 1; 111188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* start_y = dst_y + y * dst_stride_y + x; 111288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* start_u = dst_u + (y / 2) * dst_stride_u + (x / 2); 111388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* start_v = dst_v + (y / 2) * dst_stride_v + (x / 2); 111488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_y || !dst_u || !dst_v || 111588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height <= 0 || 111688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org x < 0 || y < 0 || 111788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org value_y < 0 || value_y > 255 || 111888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org value_u < 0 || value_u > 255 || 111988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org value_v < 0 || value_v > 255) { 112088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 112188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 112288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 112388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SetPlane(start_y, dst_stride_y, width, height, value_y); 112488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SetPlane(start_u, dst_stride_u, halfwidth, halfheight, value_u); 112588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SetPlane(start_v, dst_stride_v, halfwidth, halfheight, value_v); 112688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 112788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 112888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 112988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Draw a rectangle into ARGB 113088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 113188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBRect(uint8* dst_argb, int dst_stride_argb, 113288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int dst_x, int dst_y, 113388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height, 113488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint32 value) { 113588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_argb || 113688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height <= 0 || 113788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_x < 0 || dst_y < 0) { 113888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 113988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 114088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_y * dst_stride_argb + dst_x * 4; 114188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 114288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_stride_argb == width * 4) { 114388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 114488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 114588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = 0; 114688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 114788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SETROW_NEON) 114888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16) && 114988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 115088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSetRows_NEON(dst_argb, value, width, dst_stride_argb, height); 115188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 115288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 115388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 115488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SETROW_X86) 115588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasX86)) { 115688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSetRows_X86(dst_argb, value, width, dst_stride_argb, height); 115788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 115888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 115988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 116088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSetRows_C(dst_argb, value, width, dst_stride_argb, height); 116188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 116288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 116388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 116488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert unattentuated ARGB to preattenuated ARGB. 116588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// An unattenutated ARGB alpha blend uses the formula 116688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// p = a * f + (1 - a) * b 116788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// where 116888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// p is output pixel 116988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// f is foreground pixel 117088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// b is background pixel 117188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// a is alpha value from foreground pixel 117288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// An preattenutated ARGB alpha blend uses the formula 117388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// p = f + (1 - a) * b 117488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// where 117588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// f is foreground pixel premultiplied by alpha 117688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 117788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 117888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBAttenuate(const uint8* src_argb, int src_stride_argb, 117988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 118088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 118188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 118288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBAttenuateRow)(const uint8* src_argb, uint8* dst_argb, 118388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBAttenuateRow_C; 118488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0) { 118588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 118688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 118788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 118888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 118988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 119088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 119188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 119288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 119388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 119488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 119588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 119688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 119788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 119888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 119988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBATTENUATEROW_SSE2) 120088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 4 && 120188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) && 120288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 120388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_Any_SSE2; 120488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 120588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_SSE2; 120688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 120788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 120888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 120988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBATTENUATEROW_SSSE3) 121088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 4) { 121188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; 121288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 121388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_SSSE3; 121488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 121588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 121688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 121788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBATTENUATEROW_AVX2) 121888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 8) { 121988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_Any_AVX2; 122088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 122188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_AVX2; 122288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 122388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 122488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 122588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBATTENUATEROW_NEON) 122688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 122788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_Any_NEON; 122888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 122988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow = ARGBAttenuateRow_NEON; 123088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 123188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 123288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 123388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 123488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 123588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBAttenuateRow(src_argb, dst_argb, width); 123688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 123788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 123888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 123988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 124088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 124188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 124288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert preattentuated ARGB to unattenuated ARGB. 124388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 124488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBUnattenuate(const uint8* src_argb, int src_stride_argb, 124588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 124688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 124788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 124888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBUnattenuateRow)(const uint8* src_argb, uint8* dst_argb, 124988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBUnattenuateRow_C; 125088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0) { 125188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 125288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 125388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 125488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 125588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 125688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 125788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 125888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 125988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 126088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 126188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 126288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 126388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 126488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 126588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBUNATTENUATEROW_SSE2) 126688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 4) { 126788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBUnattenuateRow = ARGBUnattenuateRow_Any_SSE2; 126888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 126988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBUnattenuateRow = ARGBUnattenuateRow_SSE2; 127088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 127188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 127288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 127388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBUNATTENUATEROW_AVX2) 127488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 8) { 127588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBUnattenuateRow = ARGBUnattenuateRow_Any_AVX2; 127688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 127788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBUnattenuateRow = ARGBUnattenuateRow_AVX2; 127888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 127988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 128088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 128188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// TODO(fbarchard): Neon version. 128288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 128388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 128488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBUnattenuateRow(src_argb, dst_argb, width); 128588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 128688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 128788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 128888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 128988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 129088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 129188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Convert ARGB to Grayed ARGB. 129288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 129388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBGrayTo(const uint8* src_argb, int src_stride_argb, 129488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 129588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 129688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 129788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBGrayRow)(const uint8* src_argb, uint8* dst_argb, 129888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBGrayRow_C; 129988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0) { 130088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 130188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 130288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 130388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 130488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 130588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 130688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 130788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 130888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 130988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 131088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 131188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 131288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 131388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 131488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBGRAYROW_SSSE3) 131588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8) && 131688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) && 131788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 131888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBGrayRow = ARGBGrayRow_SSSE3; 131988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 132088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_ARGBGRAYROW_NEON) 132188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 132288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBGrayRow = ARGBGrayRow_NEON; 132388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 132488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 132588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 132688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 132788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBGrayRow(src_argb, dst_argb, width); 132888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 132988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 133088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 133188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 133288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 133388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 133488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Make a rectangle of ARGB gray scale. 133588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 133688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBGray(uint8* dst_argb, int dst_stride_argb, 133788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int dst_x, int dst_y, 133888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 133988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 134088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBGrayRow)(const uint8* src_argb, uint8* dst_argb, 134188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBGrayRow_C; 134288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 134388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { 134488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 134588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 134688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 134788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_stride_argb == width * 4) { 134888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 134988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 135088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = 0; 135188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 135288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBGRAYROW_SSSE3) 135388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8) && 135488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 135588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBGrayRow = ARGBGrayRow_SSSE3; 135688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 135788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_ARGBGRAYROW_NEON) 135888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 135988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBGrayRow = ARGBGrayRow_NEON; 136088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 136188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 136288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 136388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBGrayRow(dst, dst, width); 136488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst += dst_stride_argb; 136588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 136688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 136788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 136888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 136988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Make a rectangle of ARGB Sepia tone. 137088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 137188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBSepia(uint8* dst_argb, int dst_stride_argb, 137288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int dst_x, int dst_y, int width, int height) { 137388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 137488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBSepiaRow)(uint8* dst_argb, int width) = ARGBSepiaRow_C; 137588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 137688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { 137788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 137888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 137988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 138088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_stride_argb == width * 4) { 138188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 138288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 138388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = 0; 138488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 138588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSEPIAROW_SSSE3) 138688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8) && 138788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 138888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSepiaRow = ARGBSepiaRow_SSSE3; 138988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 139088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_ARGBSEPIAROW_NEON) 139188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 139288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSepiaRow = ARGBSepiaRow_NEON; 139388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 139488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 139588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 139688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBSepiaRow(dst, width); 139788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst += dst_stride_argb; 139888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 139988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 140088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 140188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 140288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Apply a 4x4 matrix to each ARGB pixel. 140388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Note: Normally for shading, but can be used to swizzle or invert. 140488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 140588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBColorMatrix(const uint8* src_argb, int src_stride_argb, 140688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 140788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int8* matrix_argb, 140888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 140988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 141088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBColorMatrixRow)(const uint8* src_argb, uint8* dst_argb, 141188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int8* matrix_argb, int width) = ARGBColorMatrixRow_C; 141288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || !matrix_argb || width <= 0 || height == 0) { 141388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 141488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 141588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 141688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 141788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 141888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 141988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 142088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 142188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 142288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 142388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 142488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 142588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 142688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 142788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBCOLORMATRIXROW_SSSE3) 142888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8) && 142988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 143088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBColorMatrixRow = ARGBColorMatrixRow_SSSE3; 143188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 143288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_ARGBCOLORMATRIXROW_NEON) 143388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 143488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBColorMatrixRow = ARGBColorMatrixRow_NEON; 143588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 143688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 143788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 143888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBColorMatrixRow(src_argb, dst_argb, matrix_argb, width); 143988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 144088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 144188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 144288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 144388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 144488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 144588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Apply a 4x3 matrix to each ARGB pixel. 144688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Deprecated. 144788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 144888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint RGBColorMatrix(uint8* dst_argb, int dst_stride_argb, 144988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int8* matrix_rgb, 145088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int dst_x, int dst_y, int width, int height) { 145188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SIMD_ALIGNED(int8 matrix_argb[16]); 145288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 145388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_argb || !matrix_rgb || width <= 0 || height <= 0 || 145488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_x < 0 || dst_y < 0) { 145588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 145688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 145788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 145888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Convert 4x3 7 bit matrix to 4x4 6 bit matrix. 145988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[0] = matrix_rgb[0] / 2; 146088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[1] = matrix_rgb[1] / 2; 146188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[2] = matrix_rgb[2] / 2; 146288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[3] = matrix_rgb[3] / 2; 146388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[4] = matrix_rgb[4] / 2; 146488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[5] = matrix_rgb[5] / 2; 146588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[6] = matrix_rgb[6] / 2; 146688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[7] = matrix_rgb[7] / 2; 146788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[8] = matrix_rgb[8] / 2; 146888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[9] = matrix_rgb[9] / 2; 146988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[10] = matrix_rgb[10] / 2; 147088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[11] = matrix_rgb[11] / 2; 147188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[14] = matrix_argb[13] = matrix_argb[12] = 0; 147288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org matrix_argb[15] = 64; // 1.0 147388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 147488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return ARGBColorMatrix((const uint8*)(dst), dst_stride_argb, 147588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst, dst_stride_argb, 147688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org &matrix_argb[0], width, height); 147788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 147888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 147988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Apply a color table each ARGB pixel. 148088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Table contains 256 ARGB values. 148188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 148288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBColorTable(uint8* dst_argb, int dst_stride_argb, 148388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* table_argb, 148488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int dst_x, int dst_y, int width, int height) { 148588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 148688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBColorTableRow)(uint8* dst_argb, const uint8* table_argb, 148788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBColorTableRow_C; 148888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 148988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_argb || !table_argb || width <= 0 || height <= 0 || 149088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_x < 0 || dst_y < 0) { 149188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 149288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 149388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 149488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_stride_argb == width * 4) { 149588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 149688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 149788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = 0; 149888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 149988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBCOLORTABLEROW_X86) 150088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasX86)) { 150188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBColorTableRow = ARGBColorTableRow_X86; 150288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 150388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 150488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 150588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBColorTableRow(dst, table_argb, width); 150688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst += dst_stride_argb; 150788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 150888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 150988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 151088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 151188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Apply a color table each ARGB pixel but preserve destination alpha. 151288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Table contains 256 ARGB values. 151388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 151488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint RGBColorTable(uint8* dst_argb, int dst_stride_argb, 151588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* table_argb, 151688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int dst_x, int dst_y, int width, int height) { 151788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 151888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*RGBColorTableRow)(uint8* dst_argb, const uint8* table_argb, 151988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = RGBColorTableRow_C; 152088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 152188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_argb || !table_argb || width <= 0 || height <= 0 || 152288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_x < 0 || dst_y < 0) { 152388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 152488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 152588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 152688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_stride_argb == width * 4) { 152788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 152888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 152988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = 0; 153088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 153188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_RGBCOLORTABLEROW_X86) 153288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasX86)) { 153388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org RGBColorTableRow = RGBColorTableRow_X86; 153488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 153588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 153688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 153788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org RGBColorTableRow(dst, table_argb, width); 153888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst += dst_stride_argb; 153988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 154088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 154188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 154288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 154388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// ARGBQuantize is used to posterize art. 154488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// e.g. rgb / qvalue * qvalue + qvalue / 2 154588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// But the low levels implement efficiently with 3 parameters, and could be 154688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// used for other high level operations. 154788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// dst_argb[0] = (b * scale >> 16) * interval_size + interval_offset; 154888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// where scale is 1 / interval_size as a fixed point value. 154988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// The divide is replaces with a multiply by reciprocal fixed point multiply. 155088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Caveat - although SSE2 saturates, the C function does not and should be used 155188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// with care if doing anything but quantization. 155288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 155388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBQuantize(uint8* dst_argb, int dst_stride_argb, 155488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int scale, int interval_size, int interval_offset, 155588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int dst_x, int dst_y, int width, int height) { 155688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 155788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBQuantizeRow)(uint8* dst_argb, int scale, int interval_size, 155888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int interval_offset, int width) = ARGBQuantizeRow_C; 155988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 156088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0 || 156188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org interval_size < 1 || interval_size > 255) { 156288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 156388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 156488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 156588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (dst_stride_argb == width * 4) { 156688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 156788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 156888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = 0; 156988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 157088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBQUANTIZEROW_SSE2) 157188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 4) && 157288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 157388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBQuantizeRow = ARGBQuantizeRow_SSE2; 157488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 157588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_ARGBQUANTIZEROW_NEON) 157688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 157788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBQuantizeRow = ARGBQuantizeRow_NEON; 157888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 157988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 158088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 158188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBQuantizeRow(dst, scale, interval_size, interval_offset, width); 158288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst += dst_stride_argb; 158388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 158488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 158588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 158688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 158788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Computes table of cumulative sum for image where the value is the sum 158888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// of all values above and to the left of the entry. Used by ARGBBlur. 158988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 159088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBComputeCumulativeSum(const uint8* src_argb, int src_stride_argb, 159188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int32* dst_cumsum, int dst_stride32_cumsum, 159288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 159388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 159488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ComputeCumulativeSumRow)(const uint8* row, int32* cumsum, 159588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C; 159688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int32* previous_cumsum = dst_cumsum; 159788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!dst_cumsum || !src_argb || width <= 0 || height <= 0) { 159888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 159988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 160088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_CUMULATIVESUMTOAVERAGEROW_SSE2) 160188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2)) { 160288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ComputeCumulativeSumRow = ComputeCumulativeSumRow_SSE2; 160388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 160488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 160588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org memset(dst_cumsum, 0, width * sizeof(dst_cumsum[0]) * 4); // 4 int per pixel. 160688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 160788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ComputeCumulativeSumRow(src_argb, dst_cumsum, previous_cumsum, width); 160888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org previous_cumsum = dst_cumsum; 160988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_cumsum += dst_stride32_cumsum; 161088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 161188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 161288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 161388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 161488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 161588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Blur ARGB image. 161688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Caller should allocate CumulativeSum table of width * height * 16 bytes 161788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// aligned to 16 byte boundary. height can be radius * 2 + 2 to save memory 161888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// as the buffer is treated as circular. 161988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 162088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBBlur(const uint8* src_argb, int src_stride_argb, 162188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 162288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int32* dst_cumsum, int dst_stride32_cumsum, 162388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height, int radius) { 162488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 162588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ComputeCumulativeSumRow)(const uint8 *row, int32 *cumsum, 162688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C; 162788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*CumulativeSumToAverageRow)(const int32* topleft, const int32* botleft, 162888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int area, uint8* dst, int count) = CumulativeSumToAverageRow_C; 162988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int32* cumsum_bot_row; 163088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int32* max_cumsum_bot_row; 163188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int32* cumsum_top_row; 163288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 163388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0) { 163488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 163588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 163688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 163788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 163888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 163988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 164088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 164188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (radius > height) { 164288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org radius = height; 164388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 164488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (radius > (width / 2 - 1)) { 164588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org radius = width / 2 - 1; 164688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 164788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (radius <= 0) { 164888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 164988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 165088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_CUMULATIVESUMTOAVERAGEROW_SSE2) 165188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2)) { 165288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ComputeCumulativeSumRow = ComputeCumulativeSumRow_SSE2; 165388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CumulativeSumToAverageRow = CumulativeSumToAverageRow_SSE2; 165488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 165588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 165688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Compute enough CumulativeSum for first row to be blurred. After this 165788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // one row of CumulativeSum is updated at a time. 165888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBComputeCumulativeSum(src_argb, src_stride_argb, 165988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_cumsum, dst_stride32_cumsum, 166088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width, radius); 166188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 166288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + radius * src_stride_argb; 166388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org cumsum_bot_row = &dst_cumsum[(radius - 1) * dst_stride32_cumsum]; 166488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 166588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org max_cumsum_bot_row = &dst_cumsum[(radius * 2 + 2) * dst_stride32_cumsum]; 166688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org cumsum_top_row = &dst_cumsum[0]; 166788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 166888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 166988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int top_y = ((y - radius - 1) >= 0) ? (y - radius - 1) : 0; 167088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int bot_y = ((y + radius) < height) ? (y + radius) : (height - 1); 167188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int area = radius * (bot_y - top_y); 167288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int boxwidth = radius * 4; 167388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int x; 167488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int n; 167588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 167688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Increment cumsum_top_row pointer with circular buffer wrap around. 167788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (top_y) { 167888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org cumsum_top_row += dst_stride32_cumsum; 167988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (cumsum_top_row >= max_cumsum_bot_row) { 168088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org cumsum_top_row = dst_cumsum; 168188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 168288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 168388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Increment cumsum_bot_row pointer with circular buffer wrap around and 168488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // then fill in a row of CumulativeSum. 168588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if ((y + radius) < height) { 168688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int32* prev_cumsum_bot_row = cumsum_bot_row; 168788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org cumsum_bot_row += dst_stride32_cumsum; 168888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (cumsum_bot_row >= max_cumsum_bot_row) { 168988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org cumsum_bot_row = dst_cumsum; 169088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 169188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ComputeCumulativeSumRow(src_argb, cumsum_bot_row, prev_cumsum_bot_row, 169288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width); 169388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 169488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 169588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 169688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Left clipped. 169788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (x = 0; x < radius + 1; ++x) { 169888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CumulativeSumToAverageRow(cumsum_top_row, cumsum_bot_row, 169988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org boxwidth, area, &dst_argb[x * 4], 1); 170088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org area += (bot_y - top_y); 170188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org boxwidth += 4; 170288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 170388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 170488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Middle unclipped. 170588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org n = (width - 1) - radius - x + 1; 170688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CumulativeSumToAverageRow(cumsum_top_row, cumsum_bot_row, 170788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org boxwidth, area, &dst_argb[x * 4], n); 170888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 170988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Right clipped. 171088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (x += n; x <= width - 1; ++x) { 171188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org area -= (bot_y - top_y); 171288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org boxwidth -= 4; 171388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org CumulativeSumToAverageRow(cumsum_top_row + (x - radius - 1) * 4, 171488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org cumsum_bot_row + (x - radius - 1) * 4, 171588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org boxwidth, area, &dst_argb[x * 4], 1); 171688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 171788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 171888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 171988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 172088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 172188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 172288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Multiply ARGB image by a specified ARGB value. 172388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 172488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBShade(const uint8* src_argb, int src_stride_argb, 172588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 172688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height, uint32 value) { 172788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 172888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBShadeRow)(const uint8* src_argb, uint8* dst_argb, 172988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, uint32 value) = ARGBShadeRow_C; 173088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0 || value == 0u) { 173188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 173288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 173388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 173488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 173588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 173688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 173788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 173888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 173988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 174088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 174188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 174288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 174388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 174488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 174588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSHADEROW_SSE2) 174688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 4) && 174788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) && 174888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 174988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShadeRow = ARGBShadeRow_SSE2; 175088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 175188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#elif defined(HAS_ARGBSHADEROW_NEON) 175288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 175388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShadeRow = ARGBShadeRow_NEON; 175488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 175588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 175688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 175788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 175888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShadeRow(src_argb, dst_argb, width, value); 175988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 176088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 176188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 176288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 176388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 176488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 176588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Interpolate 2 ARGB images by specified amount (0 to 255). 176688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 176788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0, 176888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_argb1, int src_stride_argb1, 176988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 177088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height, int interpolation) { 177188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 177288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 177388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ptrdiff_t src_stride, int dst_width, 177488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int source_y_fraction) = InterpolateRow_C; 177588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 177688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 177788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 177888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 177988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 178088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 178188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb = dst_argb + (height - 1) * dst_stride_argb; 178288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb = -dst_stride_argb; 178388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 178488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 178588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb0 == width * 4 && 178688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb1 == width * 4 && 178788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 178888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 178988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 179088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 179188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 179288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_INTERPOLATEROW_SSE2) 179388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 4) { 179488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_Any_SSE2; 179588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 179688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_Unaligned_SSE2; 179788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(src_argb0, 16) && IS_ALIGNED(src_stride_argb0, 16) && 179888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb1, 16) && IS_ALIGNED(src_stride_argb1, 16) && 179988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 180088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_SSE2; 180188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 180288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 180388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 180488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 180588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_INTERPOLATEROW_SSSE3) 180688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 4) { 180788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_Any_SSSE3; 180888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 180988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_Unaligned_SSSE3; 181088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(src_argb0, 16) && IS_ALIGNED(src_stride_argb0, 16) && 181188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb1, 16) && IS_ALIGNED(src_stride_argb1, 16) && 181288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 181388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_SSSE3; 181488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 181588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 181688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 181788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 181888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_INTERPOLATEROW_AVX2) 181988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 8) { 182088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_Any_AVX2; 182188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 182288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_AVX2; 182388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 182488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 182588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 182688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_INTERPOLATEROW_NEON) 182788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 4) { 182888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_Any_NEON; 182988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 183088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow = InterpolateRow_NEON; 183188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 183288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 183388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 183488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_INTERPOLATEROWS_MIPS_DSPR2) 183588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasMIPS_DSPR2) && width >= 1 && 183688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb0, 4) && IS_ALIGNED(src_stride_argb0, 4) && 183788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb1, 4) && IS_ALIGNED(src_stride_argb1, 4) && 183888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { 183988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ScaleARGBFilterRows = InterpolateRow_MIPS_DSPR2; 184088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 184188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 184288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 184388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 184488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org InterpolateRow(dst_argb, src_argb0, src_argb1 - src_argb0, 184588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width * 4, interpolation); 184688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb0 += src_stride_argb0; 184788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb1 += src_stride_argb1; 184888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 184988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 185088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 185188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 185288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 185388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Shuffle ARGB channel order. e.g. BGRA to ARGB. 185488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 185588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBShuffle(const uint8* src_bgra, int src_stride_bgra, 185688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 185788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* shuffler, int width, int height) { 185888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 185988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBShuffleRow)(const uint8* src_bgra, uint8* dst_argb, 186088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* shuffler, int pix) = ARGBShuffleRow_C; 186188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_bgra || !dst_argb || 186288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width <= 0 || height == 0) { 186388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 186488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 186588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 186688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 186788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 186888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_bgra = src_bgra + (height - 1) * src_stride_bgra; 186988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_bgra = -src_stride_bgra; 187088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 187188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 187288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_bgra == width * 4 && 187388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 187488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 187588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 187688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_bgra = dst_stride_argb = 0; 187788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 187888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSHUFFLEROW_SSE2) 187988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 4) { 188088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_Any_SSE2; 188188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 188288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_SSE2; 188388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 188488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 188588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 188688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSHUFFLEROW_SSSE3) 188788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 188888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_Any_SSSE3; 188988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 189088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_Unaligned_SSSE3; 189188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(src_bgra, 16) && IS_ALIGNED(src_stride_bgra, 16) && 189288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 189388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_SSSE3; 189488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 189588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 189688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 189788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 189888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSHUFFLEROW_AVX2) 189988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && width >= 16) { 190088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_Any_AVX2; 190188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 16)) { 190288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_AVX2; 190388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 190488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 190588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 190688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBSHUFFLEROW_NEON) 190788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 4) { 190888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_Any_NEON; 190988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 4)) { 191088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow = ARGBShuffleRow_NEON; 191188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 191288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 191388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 191488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 191588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 191688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBShuffleRow(src_bgra, dst_argb, shuffler, width); 191788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_bgra += src_stride_bgra; 191888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 191988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 192088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 192188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 192288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 192388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Sobel ARGB effect. 192488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgstatic int ARGBSobelize(const uint8* src_argb, int src_stride_argb, 192588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 192688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height, 192788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*SobelRow)(const uint8* src_sobelx, 192888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_sobely, 192988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst, int width)) { 193088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 193188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBToBayerRow)(const uint8* src_argb, uint8* dst_bayer, 193288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint32 selector, int pix) = ARGBToBayerGGRow_C; 193388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1, 193488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_sobely, int width) = SobelYRow_C; 193588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1, 193688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* src_y2, uint8* dst_sobely, int width) = 193788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelXRow_C; 193888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int kEdge = 16; // Extra pixels at start of row for extrude/align. 193988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0) { 194088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 194188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 194288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 194388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 194488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 194588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 194688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 194788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 194888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // ARGBToBayer used to select G channel from ARGB. 194988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBTOBAYERGGROW_SSE2) 195088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && width >= 8 && 195188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) { 195288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow = ARGBToBayerGGRow_Any_SSE2; 195388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 195488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow = ARGBToBayerGGRow_SSE2; 195588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 195688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 195788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 195888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBTOBAYERROW_SSSE3) 195988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && width >= 8 && 196088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) { 196188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow = ARGBToBayerRow_Any_SSSE3; 196288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 196388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow = ARGBToBayerRow_SSSE3; 196488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 196588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 196688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 196788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBTOBAYERGGROW_NEON) 196888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 196988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow = ARGBToBayerGGRow_Any_NEON; 197088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (IS_ALIGNED(width, 8)) { 197188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow = ARGBToBayerGGRow_NEON; 197288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 197388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 197488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 197588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELYROW_SSE2) 197688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2)) { 197788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelYRow = SobelYRow_SSE2; 197888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 197988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 198088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELYROW_NEON) 198188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON)) { 198288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelYRow = SobelYRow_NEON; 198388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 198488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 198588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELXROW_SSE2) 198688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2)) { 198788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelXRow = SobelXRow_SSE2; 198888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 198988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 199088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELXROW_NEON) 199188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON)) { 199288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelXRow = SobelXRow_NEON; 199388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 199488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 199588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org { 199688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // 3 rows with edges before/after. 199788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int kRowSize = (width + kEdge + 15) & ~15; 199888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org align_buffer_64(rows, kRowSize * 2 + (kEdge + kRowSize * 3 + kEdge)); 199988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* row_sobelx = rows; 200088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* row_sobely = rows + kRowSize; 200188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* row_y = rows + kRowSize * 2; 200288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 200388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Convert first row. 200488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* row_y0 = row_y + kEdge; 200588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* row_y1 = row_y0 + kRowSize; 200688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* row_y2 = row_y1 + kRowSize; 200788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow(src_argb, row_y0, 0x0d090501, width); 200888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org row_y0[-1] = row_y0[0]; 200988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind. 201088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow(src_argb, row_y1, 0x0d090501, width); 201188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org row_y1[-1] = row_y1[0]; 201288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org memset(row_y1 + width, row_y1[width - 1], 16); 201388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org memset(row_y2 + width, 0, 16); 201488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 201588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 201688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Convert next row of ARGB to Y. 201788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (y < (height - 1)) { 201888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 201988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 202088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBToBayerRow(src_argb, row_y2, 0x0d090501, width); 202188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org row_y2[-1] = row_y2[0]; 202288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org row_y2[width] = row_y2[width - 1]; 202388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 202488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelXRow(row_y0 - 1, row_y1 - 1, row_y2 - 1, row_sobelx, width); 202588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelYRow(row_y0 - 1, row_y2 - 1, row_sobely, width); 202688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelRow(row_sobelx, row_sobely, dst_argb, width); 202788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 202888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Cycle thru circular queue of 3 row_y buffers. 202988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org { 203088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* row_yt = row_y0; 203188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org row_y0 = row_y1; 203288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org row_y1 = row_y2; 203388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org row_y2 = row_yt; 203488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 203588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 203688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 203788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 203888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org free_aligned_buffer_64(rows); 203988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 204088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 204188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 204288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 204388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Sobel ARGB effect. 204488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 204588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBSobel(const uint8* src_argb, int src_stride_argb, 204688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 204788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 204888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely, 204988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int width) = SobelRow_C; 205088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELROW_SSE2) 205188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16) && 205288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 205388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelRow = SobelRow_SSE2; 205488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 205588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 205688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELROW_NEON) 205788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 205888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelRow = SobelRow_NEON; 205988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 206088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 206188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, 206288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width, height, SobelRow); 206388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 206488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 206588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Sobel ARGB effect with planar output. 206688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 206788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBSobelToPlane(const uint8* src_argb, int src_stride_argb, 206888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_y, int dst_stride_y, 206988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 207088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely, 207188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_, int width) = SobelToPlaneRow_C; 207288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELTOPLANEROW_SSE2) 207388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16) && 207488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 207588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelToPlaneRow = SobelToPlaneRow_SSE2; 207688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 207788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 207888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELTOPLANEROW_NEON) 207988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) { 208088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelToPlaneRow = SobelToPlaneRow_NEON; 208188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 208288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 208388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return ARGBSobelize(src_argb, src_stride_argb, dst_y, dst_stride_y, 208488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width, height, SobelToPlaneRow); 208588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 208688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 208788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// SobelXY ARGB effect. 208888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Similar to Sobel, but also stores Sobel X in R and Sobel Y in B. G = Sobel. 208988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 209088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBSobelXY(const uint8* src_argb, int src_stride_argb, 209188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 209288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 209388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely, 209488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int width) = SobelXYRow_C; 209588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELXYROW_SSE2) 209688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16) && 209788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 209888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelXYRow = SobelXYRow_SSE2; 209988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 210088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 210188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_SOBELXYROW_NEON) 210288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 210388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org SobelXYRow = SobelXYRow_NEON; 210488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 210588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 210688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, 210788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width, height, SobelXYRow); 210888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 210988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 211088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Apply a 4x4 polynomial to each ARGB pixel. 211188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 211288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBPolynomial(const uint8* src_argb, int src_stride_argb, 211388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 211488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const float* poly, 211588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 211688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 211788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBPolynomialRow)(const uint8* src_argb, 211888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, const float* poly, 211988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width) = ARGBPolynomialRow_C; 212088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || !poly || width <= 0 || height == 0) { 212188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 212288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 212388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 212488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 212588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 212688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 212788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 212888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 212988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 213088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 213188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 213288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 213388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 213488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 213588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 213688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBPOLYNOMIALROW_SSE2) 213788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 2)) { 213888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBPolynomialRow = ARGBPolynomialRow_SSE2; 213988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 214088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 214188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBPOLYNOMIALROW_AVX2) 214288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && TestCpuFlag(kCpuHasFMA3) && 214388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(width, 2)) { 214488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBPolynomialRow = ARGBPolynomialRow_AVX2; 214588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 214688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 214788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 214888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 214988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBPolynomialRow(src_argb, dst_argb, poly, width); 215088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 215188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 215288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 215388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 215488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 215588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 215688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Apply a lumacolortable to each ARGB pixel. 215788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 215888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBLumaColorTable(const uint8* src_argb, int src_stride_argb, 215988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 216088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const uint8* luma, 216188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 216288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 216388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBLumaColorTableRow)(const uint8* src_argb, uint8* dst_argb, 216488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, const uint8* luma, const uint32 lumacoeff) = 216588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBLumaColorTableRow_C; 216688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || !luma || width <= 0 || height == 0) { 216788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 216888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 216988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 217088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 217188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 217288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 217388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 217488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 217588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 217688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 217788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 217888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 217988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 218088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 218188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 218288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBLUMACOLORTABLEROW_SSSE3) 218388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4)) { 218488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBLumaColorTableRow = ARGBLumaColorTableRow_SSSE3; 218588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 218688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 218788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 218888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 218988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBLumaColorTableRow(src_argb, dst_argb, width, luma, 0x00264b0f); 219088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 219188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 219288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 219388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 219488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 219588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 219688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Copy Alpha from one ARGB image to another. 219788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 219888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBCopyAlpha(const uint8* src_argb, int src_stride_argb, 219988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 220088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 220188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 220288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBCopyAlphaRow)(const uint8* src_argb, uint8* dst_argb, int width) = 220388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyAlphaRow_C; 220488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_argb || !dst_argb || width <= 0 || height == 0) { 220588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 220688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 220788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 220888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 220988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 221088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb = src_argb + (height - 1) * src_stride_argb; 221188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = -src_stride_argb; 221288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 221388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 221488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_argb == width * 4 && 221588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 221688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 221788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 221888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_argb = dst_stride_argb = 0; 221988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 222088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBCOPYALPHAROW_SSE2) 222188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && 222288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16) && 222388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16) && 222488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(width, 8)) { 222588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyAlphaRow = ARGBCopyAlphaRow_SSE2; 222688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 222788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 222888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBCOPYALPHAROW_AVX2) 222988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 16)) { 223088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyAlphaRow = ARGBCopyAlphaRow_AVX2; 223188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 223288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 223388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 223488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 223588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyAlphaRow(src_argb, dst_argb, width); 223688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_argb += src_stride_argb; 223788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 223888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 223988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 224088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 224188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 224288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org// Copy a planar Y channel to the alpha channel of a destination ARGB image. 224388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgLIBYUV_API 224488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgint ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y, 224588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uint8* dst_argb, int dst_stride_argb, 224688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int width, int height) { 224788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int y; 224888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org void (*ARGBCopyYToAlphaRow)(const uint8* src_y, uint8* dst_argb, int width) = 224988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyYToAlphaRow_C; 225088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (!src_y || !dst_argb || width <= 0 || height == 0) { 225188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return -1; 225288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 225388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Negative height means invert the image. 225488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (height < 0) { 225588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = -height; 225688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y = src_y + (height - 1) * src_stride_y; 225788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = -src_stride_y; 225888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 225988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org // Coalesce rows. 226088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (src_stride_y == width && 226188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_stride_argb == width * 4) { 226288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org width *= height; 226388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org height = 1; 226488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_stride_y = dst_stride_argb = 0; 226588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 226688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBCOPYYTOALPHAROW_SSE2) 226788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasSSE2) && 226888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) && 226988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16) && 227088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org IS_ALIGNED(width, 8)) { 227188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_SSE2; 227288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 227388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 227488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#if defined(HAS_ARGBCOPYYTOALPHAROW_AVX2) 227588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 16)) { 227688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_AVX2; 227788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 227888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 227988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 228088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (y = 0; y < height; ++y) { 228188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org ARGBCopyYToAlphaRow(src_y, dst_argb, width); 228288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org src_y += src_stride_y; 228388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org dst_argb += dst_stride_argb; 228488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 228588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org return 0; 228688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 228788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 228888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#ifdef __cplusplus 228988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} // extern "C" 229088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} // namespace libyuv 229188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org#endif 2292