1ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian/* 2ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * 4ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 5ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 6ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 7ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 8ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 9ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian */ 10ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 11ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/convert.h" 12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/basic_types.h" 14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/cpu_id.h" 15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/planar_functions.h" 16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/rotate.h" 17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/scale.h" // For ScalePlane() 18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/row.h" 19ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 20ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace libyuv { 22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianextern "C" { 23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 24ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) 26ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic __inline int Abs(int v) { 27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return v >= 0 ? v : -v; 28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Any I4xx To I420 format with mirroring. 31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic int I4xxToI420(const uint8* src_y, int src_stride_y, 32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_y_width, int src_y_height, 38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_uv_width, int src_uv_height) { 39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int dst_y_width = Abs(src_y_width); 40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int dst_y_height = Abs(src_y_height); 41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); 42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); 43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_y_width == 0 || src_y_height == 0 || 44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv_width == 0 || src_uv_height == 0) { 45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, 48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y, dst_stride_y, dst_y_width, dst_y_height, 49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian kFilterBilinear); 50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, 51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u, dst_stride_u, dst_uv_width, dst_uv_height, 52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian kFilterBilinear); 53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, 54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v, dst_stride_v, dst_uv_width, dst_uv_height, 55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian kFilterBilinear); 56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy I420 with optional flipping 60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// TODO(fbarchard): Use Scale plane which supports mirroring, but ensure 61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// is does row coalescing. 62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I420Copy(const uint8* src_y, int src_stride_y, 64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfheight = (height + 1) >> 1; 72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_u || !src_v || 73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfheight = (height + 1) >> 1; 81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = src_u + (halfheight - 1) * src_stride_u; 83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = src_v + (halfheight - 1) * src_stride_v; 84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_u = -src_stride_u; 86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_v = -src_stride_v; 87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_y) { 90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Copy UV planes. 93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); 94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); 95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 422 chroma is 1/2 width, 1x height 99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 420 chroma is 1/2 width, 1/2 height 100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I422ToI420(const uint8* src_y, int src_stride_y, 102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int src_uv_width = SUBSAMPLE(width, 1, 1); 109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return I4xxToI420(src_y, src_stride_y, 110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u, src_stride_u, 111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v, src_stride_v, 112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y, dst_stride_y, 113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u, dst_stride_u, 114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v, dst_stride_v, 115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height, 116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv_width, height); 117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 444 chroma is 1x width, 1x height 120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 420 chroma is 1/2 width, 1/2 height 121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I444ToI420(const uint8* src_y, int src_stride_y, 123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return I4xxToI420(src_y, src_stride_y, 130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u, src_stride_u, 131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v, src_stride_v, 132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y, dst_stride_y, 133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u, dst_stride_u, 134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v, dst_stride_v, 135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height, 136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height); 137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 411 chroma is 1/4 width, 1x height 140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// 420 chroma is 1/2 width, 1/2 height 141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I411ToI420(const uint8* src_y, int src_stride_y, 143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int src_uv_width = SUBSAMPLE(width, 3, 2); 150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return I4xxToI420(src_y, src_stride_y, 151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u, src_stride_u, 152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v, src_stride_v, 153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y, dst_stride_y, 154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u, dst_stride_u, 155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v, dst_stride_v, 156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height, 157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv_width, height); 158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// I400 is greyscale typically used in MJPG 161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I400ToI420(const uint8* src_y, int src_stride_y, 163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfheight = (height + 1) >> 1; 169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !dst_y || !dst_u || !dst_v || 170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfheight = (height + 1) >> 1; 177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SetPlane(dst_u, dst_stride_u, halfwidth, halfheight, 128); 182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SetPlane(dst_v, dst_stride_v, halfwidth, halfheight, 128); 183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic void CopyPlane2(const uint8* src, int src_stride_0, int src_stride_1, 187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst, int dst_stride, 188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; 191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_X86) 192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasX86) && IS_ALIGNED(width, 4)) { 193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_X86; 194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_SSE2) 197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32) && 198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src, 16) && 199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_stride_0, 16) && IS_ALIGNED(src_stride_1, 16) && 200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst, 16) && IS_ALIGNED(dst_stride, 16)) { 201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_SSE2; 202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_ERMS) 205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasERMS)) { 206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_ERMS; 207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_NEON) 210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { 211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_NEON; 212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_MIPS) 215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS)) { 216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_MIPS; 217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Copy plane 221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow(src, dst, width); 223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow(src + src_stride_0, dst + dst_stride, width); 224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src += src_stride_0 + src_stride_1; 225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += dst_stride * 2; 226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow(src, dst, width); 229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Support converting from FOURCC_M420 233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Useful for bandwidth constrained transports like USB 1.0 and 2.0 and for 234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// easy conversion to I420. 235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// M420 format description: 236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// M420 is row biplanar 420: 2 rows of Y and 1 row of UV. 237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Chroma is half width / half height. (420) 238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// src_stride_m420 is row planar. Normally this will be the width in pixels. 239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// The UV plane is half width, but 2 values, so src_stride_m420 applies to 240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// this as well as the two Y planes. 241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic int X420ToI420(const uint8* src_y, 242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_stride_y0, int src_stride_y1, 243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_uv, int src_stride_uv, 244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfheight = (height + 1) >> 1; 251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) = 252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow_C; 253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_uv || 254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfheight = (height + 1) >> 1; 262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y = dst_y + (height - 1) * dst_stride_y; 263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u = dst_u + (halfheight - 1) * dst_stride_u; 264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v = dst_v + (halfheight - 1) * dst_stride_v; 265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y = -dst_stride_y; 266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_u = -dst_stride_u; 267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_v = -dst_stride_v; 268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y0 == width && 271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y1 == width && 272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y == width) { 273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y0 = src_stride_y1 = dst_stride_y = 0; 276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_uv == halfwidth * 2 && 279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_u == halfwidth && 280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_v == halfwidth) { 281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfwidth *= halfheight; 282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfheight = 1; 283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_uv = dst_stride_u = dst_stride_v = 0; 284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_SSE2) 286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && halfwidth >= 16) { 287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_SSE2; 288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(halfwidth, 16)) { 289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Unaligned_SSE2; 290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_uv, 16) && IS_ALIGNED(src_stride_uv, 16) && 291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_u, 16) && IS_ALIGNED(dst_stride_u, 16) && 292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_v, 16) && IS_ALIGNED(dst_stride_v, 16)) { 293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_SSE2; 294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_AVX2) 299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && halfwidth >= 32) { 300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_AVX2; 301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(halfwidth, 32)) { 302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_AVX2; 303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_NEON) 307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && halfwidth >= 16) { 308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_NEON; 309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(halfwidth, 16)) { 310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_NEON; 311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_MIPS_DSPR2) 315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && halfwidth >= 16) { 316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_MIPS_DSPR2; 317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(halfwidth, 16)) { 318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Unaligned_MIPS_DSPR2; 319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_uv, 4) && IS_ALIGNED(src_stride_uv, 4) && 320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) && 321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) { 322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_MIPS_DSPR2; 323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_y) { 329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y0 == src_stride_y1) { 330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_y, src_stride_y0, dst_y, dst_stride_y, width, height); 331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane2(src_y, src_stride_y0, src_stride_y1, dst_y, dst_stride_y, 333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height); 334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < halfheight; ++y) { 338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Copy a row of UV. 339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SplitUVRow(src_uv, dst_u, dst_v, halfwidth); 340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv += src_stride_uv; 343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert NV12 to I420. 348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint NV12ToI420(const uint8* src_y, int src_stride_y, 350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_uv, int src_stride_uv, 351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return X420ToI420(src_y, src_stride_y, src_stride_y, 356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv, src_stride_uv, 357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y, dst_stride_y, 358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u, dst_stride_u, 359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v, dst_stride_v, 360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height); 361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert NV21 to I420. Same as NV12 but u and v pointers swapped. 364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint NV21ToI420(const uint8* src_y, int src_stride_y, 366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_vu, int src_stride_vu, 367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return X420ToI420(src_y, src_stride_y, src_stride_y, 372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_vu, src_stride_vu, 373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y, dst_stride_y, 374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v, dst_stride_v, 375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u, dst_stride_u, 376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height); 377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert M420 to I420. 380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint M420ToI420(const uint8* src_m420, int src_stride_m420, 382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return X420ToI420(src_m420, src_stride_m420, src_stride_m420 * 2, 387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_m420 + src_stride_m420 * 2, src_stride_m420 * 3, 388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y, dst_stride_y, 389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u, dst_stride_u, 390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v, dst_stride_v, 391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height); 392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert Q420 to I420. 395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Format is rows of YY/YUYV 396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint Q420ToI420(const uint8* src_y, int src_stride_y, 398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_yuy2, int src_stride_yuy2, 399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 402ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfheight = (height + 1) >> 1; 405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; 406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*YUY2ToUV422Row)(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v, 407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int pix) = YUY2ToUV422Row_C; 408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int pix) = 409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow_C; 410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_yuy2 || 411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfheight = (height + 1) >> 1; 419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y = dst_y + (height - 1) * dst_stride_y; 420ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u = dst_u + (halfheight - 1) * dst_stride_u; 421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v = dst_v + (halfheight - 1) * dst_stride_v; 422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y = -dst_stride_y; 423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_u = -dst_stride_u; 424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_v = -dst_stride_v; 425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // CopyRow for rows of just Y in Q420 copied to Y plane of I420. 427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_NEON) 428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { 429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_NEON; 430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_X86) 433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_X86; 435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_SSE2) 438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32) && 439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) && 440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_SSE2; 442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_ERMS) 445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasERMS)) { 446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_ERMS; 447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_MIPS) 450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS)) { 451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_MIPS; 452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_SSE2) 456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_Any_SSE2; 458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_SSE2; 459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_Unaligned_SSE2; 461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Unaligned_SSE2; 462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16)) { 463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_SSE2; 464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_SSE2; 466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_AVX2) 472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_Any_AVX2; 474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_AVX2; 475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_AVX2; 477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_AVX2; 478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_NEON) 482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_NEON; 484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_Any_NEON; 486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_NEON; 489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_NEON; 490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow(src_y, dst_y, width); 496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); 500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow(src_yuy2, dst_y, width); 501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_yuy2 += src_stride_yuy2; 502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow(src_y, dst_y, width); 508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); 509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert YUY2 to I420. 514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint YUY2ToI420(const uint8* src_yuy2, int src_stride_yuy2, 516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*YUY2ToUVRow)(const uint8* src_yuy2, int src_stride_yuy2, 522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int pix) = YUY2ToUVRow_C; 523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*YUY2ToYRow)(const uint8* src_yuy2, 524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int pix) = YUY2ToYRow_C; 525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_yuy2 = -src_stride_yuy2; 530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_SSE2) 532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow = YUY2ToUVRow_Any_SSE2; 534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_SSE2; 535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow = YUY2ToUVRow_Unaligned_SSE2; 537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Unaligned_SSE2; 538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16)) { 539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow = YUY2ToUVRow_SSE2; 540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_SSE2; 542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_AVX2) 548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow = YUY2ToUVRow_Any_AVX2; 550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_AVX2; 551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow = YUY2ToUVRow_AVX2; 553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_AVX2; 554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_NEON) 558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_NEON; 560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow = YUY2ToUVRow_Any_NEON; 562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_NEON; 565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow = YUY2ToUVRow_NEON; 566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow(src_yuy2, src_stride_yuy2, dst_u, dst_v, width); 572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow(src_yuy2, dst_y, width); 573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y, width); 574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_yuy2 += src_stride_yuy2 * 2; 575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUVRow(src_yuy2, 0, dst_u, dst_v, width); 581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow(src_yuy2, dst_y, width); 582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert UYVY to I420. 587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint UYVYToI420(const uint8* src_uyvy, int src_stride_uyvy, 589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*UYVYToUVRow)(const uint8* src_uyvy, int src_stride_uyvy, 595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int pix) = UYVYToUVRow_C; 596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*UYVYToYRow)(const uint8* src_uyvy, 597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int pix) = UYVYToYRow_C; 598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_uyvy = -src_stride_uyvy; 603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_UYVYTOYROW_SSE2) 605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow = UYVYToUVRow_Any_SSE2; 607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_Any_SSE2; 608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow = UYVYToUVRow_Unaligned_SSE2; 610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_Unaligned_SSE2; 611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16)) { 612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow = UYVYToUVRow_SSE2; 613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_SSE2; 615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_UYVYTOYROW_AVX2) 621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow = UYVYToUVRow_Any_AVX2; 623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_Any_AVX2; 624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow = UYVYToUVRow_AVX2; 626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_AVX2; 627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_UYVYTOYROW_NEON) 631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_Any_NEON; 633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow = UYVYToUVRow_Any_NEON; 635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_NEON; 638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow = UYVYToUVRow_NEON; 639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width); 645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow(src_uyvy, dst_y, width); 646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow(src_uyvy + src_stride_uyvy, dst_y + dst_stride_y, width); 647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uyvy += src_stride_uyvy * 2; 648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUVRow(src_uyvy, 0, dst_u, dst_v, width); 654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow(src_uyvy, dst_y, width); 655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert ARGB to I420. 660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBToI420(const uint8* src_argb, int src_stride_argb, 662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow_C; 671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || 672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3) 683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_SSSE3; 686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3; 688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) { 690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_SSSE3; 691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_SSSE3; 693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2) 699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_AVX2; 701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_AVX2; 702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_AVX2; 704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_AVX2; 705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOYROW_NEON) 709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_NEON; 711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_NEON; 713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_NEON; 716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_NEON; 718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width); 725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(src_argb, dst_y, width); 726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); 727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb * 2; 728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(src_argb, 0, dst_u, dst_v, width); 734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(src_argb, dst_y, width); 735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert BGRA to I420. 740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint BGRAToI420(const uint8* src_bgra, int src_stride_bgra, 742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*BGRAToUVRow)(const uint8* src_bgra0, int src_stride_bgra, 748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = BGRAToUVRow_C; 749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*BGRAToYRow)(const uint8* src_bgra, uint8* dst_y, int pix) = 750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow_C; 751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_bgra || 752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_bgra = src_bgra + (height - 1) * src_stride_bgra; 760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_bgra = -src_stride_bgra; 761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_BGRATOYROW_SSSE3) 763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToUVRow = BGRAToUVRow_Any_SSSE3; 765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow = BGRAToYRow_Any_SSSE3; 766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToUVRow = BGRAToUVRow_Unaligned_SSSE3; 768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow = BGRAToYRow_Unaligned_SSSE3; 769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_bgra, 16) && IS_ALIGNED(src_stride_bgra, 16)) { 770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToUVRow = BGRAToUVRow_SSSE3; 771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow = BGRAToYRow_SSSE3; 773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#elif defined(HAS_BGRATOYROW_NEON) 778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow = BGRAToYRow_Any_NEON; 780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow = BGRAToYRow_NEON; 782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToUVRow = BGRAToUVRow_Any_NEON; 785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToUVRow = BGRAToUVRow_NEON; 787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToUVRow(src_bgra, src_stride_bgra, dst_u, dst_v, width); 794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow(src_bgra, dst_y, width); 795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow(src_bgra + src_stride_bgra, dst_y + dst_stride_y, width); 796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_bgra += src_stride_bgra * 2; 797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToUVRow(src_bgra, 0, dst_u, dst_v, width); 803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian BGRAToYRow(src_bgra, dst_y, width); 804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert ABGR to I420. 809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ABGRToI420(const uint8* src_abgr, int src_stride_abgr, 811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 814ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ABGRToUVRow)(const uint8* src_abgr0, int src_stride_abgr, 817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ABGRToUVRow_C; 818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ABGRToYRow)(const uint8* src_abgr, uint8* dst_y, int pix) = 819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow_C; 820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_abgr || 821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_abgr = src_abgr + (height - 1) * src_stride_abgr; 829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_abgr = -src_stride_abgr; 830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 831ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ABGRTOYROW_SSSE3) 832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToUVRow = ABGRToUVRow_Any_SSSE3; 834ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow = ABGRToYRow_Any_SSSE3; 835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToUVRow = ABGRToUVRow_Unaligned_SSSE3; 837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow = ABGRToYRow_Unaligned_SSSE3; 838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_abgr, 16) && IS_ALIGNED(src_stride_abgr, 16)) { 839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToUVRow = ABGRToUVRow_SSSE3; 840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow = ABGRToYRow_SSSE3; 842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#elif defined(HAS_ABGRTOYROW_NEON) 847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow = ABGRToYRow_Any_NEON; 849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow = ABGRToYRow_NEON; 851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToUVRow = ABGRToUVRow_Any_NEON; 854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToUVRow = ABGRToUVRow_NEON; 856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToUVRow(src_abgr, src_stride_abgr, dst_u, dst_v, width); 863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow(src_abgr, dst_y, width); 864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow(src_abgr + src_stride_abgr, dst_y + dst_stride_y, width); 865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_abgr += src_stride_abgr * 2; 866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToUVRow(src_abgr, 0, dst_u, dst_v, width); 872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ABGRToYRow(src_abgr, dst_y, width); 873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert RGBA to I420. 878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint RGBAToI420(const uint8* src_rgba, int src_stride_rgba, 880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGBAToUVRow)(const uint8* src_rgba0, int src_stride_rgba, 886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = RGBAToUVRow_C; 887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGBAToYRow)(const uint8* src_rgba, uint8* dst_y, int pix) = 888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow_C; 889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_rgba || 890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_rgba = src_rgba + (height - 1) * src_stride_rgba; 898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_rgba = -src_stride_rgba; 899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGBATOYROW_SSSE3) 901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToUVRow = RGBAToUVRow_Any_SSSE3; 903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow = RGBAToYRow_Any_SSSE3; 904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToUVRow = RGBAToUVRow_Unaligned_SSSE3; 906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow = RGBAToYRow_Unaligned_SSSE3; 907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(src_rgba, 16) && IS_ALIGNED(src_stride_rgba, 16)) { 908ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToUVRow = RGBAToUVRow_SSSE3; 909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 910ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow = RGBAToYRow_SSSE3; 911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#elif defined(HAS_RGBATOYROW_NEON) 916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow = RGBAToYRow_Any_NEON; 918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow = RGBAToYRow_NEON; 920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToUVRow = RGBAToUVRow_Any_NEON; 923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToUVRow = RGBAToUVRow_NEON; 925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToUVRow(src_rgba, src_stride_rgba, dst_u, dst_v, width); 932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow(src_rgba, dst_y, width); 933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow(src_rgba + src_stride_rgba, dst_y + dst_stride_y, width); 934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_rgba += src_stride_rgba * 2; 935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 939ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToUVRow(src_rgba, 0, dst_u, dst_v, width); 941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBAToYRow(src_rgba, dst_y, width); 942ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert RGB24 to I420. 947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint RGB24ToI420(const uint8* src_rgb24, int src_stride_rgb24, 949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB24TOYROW_NEON) 955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGB24ToUVRow)(const uint8* src_rgb24, int src_stride_rgb24, 956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = RGB24ToUVRow_C; 957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGB24ToYRow)(const uint8* src_rgb24, uint8* dst_y, int pix) = 958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToYRow_C; 959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToARGBRow_C; 962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow_C; 966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (width * 4 + 15) & ~15; 968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_rgb24 || !dst_y || !dst_u || !dst_v || 971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; 978ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_rgb24 = -src_stride_rgb24; 979ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 981ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB24TOYROW_NEON) 982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToYRow = RGB24ToYRow_Any_NEON; 984ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToYRow = RGB24ToYRow_NEON; 986ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 987ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToUVRow = RGB24ToUVRow_Any_NEON; 989ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 990ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToUVRow = RGB24ToUVRow_NEON; 991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 992ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else // HAS_RGB24TOYROW_NEON 995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB24TOARGBROW_SSSE3) 997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3; 999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1000ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToARGBRow = RGB24ToARGBRow_SSSE3; 1001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1004ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1007ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1008ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_SSSE3; 1009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1011ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1013ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1014ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_SSSE3; 1015ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_SSSE3; 1019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1021ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_ARGBTOUVROW_SSSE3 1023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_RGB24TOYROW_NEON 1024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 1026ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB24TOYROW_NEON) 1027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToUVRow(src_rgb24, src_stride_rgb24, dst_u, dst_v, width); 1028ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToYRow(src_rgb24, dst_y, width); 1029ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToYRow(src_rgb24 + src_stride_rgb24, dst_y + dst_stride_y, width); 1030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToARGBRow(src_rgb24, row, width); 1032ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToARGBRow(src_rgb24 + src_stride_rgb24, row + kRowSize, width); 1033ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1037ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_rgb24 += src_stride_rgb24 * 2; 1038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 1039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 1040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 1041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 1043ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB24TOYROW_NEON) 1044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToUVRow(src_rgb24, 0, dst_u, dst_v, width); 1045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToYRow(src_rgb24, dst_y, width); 1046ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB24ToARGBRow(src_rgb24, row, width); 1048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, 0, dst_u, dst_v, width); 1049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1050ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if !defined(HAS_RGB24TOYROW_NEON) 1053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 1054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert RAW to I420. 1059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint RAWToI420(const uint8* src_raw, int src_stride_raw, 1061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 1062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 1063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 1064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RAWTOYROW_NEON) 1067ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RAWToUVRow)(const uint8* src_raw, int src_stride_raw, 1068ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = RAWToUVRow_C; 1069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RAWToYRow)(const uint8* src_raw, uint8* dst_y, int pix) = 1070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToYRow_C; 1071ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1073ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToARGBRow_C; 1074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 1075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1076ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1077ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow_C; 1078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 1079ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (width * 4 + 15) & ~15; 1080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 1081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1082ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_raw || !dst_y || !dst_u || !dst_v || 1083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 1084ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1085ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1086ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1087ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1088ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1089ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_raw = src_raw + (height - 1) * src_stride_raw; 1090ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_raw = -src_stride_raw; 1091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RAWTOYROW_NEON) 1094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToYRow = RAWToYRow_Any_NEON; 1096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToYRow = RAWToYRow_NEON; 1098ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1099ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 1100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToUVRow = RAWToUVRow_Any_NEON; 1101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToUVRow = RAWToUVRow_NEON; 1103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else // HAS_RAWTOYROW_NEON 1107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RAWTOARGBROW_SSSE3) 1109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToARGBRow = RAWToARGBRow_Any_SSSE3; 1111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToARGBRow = RAWToARGBRow_SSSE3; 1113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_SSSE3; 1121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_SSSE3; 1127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_SSSE3; 1131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_ARGBTOUVROW_SSSE3 1135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_RAWTOYROW_NEON 1136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 1138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RAWTOYROW_NEON) 1139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToUVRow(src_raw, src_stride_raw, dst_u, dst_v, width); 1140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToYRow(src_raw, dst_y, width); 1141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToYRow(src_raw + src_stride_raw, dst_y + dst_stride_y, width); 1142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToARGBRow(src_raw, row, width); 1144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToARGBRow(src_raw + src_stride_raw, row + kRowSize, width); 1145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_raw += src_stride_raw * 2; 1150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 1151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 1152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 1153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 1155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RAWTOYROW_NEON) 1156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToUVRow(src_raw, 0, dst_u, dst_v, width); 1157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToYRow(src_raw, dst_y, width); 1158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RAWToARGBRow(src_raw, row, width); 1160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, 0, dst_u, dst_v, width); 1161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if !defined(HAS_RAWTOYROW_NEON) 1165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 1166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert RGB565 to I420. 1171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565, 1173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 1174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 1175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 1176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB565TOYROW_NEON) 1179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGB565ToUVRow)(const uint8* src_rgb565, int src_stride_rgb565, 1180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = RGB565ToUVRow_C; 1181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGB565ToYRow)(const uint8* src_rgb565, uint8* dst_y, int pix) = 1182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToYRow_C; 1183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGB565ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToARGBRow_C; 1186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 1187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow_C; 1190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 1191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (width * 4 + 15) & ~15; 1192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 1193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_rgb565 || !dst_y || !dst_u || !dst_v || 1195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 1196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565; 1202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_rgb565 = -src_stride_rgb565; 1203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB565TOYROW_NEON) 1206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToYRow = RGB565ToYRow_Any_NEON; 1208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToYRow = RGB565ToYRow_NEON; 1210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 1212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToUVRow = RGB565ToUVRow_Any_NEON; 1213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToUVRow = RGB565ToUVRow_NEON; 1215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else // HAS_RGB565TOYROW_NEON 1219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB565TOARGBROW_SSE2) 1221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && width >= 8) { 1222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2; 1223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToARGBRow = RGB565ToARGBRow_SSE2; 1225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_SSSE3; 1233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_SSSE3; 1239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_SSSE3; 1243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_ARGBTOUVROW_SSSE3 1247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_RGB565TOYROW_NEON 1248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 1250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB565TOYROW_NEON) 1251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToUVRow(src_rgb565, src_stride_rgb565, dst_u, dst_v, width); 1252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToYRow(src_rgb565, dst_y, width); 1253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToYRow(src_rgb565 + src_stride_rgb565, dst_y + dst_stride_y, width); 1254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToARGBRow(src_rgb565, row, width); 1256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToARGBRow(src_rgb565 + src_stride_rgb565, row + kRowSize, width); 1257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_rgb565 += src_stride_rgb565 * 2; 1262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 1263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 1264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 1265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 1267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGB565TOYROW_NEON) 1268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToUVRow(src_rgb565, 0, dst_u, dst_v, width); 1269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToYRow(src_rgb565, dst_y, width); 1270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGB565ToARGBRow(src_rgb565, row, width); 1272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, 0, dst_u, dst_v, width); 1273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if !defined(HAS_RGB565TOYROW_NEON) 1277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 1278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert ARGB1555 to I420. 1283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555, 1285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 1286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 1287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 1288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB1555TOYROW_NEON) 1291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGB1555ToUVRow)(const uint8* src_argb1555, int src_stride_argb1555, 1292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGB1555ToUVRow_C; 1293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGB1555ToYRow)(const uint8* src_argb1555, uint8* dst_y, int pix) = 1294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToYRow_C; 1295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGB1555ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToARGBRow_C; 1298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 1299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow_C; 1302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 1303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (width * 4 + 15) & ~15; 1304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 1305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb1555 || !dst_y || !dst_u || !dst_v || 1307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 1308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555; 1314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb1555 = -src_stride_argb1555; 1315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB1555TOYROW_NEON) 1318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToYRow = ARGB1555ToYRow_Any_NEON; 1320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToYRow = ARGB1555ToYRow_NEON; 1322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 1324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToUVRow = ARGB1555ToUVRow_Any_NEON; 1325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToUVRow = ARGB1555ToUVRow_NEON; 1327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else // HAS_ARGB1555TOYROW_NEON 1331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB1555TOARGBROW_SSE2) 1333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && width >= 8) { 1334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2; 1335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2; 1337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_SSSE3; 1345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_SSSE3; 1351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_SSSE3; 1355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_ARGBTOUVROW_SSSE3 1359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_ARGB1555TOYROW_NEON 1360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 1362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB1555TOYROW_NEON) 1363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width); 1364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToYRow(src_argb1555, dst_y, width); 1365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToYRow(src_argb1555 + src_stride_argb1555, dst_y + dst_stride_y, 1366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width); 1367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToARGBRow(src_argb1555, row, width); 1369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555, row + kRowSize, 1370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width); 1371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb1555 += src_stride_argb1555 * 2; 1376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 1377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 1378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 1379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 1381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB1555TOYROW_NEON) 1382ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToUVRow(src_argb1555, 0, dst_u, dst_v, width); 1383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToYRow(src_argb1555, dst_y, width); 1384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB1555ToARGBRow(src_argb1555, row, width); 1386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, 0, dst_u, dst_v, width); 1387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if !defined(HAS_ARGB1555TOYROW_NEON) 1391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 1392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert ARGB4444 to I420. 1397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444, 1399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 1400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 1401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 1402ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB4444TOYROW_NEON) 1405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGB4444ToUVRow)(const uint8* src_argb4444, int src_stride_argb4444, 1406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGB4444ToUVRow_C; 1407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGB4444ToYRow)(const uint8* src_argb4444, uint8* dst_y, int pix) = 1408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToYRow_C; 1409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGB4444ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToARGBRow_C; 1412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 1413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow_C; 1416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Allocate 2 rows of ARGB. 1417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kRowSize = (width * 4 + 15) & ~15; 1418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(row, kRowSize * 2); 1419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1420ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb4444 || !dst_y || !dst_u || !dst_v || 1421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 1422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444; 1428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb4444 = -src_stride_argb4444; 1429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB4444TOYROW_NEON) 1432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToYRow = ARGB4444ToYRow_Any_NEON; 1434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToYRow = ARGB4444ToYRow_NEON; 1436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 1438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToUVRow = ARGB4444ToUVRow_Any_NEON; 1439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToUVRow = ARGB4444ToUVRow_NEON; 1441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else // HAS_ARGB4444TOYROW_NEON 1445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB4444TOARGBROW_SSE2) 1447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && width >= 8) { 1448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2; 1449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2; 1451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow = ARGBToUVRow_SSSE3; 1459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBTOUVROW_SSSE3) 1463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Any_SSSE3; 1465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow = ARGBToYRow_SSSE3; 1469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_ARGBTOUVROW_SSSE3 1473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif // HAS_ARGB4444TOYROW_NEON 1474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 1476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB4444TOYROW_NEON) 1477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToUVRow(src_argb4444, src_stride_argb4444, dst_u, dst_v, width); 1478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToYRow(src_argb4444, dst_y, width); 1479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToYRow(src_argb4444 + src_stride_argb4444, dst_y + dst_stride_y, 1480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width); 1481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToARGBRow(src_argb4444, row, width); 1483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToARGBRow(src_argb4444 + src_stride_argb4444, row + kRowSize, 1484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width); 1485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb4444 += src_stride_argb4444 * 2; 1490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 1491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 1492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 1493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height & 1) { 1495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGB4444TOYROW_NEON) 1496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToUVRow(src_argb4444, 0, dst_u, dst_v, width); 1497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToYRow(src_argb4444, dst_y, width); 1498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#else 1499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGB4444ToARGBRow(src_argb4444, row, width); 1500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToUVRow(row, 0, dst_u, dst_v, width); 1501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBToYRow(row, dst_y, width); 1502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if !defined(HAS_ARGB4444TOYROW_NEON) 1505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(row); 1506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 1511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // extern "C" 1512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // namespace libyuv 1513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1514