133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp/*
233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *  Copyright 2012 The LibYuv Project Authors. All rights reserved.
333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *
433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *  Use of this source code is governed by a BSD-style license
533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *  that can be found in the LICENSE file in the root of the source
633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *  tree. An additional intellectual property rights grant can be found
733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *  in the file PATENTS.  All contributing project authors may
833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *  be found in the AUTHORS file in the root of the source tree.
933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp */
1033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
1133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/convert_from.h"
1233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
1333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/basic_types.h"
1433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/convert.h"  // For I420Copy
1533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/cpu_id.h"
1633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/format_conversion.h"
1733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/planar_functions.h"
1833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/rotate.h"
1933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/video_common.h"
2033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/row.h"
2133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
2233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef __cplusplus
2333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampnamespace libyuv {
2433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampextern "C" {
2533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
2633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
2733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
2833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToI422(const uint8* src_y, int src_stride_y,
2933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
3033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
3133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_y, int dst_stride_y,
3233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_u, int dst_stride_u,
3333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_v, int dst_stride_v,
3433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
3533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
3633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_y || !dst_u || !dst_v ||
3733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
3833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
3933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
4033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
4133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
4233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
4333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y = dst_y + (height - 1) * dst_stride_y;
4433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u = dst_u + (height - 1) * dst_stride_u;
4533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v = dst_v + (height - 1) * dst_stride_v;
4633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_y = -dst_stride_y;
4733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_u = -dst_stride_u;
4833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_v = -dst_stride_v;
4933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
5033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int halfwidth = (width + 1) >> 1;
5133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
5233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_COPYROW_NEON)
5333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(halfwidth, 64)) {
5433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow = CopyRow_NEON;
5533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
5633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_COPYROW_X86)
5733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (IS_ALIGNED(halfwidth, 4)) {
5833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow = CopyRow_X86;
5933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_COPYROW_SSE2)
6033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(halfwidth, 32) &&
6133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        IS_ALIGNED(src_u, 16) && IS_ALIGNED(src_stride_u, 16) &&
6233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        IS_ALIGNED(src_v, 16) && IS_ALIGNED(src_stride_v, 16) &&
6333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        IS_ALIGNED(dst_u, 16) && IS_ALIGNED(dst_stride_u, 16) &&
6433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        IS_ALIGNED(dst_v, 16) && IS_ALIGNED(dst_stride_v, 16)) {
6533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      CopyRow = CopyRow_SSE2;
6633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
6733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
6833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
6933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
7033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
7133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Copy Y plane
7233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (dst_y) {
7333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
7433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
7533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
7633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // UpSample U plane.
7733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int y;
7833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (y = 0; y < height - 1; y += 2) {
7933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow(src_u, dst_u, halfwidth);
8033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow(src_u, dst_u + dst_stride_u, halfwidth);
8133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_u += src_stride_u;
8233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u += dst_stride_u * 2;
8333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
8433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height & 1) {
8533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow(src_u, dst_u, halfwidth);
8633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
8733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
8833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // UpSample V plane.
8933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (y = 0; y < height - 1; y += 2) {
9033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow(src_v, dst_v, halfwidth);
9133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow(src_v, dst_v + dst_stride_v, halfwidth);
9233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_v += src_stride_v;
9333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v += dst_stride_v * 2;
9433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
9533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height & 1) {
9633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyRow(src_v, dst_v, halfwidth);
9733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
9833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
9933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
10033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
10133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// use Bilinear for upsampling chroma
10233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ScalePlaneBilinear(int src_width, int src_height,
10333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int dst_width, int dst_height,
10433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int src_stride, int dst_stride,
10533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* src_ptr, uint8* dst_ptr);
10633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
10733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
10833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToI444(const uint8* src_y, int src_stride_y,
10933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
11033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
11133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_y, int dst_stride_y,
11233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_u, int dst_stride_u,
11333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_v, int dst_stride_v,
11433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
11533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u|| !src_v ||
11633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_y || !dst_u || !dst_v ||
11733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
11833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
11933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
12033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
12133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
12233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
12333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y = dst_y + (height - 1) * dst_stride_y;
12433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u = dst_u + (height - 1) * dst_stride_u;
12533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v = dst_v + (height - 1) * dst_stride_v;
12633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_y = -dst_stride_y;
12733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_u = -dst_stride_u;
12833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_v = -dst_stride_v;
12933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
13033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
13133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Copy Y plane
13233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (dst_y) {
13333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
13433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
13533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
13633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int halfwidth = (width + 1) >> 1;
13733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int halfheight = (height + 1) >> 1;
13833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
13933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Upsample U plane.
14033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  ScalePlaneBilinear(halfwidth, halfheight,
14133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height,
14233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_stride_u,
14333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_stride_u,
14433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_u, dst_u);
14533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
14633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Upsample V plane.
14733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  ScalePlaneBilinear(halfwidth, halfheight,
14833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height,
14933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_stride_v,
15033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_stride_v,
15133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_v, dst_v);
15233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
15333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
15433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
15533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// 420 chroma is 1/2 width, 1/2 height
15633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// 411 chroma is 1/4 width, 1x height
15733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
15833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToI411(const uint8* src_y, int src_stride_y,
15933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
16033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
16133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_y, int dst_stride_y,
16233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_u, int dst_stride_u,
16333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_v, int dst_stride_v,
16433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
16533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
16633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_y || !dst_u || !dst_v ||
16733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
16833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
16933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
17033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
17133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
17233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
17333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y = dst_y + (height - 1) * dst_stride_y;
17433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u = dst_u + (height - 1) * dst_stride_u;
17533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v = dst_v + (height - 1) * dst_stride_v;
17633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_y = -dst_stride_y;
17733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_u = -dst_stride_u;
17833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_v = -dst_stride_v;
17933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
18033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
18133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Copy Y plane
18233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (dst_y) {
18333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
18433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
18533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
18633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int halfwidth = (width + 1) >> 1;
18733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int halfheight = (height + 1) >> 1;
18833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int quarterwidth = (width + 3) >> 2;
18933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
19033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Resample U plane.
19133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  ScalePlaneBilinear(halfwidth, halfheight,  // from 1/2 width, 1/2 height
19233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     quarterwidth, height,  // to 1/4 width, 1x height
19333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_stride_u,
19433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_stride_u,
19533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_u, dst_u);
19633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
19733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Resample V plane.
19833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  ScalePlaneBilinear(halfwidth, halfheight,  // from 1/2 width, 1/2 height
19933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     quarterwidth, height,  // to 1/4 width, 1x height
20033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_stride_v,
20133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_stride_v,
20233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     src_v, dst_v);
20333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
20433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
20533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
20633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Copy to I400. Source can be I420,422,444,400,NV12,NV21
20733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
20833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I400Copy(const uint8* src_y, int src_stride_y,
20933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp             uint8* dst_y, int dst_stride_y,
21033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp             int width, int height) {
21133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !dst_y ||
21233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
21333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
21433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
21533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
21633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
21733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
21833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y = src_y + (height - 1) * src_stride_y;
21933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_stride_y = -src_stride_y;
22033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
22133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
22233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
22333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
22433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
22533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// YUY2 - Macro-pixel = 2 image pixels
22633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Y0U0Y1V0....Y2U2Y3V2...Y4U4Y5V4....
22733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
22833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// UYVY - Macro-pixel = 2 image pixels
22933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// U0Y0V0Y1
23033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
23133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if !defined(YUV_DISABLE_ASM) && defined(_M_IX86)
23233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define HAS_I42XTOYUY2ROW_SSE2
23333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp__declspec(naked) __declspec(align(16))
23433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic void I42xToYUY2Row_SSE2(const uint8* src_y,
23533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_u,
23633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_v,
23733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               uint8* dst_frame, int width) {
23833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  __asm {
23933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    push       esi
24033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    push       edi
24133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        eax, [esp + 8 + 4]    // src_y
24233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        esi, [esp + 8 + 8]    // src_u
24333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        edx, [esp + 8 + 12]   // src_v
24433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        edi, [esp + 8 + 16]   // dst_frame
24533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        ecx, [esp + 8 + 20]   // width
24633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    sub        edx, esi
24733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
24833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    align      16
24933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  convertloop:
25033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movq       xmm2, qword ptr [esi] // U
25133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movq       xmm3, qword ptr [esi + edx] // V
25233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    lea        esi, [esi + 8]
25333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    punpcklbw  xmm2, xmm3 // UV
25433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     xmm0, [eax] // Y
25533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    lea        eax, [eax + 16]
25633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     xmm1, xmm0
25733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    punpcklbw  xmm0, xmm2 // YUYV
25833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    punpckhbw  xmm1, xmm2
25933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     [edi], xmm0
26033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     [edi + 16], xmm1
26133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    lea        edi, [edi + 32]
26233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    sub        ecx, 16
26333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    jg         convertloop
26433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
26533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    pop        edi
26633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    pop        esi
26733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ret
26833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
26933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
27033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
27133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define HAS_I42XTOUYVYROW_SSE2
27233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp__declspec(naked) __declspec(align(16))
27333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic void I42xToUYVYRow_SSE2(const uint8* src_y,
27433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_u,
27533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_v,
27633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               uint8* dst_frame, int width) {
27733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  __asm {
27833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    push       esi
27933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    push       edi
28033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        eax, [esp + 8 + 4]    // src_y
28133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        esi, [esp + 8 + 8]    // src_u
28233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        edx, [esp + 8 + 12]   // src_v
28333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        edi, [esp + 8 + 16]   // dst_frame
28433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    mov        ecx, [esp + 8 + 20]   // width
28533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    sub        edx, esi
28633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
28733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    align      16
28833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  convertloop:
28933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movq       xmm2, qword ptr [esi] // U
29033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movq       xmm3, qword ptr [esi + edx] // V
29133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    lea        esi, [esi + 8]
29233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    punpcklbw  xmm2, xmm3 // UV
29333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     xmm0, [eax] // Y
29433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     xmm1, xmm2
29533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    lea        eax, [eax + 16]
29633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    punpcklbw  xmm1, xmm0 // UYVY
29733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    punpckhbw  xmm2, xmm0
29833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     [edi], xmm1
29933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    movdqa     [edi + 16], xmm2
30033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    lea        edi, [edi + 32]
30133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    sub        ecx, 16
30233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    jg         convertloop
30333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
30433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    pop        edi
30533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    pop        esi
30633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ret
30733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
30833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
30933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif !defined(YUV_DISABLE_ASM) && (defined(__x86_64__) || defined(__i386__))
31033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define HAS_I42XTOYUY2ROW_SSE2
31133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic void I42xToYUY2Row_SSE2(const uint8* src_y,
31233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_u,
31333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_v,
31433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               uint8* dst_frame, int width) {
31533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp asm volatile (
31633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "sub        %1,%2                            \n"
31733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ".p2align  4                                 \n"
31833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  "1:                                            \n"
31933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movq      (%1),%%xmm2                       \n"
32033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movq      (%1,%2,1),%%xmm3                  \n"
32133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "lea       0x8(%1),%1                        \n"
32233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "punpcklbw %%xmm3,%%xmm2                     \n"
32333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    (%0),%%xmm0                       \n"
32433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "lea       0x10(%0),%0                       \n"
32533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    %%xmm0,%%xmm1                     \n"
32633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "punpcklbw %%xmm2,%%xmm0                     \n"
32733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "punpckhbw %%xmm2,%%xmm1                     \n"
32833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    %%xmm0,(%3)                       \n"
32933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    %%xmm1,0x10(%3)                   \n"
33033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "lea       0x20(%3),%3                       \n"
33133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "sub       $0x10,%4                          \n"
33233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "jg         1b                               \n"
33333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    : "+r"(src_y),  // %0
33433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+r"(src_u),  // %1
33533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+r"(src_v),  // %2
33633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+r"(dst_frame),  // %3
33733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+rm"(width)  // %4
33833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    :
33933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    : "memory", "cc"
34033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(__SSE2__)
34133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    , "xmm0", "xmm1", "xmm2", "xmm3"
34233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
34333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  );
34433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
34533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
34633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define HAS_I42XTOUYVYROW_SSE2
34733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic void I42xToUYVYRow_SSE2(const uint8* src_y,
34833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_u,
34933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const uint8* src_v,
35033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               uint8* dst_frame, int width) {
35133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp asm volatile (
35233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "sub        %1,%2                            \n"
35333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ".p2align  4                                 \n"
35433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  "1:                                            \n"
35533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movq      (%1),%%xmm2                       \n"
35633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movq      (%1,%2,1),%%xmm3                  \n"
35733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "lea       0x8(%1),%1                        \n"
35833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "punpcklbw %%xmm3,%%xmm2                     \n"
35933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    (%0),%%xmm0                       \n"
36033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    %%xmm2,%%xmm1                     \n"
36133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "lea       0x10(%0),%0                       \n"
36233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "punpcklbw %%xmm0,%%xmm1                     \n"
36333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "punpckhbw %%xmm0,%%xmm2                     \n"
36433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    %%xmm1,(%3)                       \n"
36533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "movdqa    %%xmm2,0x10(%3)                   \n"
36633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "lea       0x20(%3),%3                       \n"
36733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "sub       $0x10,%4                          \n"
36833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    "jg         1b                               \n"
36933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    : "+r"(src_y),  // %0
37033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+r"(src_u),  // %1
37133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+r"(src_v),  // %2
37233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+r"(dst_frame),  // %3
37333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      "+rm"(width)  // %4
37433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    :
37533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    : "memory", "cc"
37633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(__SSE2__)
37733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    , "xmm0", "xmm1", "xmm2", "xmm3"
37833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
37933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  );
38033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
38133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
38233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
38333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic void I42xToYUY2Row_C(const uint8* src_y,
38433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            const uint8* src_u,
38533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            const uint8* src_v,
38633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            uint8* dst_frame, int width) {
38733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    for (int x = 0; x < width - 1; x += 2) {
38833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[0] = src_y[0];
38933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[1] = src_u[0];
39033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[2] = src_y[1];
39133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[3] = src_v[0];
39233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame += 4;
39333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_y += 2;
39433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += 1;
39533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += 1;
39633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
39733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (width & 1) {
39833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[0] = src_y[0];
39933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[1] = src_u[0];
40033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[2] = src_y[0];  // duplicate last y
40133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[3] = src_v[0];
40233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
40333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
40433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
40533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic void I42xToUYVYRow_C(const uint8* src_y,
40633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            const uint8* src_u,
40733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            const uint8* src_v,
40833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            uint8* dst_frame, int width) {
40933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    for (int x = 0; x < width - 1; x += 2) {
41033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[0] = src_u[0];
41133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[1] = src_y[0];
41233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[2] = src_v[0];
41333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[3] = src_y[1];
41433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame += 4;
41533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_y += 2;
41633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += 1;
41733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += 1;
41833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
41933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (width & 1) {
42033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[0] = src_u[0];
42133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[1] = src_y[0];
42233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[2] = src_v[0];
42333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      dst_frame[3] = src_y[0];  // duplicate last y
42433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
42533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
42633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
42733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Visual C x86 or GCC little endian.
42833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(__x86_64__) || defined(_M_X64) || \
42933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  defined(__i386__) || defined(_M_IX86) || \
43033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  defined(__arm__) || defined(_M_ARM) || \
43133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
43233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define LIBYUV_LITTLE_ENDIAN
43333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
43433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
43533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef LIBYUV_LITTLE_ENDIAN
43633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define WRITEWORD(p, v) *reinterpret_cast<uint32*>(p) = v
43733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#else
43833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic inline void WRITEWORD(uint8* p, uint32 v) {
43933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  p[0] = (uint8)(v & 255);
44033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  p[1] = (uint8)((v >> 8) & 255);
44133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  p[2] = (uint8)((v >> 16) & 255);
44233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  p[3] = (uint8)((v >> 24) & 255);
44333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
44433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
44533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
44633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define EIGHTTOTEN(x) (x << 2 | x >> 6)
44733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic void UYVYToV210Row_C(const uint8* src_uyvy, uint8* dst_v210, int width) {
44833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; x += 6) {
44933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    WRITEWORD(dst_v210 + 0, (EIGHTTOTEN(src_uyvy[0])) |
45033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            (EIGHTTOTEN(src_uyvy[1]) << 10) |
45133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            (EIGHTTOTEN(src_uyvy[2]) << 20));
45233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    WRITEWORD(dst_v210 + 4, (EIGHTTOTEN(src_uyvy[3])) |
45333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            (EIGHTTOTEN(src_uyvy[4]) << 10) |
45433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            (EIGHTTOTEN(src_uyvy[5]) << 20));
45533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    WRITEWORD(dst_v210 + 8, (EIGHTTOTEN(src_uyvy[6])) |
45633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            (EIGHTTOTEN(src_uyvy[7]) << 10) |
45733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                            (EIGHTTOTEN(src_uyvy[8]) << 20));
45833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    WRITEWORD(dst_v210 + 12, (EIGHTTOTEN(src_uyvy[9])) |
45933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                             (EIGHTTOTEN(src_uyvy[10]) << 10) |
46033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                             (EIGHTTOTEN(src_uyvy[11]) << 20));
46133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_uyvy += 12;
46233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v210 += 16;
46333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
46433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
46533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
46633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// TODO(fbarchard): Deprecate, move or expand 422 support?
46733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
46833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I422ToYUY2(const uint8* src_y, int src_stride_y,
46933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
47033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
47133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_frame, int dst_stride_frame,
47233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
47333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v || !dst_frame ||
47433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
47533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
47633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
47733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
47833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
47933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
48033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame = dst_frame + (height - 1) * dst_stride_frame;
48133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_frame = -dst_stride_frame;
48233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
48333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I42xToYUY2Row)(const uint8* src_y, const uint8* src_u,
48433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* src_v, uint8* dst_frame, int width) =
48533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I42xToYUY2Row_C;
48633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I42XTOYUY2ROW_SSE2)
48733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2) &&
48833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(width, 16) &&
48933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) &&
49033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(dst_frame, 16) && IS_ALIGNED(dst_stride_frame, 16)) {
49133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToYUY2Row = I42xToYUY2Row_SSE2;
49233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
49333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
49433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
49533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
49633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToYUY2Row(src_y, src_u, src_y, dst_frame, width);
49733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
49833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_u += src_stride_u;
49933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_v += src_stride_v;
50033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame += dst_stride_frame;
50133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
50233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
50333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
50433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
50533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
50633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToYUY2(const uint8* src_y, int src_stride_y,
50733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
50833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
50933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_frame, int dst_stride_frame,
51033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
51133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v || !dst_frame ||
51233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
51333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
51433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
51533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
51633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
51733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
51833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame = dst_frame + (height - 1) * dst_stride_frame;
51933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_frame = -dst_stride_frame;
52033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
52133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I42xToYUY2Row)(const uint8* src_y, const uint8* src_u,
52233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* src_v, uint8* dst_frame, int width) =
52333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I42xToYUY2Row_C;
52433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I42XTOYUY2ROW_SSE2)
52533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2) &&
52633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(width, 16) &&
52733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) &&
52833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(dst_frame, 16) && IS_ALIGNED(dst_stride_frame, 16)) {
52933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToYUY2Row = I42xToYUY2Row_SSE2;
53033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
53133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
53233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
53333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height - 1; y += 2) {
53433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToYUY2Row(src_y, src_u, src_v, dst_frame, width);
53533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToYUY2Row(src_y + src_stride_y, src_u, src_v,
53633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                  dst_frame + dst_stride_frame, width);
53733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y * 2;
53833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_u += src_stride_u;
53933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_v += src_stride_v;
54033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame += dst_stride_frame * 2;
54133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
54233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height & 1) {
54333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToYUY2Row(src_y, src_u, src_v, dst_frame, width);
54433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
54533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
54633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
54733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
54833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// TODO(fbarchard): Deprecate, move or expand 422 support?
54933cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
55033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I422ToUYVY(const uint8* src_y, int src_stride_y,
55133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
55233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
55333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_frame, int dst_stride_frame,
55433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
55533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v || !dst_frame ||
55633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
55733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
55833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
55933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
56033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
56133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
56233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame = dst_frame + (height - 1) * dst_stride_frame;
56333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_frame = -dst_stride_frame;
56433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
56533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I42xToUYVYRow)(const uint8* src_y, const uint8* src_u,
56633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* src_v, uint8* dst_frame, int width) =
56733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I42xToUYVYRow_C;
56833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I42XTOUYVYROW_SSE2)
56933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2) &&
57033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(width, 16) &&
57133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) &&
57233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(dst_frame, 16) && IS_ALIGNED(dst_stride_frame, 16)) {
57333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow = I42xToUYVYRow_SSE2;
57433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
57533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
57633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
57733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
57833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow(src_y, src_u, src_y, dst_frame, width);
57933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
58033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_u += src_stride_u;
58133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_v += src_stride_v;
58233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame += dst_stride_frame;
58333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
58433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
58533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
58633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
58733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
58833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToUYVY(const uint8* src_y, int src_stride_y,
58933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
59033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
59133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_frame, int dst_stride_frame,
59233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
59333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v || !dst_frame ||
59433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
59533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
59633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
59733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
59833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
59933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
60033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame = dst_frame + (height - 1) * dst_stride_frame;
60133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_frame = -dst_stride_frame;
60233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
60333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I42xToUYVYRow)(const uint8* src_y, const uint8* src_u,
60433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* src_v, uint8* dst_frame, int width) =
60533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I42xToUYVYRow_C;
60633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I42XTOUYVYROW_SSE2)
60733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2) &&
60833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(width, 16) &&
60933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) &&
61033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(dst_frame, 16) && IS_ALIGNED(dst_stride_frame, 16)) {
61133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow = I42xToUYVYRow_SSE2;
61233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
61333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
61433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
61533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height - 1; y += 2) {
61633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow(src_y, src_u, src_v, dst_frame, width);
61733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow(src_y + src_stride_y, src_u, src_v,
61833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                  dst_frame + dst_stride_frame, width);
61933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y * 2;
62033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_u += src_stride_u;
62133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_v += src_stride_v;
62233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame += dst_stride_frame * 2;
62333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
62433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height & 1) {
62533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow(src_y, src_u, src_v, dst_frame, width);
62633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
62733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
62833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
62933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
63033cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
63133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToV210(const uint8* src_y, int src_stride_y,
63233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
63333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
63433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_frame, int dst_stride_frame,
63533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
63633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width * 16 / 6 > kMaxStride) {  // Row buffer of V210 is required.
63733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
63833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  } else if (!src_y || !src_u || !src_v || !dst_frame ||
63933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
64033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
64133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
64233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
64333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
64433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
64533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame = dst_frame + (height - 1) * dst_stride_frame;
64633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_frame = -dst_stride_frame;
64733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
64833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
64933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  SIMD_ALIGNED(uint8 row[kMaxStride]);
65033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*UYVYToV210Row)(const uint8* src_uyvy, uint8* dst_v210, int pix);
65133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  UYVYToV210Row = UYVYToV210Row_C;
65233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
65333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I42xToUYVYRow)(const uint8* src_y, const uint8* src_u,
65433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* src_v, uint8* dst_frame, int width) =
65533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I42xToUYVYRow_C;
65633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I42XTOUYVYROW_SSE2)
65733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2) &&
65833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(width, 16) &&
65933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16)) {
66033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow = I42xToUYVYRow_SSE2;
66133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
66233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
66333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
66433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height - 1; y += 2) {
66533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow(src_y, src_u, src_v, row, width);
66633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    UYVYToV210Row(row, dst_frame, width);
66733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow(src_y + src_stride_y, src_u, src_v, row, width);
66833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    UYVYToV210Row(row, dst_frame + dst_stride_frame, width);
66933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
67033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y * 2;
67133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_u += src_stride_u;
67233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_v += src_stride_v;
67333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_frame += dst_stride_frame * 2;
67433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
67533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height & 1) {
67633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I42xToUYVYRow(src_y, src_u, src_v, row, width);
67733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    UYVYToV210Row(row, dst_frame, width);
67833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
67933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
68033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
68133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
68233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to ARGB.
68333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
68433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToARGB(const uint8* src_y, int src_stride_y,
68533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
68633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
68733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_argb, int dst_stride_argb,
68833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
68933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v || !dst_argb ||
69033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
69133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
69233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
69333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
69433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
69533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
69633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb = dst_argb + (height - 1) * dst_stride_argb;
69733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_argb = -dst_stride_argb;
69833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
69933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToARGBRow)(const uint8* y_buf,
70033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* u_buf,
70133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* v_buf,
70233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        uint8* rgb_buf,
70333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int width) = I422ToARGBRow_C;
70433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TOARGBROW_NEON)
70533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
70633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_Any_NEON;
70733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 16)) {
70833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToARGBRow = I422ToARGBRow_NEON;
70933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
71033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
71133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TOARGBROW_SSSE3)
71233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
71333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
71433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 8)) {
71533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToARGBRow = I422ToARGBRow_Unaligned_SSSE3;
71633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
71733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        I422ToARGBRow = I422ToARGBRow_SSSE3;
71833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
71933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
72033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
72133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
72233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
72333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
72433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow(src_y, src_u, src_v, dst_argb, width);
72533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += dst_stride_argb;
72633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
72733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
72833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
72933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
73033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
73133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
73233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
73333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
73433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
73533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to BGRA.
73633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
73733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToBGRA(const uint8* src_y, int src_stride_y,
73833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
73933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
74033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_bgra, int dst_stride_bgra,
74133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
74233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
74333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_bgra ||
74433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
74533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
74633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
74733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
74833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
74933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
75033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_bgra = dst_bgra + (height - 1) * dst_stride_bgra;
75133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_bgra = -dst_stride_bgra;
75233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
75333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToBGRARow)(const uint8* y_buf,
75433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* u_buf,
75533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* v_buf,
75633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        uint8* rgb_buf,
75733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int width) = I422ToBGRARow_C;
75833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TOBGRAROW_NEON)
75933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
76033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToBGRARow = I422ToBGRARow_Any_NEON;
76133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 16)) {
76233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToBGRARow = I422ToBGRARow_NEON;
76333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
76433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
76533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TOBGRAROW_SSSE3)
76633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
76733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToBGRARow = I422ToBGRARow_Any_SSSE3;
76833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 8)) {
76933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToBGRARow = I422ToBGRARow_Unaligned_SSSE3;
77033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (IS_ALIGNED(dst_bgra, 16) && IS_ALIGNED(dst_stride_bgra, 16)) {
77133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        I422ToBGRARow = I422ToBGRARow_SSSE3;
77233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
77333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
77433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
77533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
77633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
77733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
77833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToBGRARow(src_y, src_u, src_v, dst_bgra, width);
77933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_bgra += dst_stride_bgra;
78033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
78133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
78233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
78333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
78433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
78533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
78633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
78733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
78833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
78933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to ABGR.
79033cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
79133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToABGR(const uint8* src_y, int src_stride_y,
79233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
79333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
79433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_abgr, int dst_stride_abgr,
79533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
79633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
79733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_abgr ||
79833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
79933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
80033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
80133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
80233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
80333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
80433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_abgr = dst_abgr + (height - 1) * dst_stride_abgr;
80533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_abgr = -dst_stride_abgr;
80633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
80733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToABGRRow)(const uint8* y_buf,
80833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* u_buf,
80933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* v_buf,
81033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        uint8* rgb_buf,
81133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int width) = I422ToABGRRow_C;
81233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TOABGRROW_NEON)
81333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
81433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToABGRRow = I422ToABGRRow_Any_NEON;
81533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 16)) {
81633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToABGRRow = I422ToABGRRow_NEON;
81733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
81833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
81933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TOABGRROW_SSSE3)
82033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
82133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToABGRRow = I422ToABGRRow_Any_SSSE3;
82233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 8)) {
82333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToABGRRow = I422ToABGRRow_Unaligned_SSSE3;
82433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (IS_ALIGNED(dst_abgr, 16) && IS_ALIGNED(dst_stride_abgr, 16)) {
82533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        I422ToABGRRow = I422ToABGRRow_SSSE3;
82633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
82733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
82833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
82933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
83033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
83133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
83233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToABGRRow(src_y, src_u, src_v, dst_abgr, width);
83333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_abgr += dst_stride_abgr;
83433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
83533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
83633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
83733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
83833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
83933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
84033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
84133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
84233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
84333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to RGBA.
84433cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
84533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToRGBA(const uint8* src_y, int src_stride_y,
84633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_u, int src_stride_u,
84733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               const uint8* src_v, int src_stride_v,
84833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               uint8* dst_rgba, int dst_stride_rgba,
84933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               int width, int height) {
85033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
85133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_rgba ||
85233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
85333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
85433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
85533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
85633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
85733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
85833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba;
85933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_rgba = -dst_stride_rgba;
86033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
86133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToRGBARow)(const uint8* y_buf,
86233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* u_buf,
86333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* v_buf,
86433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        uint8* rgb_buf,
86533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int width) = I422ToRGBARow_C;
86633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TORGBAROW_NEON)
86733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
86833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRGBARow = I422ToRGBARow_Any_NEON;
86933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 16)) {
87033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToRGBARow = I422ToRGBARow_NEON;
87133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
87233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
87333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TORGBAROW_SSSE3)
87433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
87533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRGBARow = I422ToRGBARow_Any_SSSE3;
87633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 8)) {
87733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToRGBARow = I422ToRGBARow_Unaligned_SSSE3;
87833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (IS_ALIGNED(dst_rgba, 16) && IS_ALIGNED(dst_stride_rgba, 16)) {
87933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        I422ToRGBARow = I422ToRGBARow_SSSE3;
88033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
88133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
88233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
88333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
88433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
88533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
88633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRGBARow(src_y, src_u, src_v, dst_rgba, width);
88733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgba += dst_stride_rgba;
88833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
88933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
89033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
89133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
89233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
89333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
89433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
89533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
89633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
89733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to RGB24.
89833cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
89933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToRGB24(const uint8* src_y, int src_stride_y,
90033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                const uint8* src_u, int src_stride_u,
90133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                const uint8* src_v, int src_stride_v,
90233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                uint8* dst_rgb24, int dst_stride_rgb24,
90333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                int width, int height) {
90433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
90533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_rgb24 ||
90633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
90733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
90833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
90933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
91033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
91133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
91233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24;
91333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_rgb24 = -dst_stride_rgb24;
91433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
91533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToRGB24Row)(const uint8* y_buf,
91633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         const uint8* u_buf,
91733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         const uint8* v_buf,
91833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         uint8* rgb_buf,
91933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         int width) = I422ToRGB24Row_C;
92033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TORGB24ROW_NEON)
92133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
92233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRGB24Row = I422ToRGB24Row_Any_NEON;
92333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 16)) {
92433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToRGB24Row = I422ToRGB24Row_NEON;
92533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
92633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
92733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TORGB24ROW_SSSE3)
92833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
92933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRGB24Row = I422ToRGB24Row_Any_SSSE3;
93033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 8)) {
93133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToRGB24Row = I422ToRGB24Row_Unaligned_SSSE3;
93233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (IS_ALIGNED(dst_rgb24, 16) && IS_ALIGNED(dst_stride_rgb24, 16)) {
93333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        I422ToRGB24Row = I422ToRGB24Row_SSSE3;
93433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
93533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
93633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
93733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
93833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
93933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
94033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRGB24Row(src_y, src_u, src_v, dst_rgb24, width);
94133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb24 += dst_stride_rgb24;
94233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
94333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
94433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
94533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
94633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
94733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
94833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
94933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
95033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
95133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to RAW.
95233cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
95333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToRAW(const uint8* src_y, int src_stride_y,
95433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              const uint8* src_u, int src_stride_u,
95533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              const uint8* src_v, int src_stride_v,
95633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              uint8* dst_raw, int dst_stride_raw,
95733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              int width, int height) {
95833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
95933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_raw ||
96033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
96133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
96233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
96333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
96433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
96533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
96633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_raw = dst_raw + (height - 1) * dst_stride_raw;
96733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_raw = -dst_stride_raw;
96833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
96933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToRAWRow)(const uint8* y_buf,
97033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       const uint8* u_buf,
97133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       const uint8* v_buf,
97233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       uint8* rgb_buf,
97333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       int width) = I422ToRAWRow_C;
97433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TORAWROW_NEON)
97533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
97633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRAWRow = I422ToRAWRow_Any_NEON;
97733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 16)) {
97833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToRAWRow = I422ToRAWRow_NEON;
97933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
98033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
98133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TORAWROW_SSSE3)
98233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
98333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRAWRow = I422ToRAWRow_Any_SSSE3;
98433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 8)) {
98533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I422ToRAWRow = I422ToRAWRow_Unaligned_SSSE3;
98633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (IS_ALIGNED(dst_raw, 16) && IS_ALIGNED(dst_stride_raw, 16)) {
98733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        I422ToRAWRow = I422ToRAWRow_SSSE3;
98833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
98933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
99033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
99133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
99233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
99333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
99433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToRAWRow(src_y, src_u, src_v, dst_raw, width);
99533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_raw += dst_stride_raw;
99633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
99733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
99833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
99933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
100033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
100133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
100233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
100333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
100433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
100533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to RGB565.
100633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
100733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToRGB565(const uint8* src_y, int src_stride_y,
100833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 const uint8* src_u, int src_stride_u,
100933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 const uint8* src_v, int src_stride_v,
101033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 uint8* dst_rgb, int dst_stride_rgb,
101133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 int width, int height) {
101233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
101333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_rgb ||
101433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
101533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
101633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
101733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
101833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
101933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
102033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb = dst_rgb + (height - 1) * dst_stride_rgb;
102133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_rgb = -dst_stride_rgb;
102233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
102333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToARGBRow)(const uint8* y_buf,
102433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* u_buf,
102533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* v_buf,
102633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        uint8* rgb_buf,
102733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int width) = I422ToARGBRow_C;
102833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TOARGBROW_NEON)
102933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
103033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_NEON;
103133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
103233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TOARGBROW_SSSE3)
103333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3)) {
103433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_SSSE3;
103533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
103633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
103733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
103833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  SIMD_ALIGNED(uint8 row[kMaxStride]);
103933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*ARGBToRGB565Row)(const uint8* src_rgb, uint8* dst_rgb, int pix) =
104033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToRGB565Row_C;
104133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_ARGBTORGB565ROW_SSE2)
104233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2)) {
104333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (width * 2 <= kMaxStride) {
104433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToRGB565Row = ARGBToRGB565Row_Any_SSE2;
104533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
104633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 4)) {
104733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToRGB565Row = ARGBToRGB565Row_SSE2;
104833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
104933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
105033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
105133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
105233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
105333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow(src_y, src_u, src_v, row, width);
105433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ARGBToRGB565Row(row, dst_rgb, width);
105533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb += dst_stride_rgb;
105633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
105733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
105833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
105933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
106033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
106133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
106233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
106333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
106433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
106533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to ARGB1555.
106633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
106733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToARGB1555(const uint8* src_y, int src_stride_y,
106833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   const uint8* src_u, int src_stride_u,
106933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   const uint8* src_v, int src_stride_v,
107033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   uint8* dst_argb, int dst_stride_argb,
107133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   int width, int height) {
107233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
107333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_argb ||
107433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
107533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
107633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
107733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
107833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
107933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
108033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb = dst_argb + (height - 1) * dst_stride_argb;
108133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_argb = -dst_stride_argb;
108233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
108333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToARGBRow)(const uint8* y_buf,
108433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* u_buf,
108533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* v_buf,
108633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        uint8* rgb_buf,
108733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int width) = I422ToARGBRow_C;
108833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TOARGBROW_NEON)
108933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
109033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_NEON;
109133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
109233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TOARGBROW_SSSE3)
109333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3)) {
109433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_SSSE3;
109533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
109633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
109733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
109833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  SIMD_ALIGNED(uint8 row[kMaxStride]);
109933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*ARGBToARGB1555Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
110033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToARGB1555Row_C;
110133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_ARGBTOARGB1555ROW_SSE2)
110233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2)) {
110333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (width * 2 <= kMaxStride) {
110433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToARGB1555Row = ARGBToARGB1555Row_Any_SSE2;
110533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
110633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 4)) {
110733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToARGB1555Row = ARGBToARGB1555Row_SSE2;
110833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
110933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
111033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
111133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
111233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
111333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow(src_y, src_u, src_v, row, width);
111433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ARGBToARGB1555Row(row, dst_argb, width);
111533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += dst_stride_argb;
111633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
111733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
111833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
111933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
112033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
112133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
112233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
112333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
112433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
112533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to ARGB4444.
112633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
112733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint I420ToARGB4444(const uint8* src_y, int src_stride_y,
112833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   const uint8* src_u, int src_stride_u,
112933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   const uint8* src_v, int src_stride_v,
113033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   uint8* dst_argb, int dst_stride_argb,
113133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   int width, int height) {
113233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!src_y || !src_u || !src_v ||
113333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      !dst_argb ||
113433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
113533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
113633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
113733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Negative height means invert the image.
113833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (height < 0) {
113933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    height = -height;
114033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb = dst_argb + (height - 1) * dst_stride_argb;
114133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_stride_argb = -dst_stride_argb;
114233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
114333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*I422ToARGBRow)(const uint8* y_buf,
114433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* u_buf,
114533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        const uint8* v_buf,
114633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        uint8* rgb_buf,
114733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                        int width) = I422ToARGBRow_C;
114833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_I422TOARGBROW_NEON)
114933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasNEON)) {
115033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_NEON;
115133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
115233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#elif defined(HAS_I422TOARGBROW_SSSE3)
115333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSSE3)) {
115433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow = I422ToARGBRow_SSSE3;
115533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
115633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
115733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
115833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  SIMD_ALIGNED(uint8 row[kMaxStride]);
115933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  void (*ARGBToARGB4444Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
116033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp     ARGBToARGB4444Row_C;
116133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_ARGBTOARGB4444ROW_SSE2)
116233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (TestCpuFlag(kCpuHasSSE2)) {
116333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (width * 2 <= kMaxStride) {
116433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToARGB4444Row = ARGBToARGB4444Row_Any_SSE2;
116533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
116633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (IS_ALIGNED(width, 4)) {
116733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBToARGB4444Row = ARGBToARGB4444Row_SSE2;
116833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
116933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
117033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
117133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
117233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
117333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    I422ToARGBRow(src_y, src_u, src_v, row, width);
117433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ARGBToARGB4444Row(row, dst_argb, width);
117533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += dst_stride_argb;
117633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_y += src_stride_y;
117733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (y & 1) {
117833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_u += src_stride_u;
117933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      src_v += src_stride_v;
118033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
118133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
118233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return 0;
118333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
118433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
118533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert I420 to specified format
118633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
118733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampint ConvertFromI420(const uint8* y, int y_stride,
118833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    const uint8* u, int u_stride,
118933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    const uint8* v, int v_stride,
119033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    uint8* dst_sample, int dst_sample_stride,
119133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    int width, int height,
119233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    uint32 format) {
119333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (!y || !u|| !v || !dst_sample ||
119433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      width <= 0 || height == 0) {
119533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return -1;
119633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
119733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int r = 0;
119833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  switch (format) {
119933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // Single plane formats
120033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_YUY2:
120133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToYUY2(y, y_stride,
120233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
120333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
120433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample,
120533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample_stride ? dst_sample_stride : width * 2,
120633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
120733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
120833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_UYVY:
120933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToUYVY(y, y_stride,
121033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
121133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
121233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample,
121333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample_stride ? dst_sample_stride : width * 2,
121433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
121533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
121633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_V210:
121733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToV210(y, y_stride,
121833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
121933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
122033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample,
122133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample_stride ? dst_sample_stride :
122233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         (width + 47) / 48 * 128,
122333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
122433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
122533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_RGBP:
122633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToRGB565(y, y_stride,
122733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       u, u_stride,
122833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       v, v_stride,
122933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       dst_sample,
123033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       dst_sample_stride ? dst_sample_stride : width * 2,
123133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       width, height);
123233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
123333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_RGBO:
123433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToARGB1555(y, y_stride,
123533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         u, u_stride,
123633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         v, v_stride,
123733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         dst_sample,
123833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         dst_sample_stride ? dst_sample_stride : width * 2,
123933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         width, height);
124033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
124133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_R444:
124233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToARGB4444(y, y_stride,
124333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         u, u_stride,
124433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         v, v_stride,
124533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         dst_sample,
124633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         dst_sample_stride ? dst_sample_stride : width * 2,
124733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                         width, height);
124833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
124933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_24BG:
125033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToRGB24(y, y_stride,
125133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      u, u_stride,
125233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      v, v_stride,
125333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      dst_sample,
125433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      dst_sample_stride ? dst_sample_stride : width * 3,
125533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      width, height);
125633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
125733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_RAW:
125833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToRAW(y, y_stride,
125933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    u, u_stride,
126033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    v, v_stride,
126133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    dst_sample,
126233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    dst_sample_stride ? dst_sample_stride : width * 3,
126333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    width, height);
126433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
126533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_ARGB:
126633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToARGB(y, y_stride,
126733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
126833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
126933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample,
127033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample_stride ? dst_sample_stride : width * 4,
127133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
127233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
127333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_BGRA:
127433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToBGRA(y, y_stride,
127533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
127633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
127733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample,
127833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample_stride ? dst_sample_stride : width * 4,
127933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
128033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
128133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_ABGR:
128233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToABGR(y, y_stride,
128333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
128433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
128533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample,
128633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample_stride ? dst_sample_stride : width * 4,
128733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
128833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
128933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_RGBA:
129033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToRGBA(y, y_stride,
129133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
129233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
129333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample,
129433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample_stride ? dst_sample_stride : width * 4,
129533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
129633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
129733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_BGGR:
129833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToBayerBGGR(y, y_stride,
129933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          u, u_stride,
130033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          v, v_stride,
130133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample,
130233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample_stride ? dst_sample_stride : width,
130333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          width, height);
130433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
130533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_GBRG:
130633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToBayerGBRG(y, y_stride,
130733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          u, u_stride,
130833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          v, v_stride,
130933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample,
131033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample_stride ? dst_sample_stride : width,
131133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          width, height);
131233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
131333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_GRBG:
131433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToBayerGRBG(y, y_stride,
131533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          u, u_stride,
131633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          v, v_stride,
131733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample,
131833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample_stride ? dst_sample_stride : width,
131933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          width, height);
132033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
132133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_RGGB:
132233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToBayerRGGB(y, y_stride,
132333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          u, u_stride,
132433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          v, v_stride,
132533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample,
132633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          dst_sample_stride ? dst_sample_stride : width,
132733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          width, height);
132833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
132933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_I400:
133033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I400Copy(y, y_stride,
133133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   dst_sample,
133233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   dst_sample_stride ? dst_sample_stride : width,
133333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   width, height);
133433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
133533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // Triplanar formats
133633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // TODO(fbarchard): halfstride instead of halfwidth
133733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_I420:
133833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_YU12:
133933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_YV12: {
134033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int halfwidth = (width + 1) / 2;
134133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int halfheight = (height + 1) / 2;
134233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_u;
134333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_v;
134433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (format == FOURCC_YV12) {
134533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_v = dst_sample + width * height;
134633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_u = dst_v + halfwidth * halfheight;
134733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      } else {
134833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_u = dst_sample + width * height;
134933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_v = dst_u + halfwidth * halfheight;
135033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
135133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420Copy(y, y_stride,
135233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   u, u_stride,
135333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   v, v_stride,
135433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   dst_sample, width,
135533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   dst_u, halfwidth,
135633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   dst_v, halfwidth,
135733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   width, height);
135833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
135933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
136033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_I422:
136133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_YV16: {
136233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int halfwidth = (width + 1) / 2;
136333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_u;
136433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_v;
136533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (format == FOURCC_YV16) {
136633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_v = dst_sample + width * height;
136733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_u = dst_v + halfwidth * height;
136833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      } else {
136933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_u = dst_sample + width * height;
137033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_v = dst_u + halfwidth * height;
137133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
137233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToI422(y, y_stride,
137333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
137433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
137533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample, width,
137633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_u, halfwidth,
137733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_v, halfwidth,
137833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
137933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
138033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
138133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_I444:
138233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_YV24: {
138333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_u;
138433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_v;
138533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (format == FOURCC_YV24) {
138633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_v = dst_sample + width * height;
138733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_u = dst_v + width * height;
138833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      } else {
138933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_u = dst_sample + width * height;
139033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        dst_v = dst_u + width * height;
139133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
139233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToI444(y, y_stride,
139333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
139433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
139533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample, width,
139633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_u, width,
139733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_v, width,
139833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
139933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
140033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
140133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    case FOURCC_I411: {
140233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int quarterwidth = (width + 3) / 4;
140333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_u = dst_sample + width * height;
140433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      uint8* dst_v = dst_u + quarterwidth * height;
140533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = I420ToI411(y, y_stride,
140633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     u, u_stride,
140733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     v, v_stride,
140833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_sample, width,
140933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_u, quarterwidth,
141033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     dst_v, quarterwidth,
141133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     width, height);
141233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      break;
141333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
141433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
141533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // Formats not supported - MJPG, biplanar, some rgb formats.
141633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    default:
141733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      return -1;  // unknown fourcc - return failure code.
141833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
141933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return r;
142033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
142133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
142233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef __cplusplus
142333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}  // extern "C"
142433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}  // namespace libyuv
142533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
1426