133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp/*
233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp *  Copyright 2011 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/row.h"
1233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
1333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include <string.h>  // For memcpy
1433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
1533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/basic_types.h"
1633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
1733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef __cplusplus
1833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampnamespace libyuv {
1933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampextern "C" {
2033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
2133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
2233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid BGRAToARGBRow_C(const uint8* src_bgra, uint8* dst_argb, int width) {
2333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
2433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // To support in-place conversion.
2533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a = src_bgra[0];
2633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_bgra[1];
2733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_bgra[2];
2833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_bgra[3];
2933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = b;
3033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = g;
3133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = r;
3233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = a;
3333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
3433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_bgra += 4;
3533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
3633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
3733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
3833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ABGRToARGBRow_C(const uint8* src_abgr, uint8* dst_argb, int width) {
3933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
4033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // To support in-place conversion.
4133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_abgr[0];
4233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_abgr[1];
4333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_abgr[2];
4433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a = src_abgr[3];
4533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = b;
4633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = g;
4733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = r;
4833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = a;
4933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
5033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_abgr += 4;
5133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
5233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
5333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
5433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid RGBAToARGBRow_C(const uint8* src_abgr, uint8* dst_argb, int width) {
5533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
5633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // To support in-place conversion.
5733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a = src_abgr[0];
5833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_abgr[1];
5933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_abgr[2];
6033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_abgr[3];
6133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = b;
6233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = g;
6333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = r;
6433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = a;
6533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
6633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_abgr += 4;
6733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
6833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
6933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
7033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid RGB24ToARGBRow_C(const uint8* src_rgb24, uint8* dst_argb, int width) {
7133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
7233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_rgb24[0];
7333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_rgb24[1];
7433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_rgb24[2];
7533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = b;
7633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = g;
7733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = r;
7833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = 255u;
7933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
8033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_rgb24 += 3;
8133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
8233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
8333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
8433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int width) {
8533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
8633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_raw[0];
8733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_raw[1];
8833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_raw[2];
8933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = b;
9033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = g;
9133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = r;
9233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = 255u;
9333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
9433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_raw += 3;
9533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
9633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
9733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
9833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid RGB565ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int width) {
9933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
10033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_rgb[0] & 0x1f;
10133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = (src_rgb[0] >> 5) | ((src_rgb[1] & 0x07) << 3);
10233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_rgb[1] >> 3;
10333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = (b << 3) | (b >> 2);
10433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = (g << 2) | (g >> 4);
10533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = (r << 3) | (r >> 2);
10633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = 255u;
10733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
10833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_rgb += 2;
10933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
11033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
11133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
11233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGB1555ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int width) {
11333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
11433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_rgb[0] & 0x1f;
11533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = (src_rgb[0] >> 5) | ((src_rgb[1] & 0x03) << 3);
11633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = (src_rgb[1] & 0x7c) >> 2;
11733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a = src_rgb[1] >> 7;
11833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = (b << 3) | (b >> 2);
11933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = (g << 3) | (g >> 2);
12033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = (r << 3) | (r >> 2);
12133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = -a;
12233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
12333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_rgb += 2;
12433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
12533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
12633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
12733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGB4444ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int width) {
12833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
12933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_rgb[0] & 0x0f;
13033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_rgb[0] >> 4;
13133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_rgb[1] & 0x0f;
13233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a = src_rgb[1] >> 4;
13333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = (b << 4) | b;
13433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = (g << 4) | g;
13533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = (r << 4) | r;
13633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = (a << 4) | a;
13733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
13833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_rgb += 2;
13933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
14033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
14133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
14233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBToRGBARow_C(const uint8* src_argb, uint8* dst_rgb, int width) {
14333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
14433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_argb[0];
14533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_argb[1];
14633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_argb[2];
14733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a = src_argb[3];
14833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[0] = a;
14933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[1] = b;
15033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[2] = g;
15133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[3] = r;
15233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb += 4;
15333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 4;
15433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
15533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
15633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
15733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBToRGB24Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
15833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
15933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_argb[0];
16033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_argb[1];
16133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_argb[2];
16233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[0] = b;
16333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[1] = g;
16433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[2] = r;
16533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb += 3;
16633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 4;
16733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
16833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
16933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
17033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBToRAWRow_C(const uint8* src_argb, uint8* dst_rgb, int width) {
17133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
17233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b = src_argb[0];
17333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g = src_argb[1];
17433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r = src_argb[2];
17533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[0] = r;
17633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[1] = g;
17733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb[2] = b;
17833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb += 3;
17933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 4;
18033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
18133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
18233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
18333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// TODO(fbarchard): support big endian CPU
18433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBToRGB565Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
18533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
18633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b0 = src_argb[0] >> 3;
18733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g0 = src_argb[1] >> 2;
18833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r0 = src_argb[2] >> 3;
18933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b1 = src_argb[4] >> 3;
19033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g1 = src_argb[5] >> 2;
19133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r1 = src_argb[6] >> 3;
19233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    *reinterpret_cast<uint32*>(dst_rgb) = b0 | (g0 << 5) | (r0 << 11) |
19333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        (b1 << 16) | (g1 << 21) | (r1 << 27);
19433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb += 4;
19533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 8;
19633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
19733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
19833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b0 = src_argb[0] >> 3;
19933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g0 = src_argb[1] >> 2;
20033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r0 = src_argb[2] >> 3;
20133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    *reinterpret_cast<uint16*>(dst_rgb) = b0 | (g0 << 5) | (r0 << 11);
20233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
20333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
20433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
20533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
20633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
20733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b0 = src_argb[0] >> 3;
20833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g0 = src_argb[1] >> 3;
20933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r0 = src_argb[2] >> 3;
21033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a0 = src_argb[3] >> 7;
21133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b1 = src_argb[4] >> 3;
21233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g1 = src_argb[5] >> 3;
21333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r1 = src_argb[6] >> 3;
21433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a1 = src_argb[7] >> 7;
21533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    *reinterpret_cast<uint32*>(dst_rgb) =
21633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        b0 | (g0 << 5) | (r0 << 10) | (a0 << 15) |
21733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        (b1 << 16) | (g1 << 21) | (r1 << 26) | (a1 << 31);
21833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb += 4;
21933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 8;
22033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
22133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
22233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b0 = src_argb[0] >> 3;
22333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g0 = src_argb[1] >> 3;
22433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r0 = src_argb[2] >> 3;
22533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a0 = src_argb[3] >> 7;
22633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    *reinterpret_cast<uint16*>(dst_rgb) =
22733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        b0 | (g0 << 5) | (r0 << 10) | (a0 << 15);
22833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
22933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
23033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
23133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBToARGB4444Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
23233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
23333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b0 = src_argb[0] >> 4;
23433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g0 = src_argb[1] >> 4;
23533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r0 = src_argb[2] >> 4;
23633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a0 = src_argb[3] >> 4;
23733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b1 = src_argb[4] >> 4;
23833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g1 = src_argb[5] >> 4;
23933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r1 = src_argb[6] >> 4;
24033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a1 = src_argb[7] >> 4;
24133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    *reinterpret_cast<uint32*>(dst_rgb) =
24233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        b0 | (g0 << 4) | (r0 << 8) | (a0 << 12) |
24333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        (b1 << 16) | (g1 << 20) | (r1 << 24) | (a1 << 28);
24433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_rgb += 4;
24533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 8;
24633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
24733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
24833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 b0 = src_argb[0] >> 4;
24933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 g0 = src_argb[1] >> 4;
25033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 r0 = src_argb[2] >> 4;
25133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 a0 = src_argb[3] >> 4;
25233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    *reinterpret_cast<uint16*>(dst_rgb) =
25333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        b0 | (g0 << 4) | (r0 << 8) | (a0 << 12);
25433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
25533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
25633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
25733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic __inline int RGBToY(uint8 r, uint8 g, uint8 b) {
25833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return (( 66 * r + 129 * g +  25 * b + 128) >> 8) + 16;
25933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
26033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
26133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic __inline int RGBToU(uint8 r, uint8 g, uint8 b) {
26233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return ((-38 * r -  74 * g + 112 * b + 128) >> 8) + 128;
26333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
26433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic __inline int RGBToV(uint8 r, uint8 g, uint8 b) {
26533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return ((112 * r -  94 * g -  18 * b + 128) >> 8) + 128;
26633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
26733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
26833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define MAKEROWY(NAME, R, G, B) \
26933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid NAME ## ToYRow_C(const uint8* src_argb0, uint8* dst_y, int width) {       \
27033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {                                            \
27133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y[0] = RGBToY(src_argb0[R], src_argb0[G], src_argb0[B]);               \
27233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb0 += 4;                                                            \
27333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y += 1;                                                                \
27433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }                                                                            \
27533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}                                                                              \
27633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid NAME ## ToUVRow_C(const uint8* src_rgb0, int src_stride_rgb,              \
27733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       uint8* dst_u, uint8* dst_v, int width) {                \
27833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  const uint8* src_rgb1 = src_rgb0 + src_stride_rgb;                           \
27933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {                                     \
28033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 ab = (src_rgb0[B] + src_rgb0[B + 4] +                                \
28133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               src_rgb1[B] + src_rgb1[B + 4]) >> 2;                            \
28233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 ag = (src_rgb0[G] + src_rgb0[G + 4] +                                \
28333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               src_rgb1[G] + src_rgb1[G + 4]) >> 2;                            \
28433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 ar = (src_rgb0[R] + src_rgb0[R + 4] +                                \
28533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp               src_rgb1[R] + src_rgb1[R + 4]) >> 2;                            \
28633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[0] = RGBToU(ar, ag, ab);                                             \
28733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[0] = RGBToV(ar, ag, ab);                                             \
28833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_rgb0 += 8;                                                             \
28933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_rgb1 += 8;                                                             \
29033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u += 1;                                                                \
29133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v += 1;                                                                \
29233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }                                                                            \
29333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {                                                             \
29433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 ab = (src_rgb0[B] + src_rgb1[B]) >> 1;                               \
29533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 ag = (src_rgb0[G] + src_rgb1[G]) >> 1;                               \
29633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 ar = (src_rgb0[R] + src_rgb1[R]) >> 1;                               \
29733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[0] = RGBToU(ar, ag, ab);                                             \
29833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[0] = RGBToV(ar, ag, ab);                                             \
29933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }                                                                            \
30033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
30133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
30233cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampMAKEROWY(ARGB, 2, 1, 0)
30333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampMAKEROWY(BGRA, 1, 2, 3)
30433cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampMAKEROWY(ABGR, 0, 1, 2)
30533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampMAKEROWY(RGBA, 3, 2, 1)
30633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
30733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// http://en.wikipedia.org/wiki/Grayscale.
30833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// 0.11 * B + 0.59 * G + 0.30 * R
30933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Coefficients rounded to multiple of 2 for consistency with SSSE3 version.
31033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic __inline int RGBToGray(uint8 r, uint8 g, uint8 b) {
31133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return (( 76 * r + 152 * g +  28 * b) >> 8);
31233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
31333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
31433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBGrayRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
31533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
31633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 y = RGBToGray(src_argb[2], src_argb[1], src_argb[0]);
31733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = dst_argb[1] = dst_argb[0] = y;
31833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = src_argb[3];
31933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
32033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 4;
32133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
32233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
32333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
32433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Convert a row of image to Sepia tone.
32533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBSepiaRow_C(uint8* dst_argb, int width) {
32633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
32733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int b = dst_argb[0];
32833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int g = dst_argb[1];
32933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int r = dst_argb[2];
33033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int sb = (b * 17 + g * 68 + r * 35) >> 7;
33133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int sg = (b * 22 + g * 88 + r * 45) >> 7;
33233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int sr = (b * 24 + g * 98 + r * 50) >> 7;
33333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    // b does not over flow. a is preserved from original.
33433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sg > 255) {
33533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sg = 255;
33633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
33733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sr > 255) {
33833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sr = 255;
33933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
34033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = sb;
34133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = sg;
34233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = sr;
34333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
34433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
34533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
34633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
34733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Apply color matrix to a row of image. Matrix is signed.
34833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBColorMatrixRow_C(uint8* dst_argb, const int8* matrix_argb, int width) {
34933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
35033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int b = dst_argb[0];
35133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int g = dst_argb[1];
35233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int r = dst_argb[2];
35333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int a = dst_argb[3];
35433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int sb = (b * matrix_argb[0] + g * matrix_argb[1] +
35533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              r * matrix_argb[2] + a * matrix_argb[3]) >> 7;
35633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int sg = (b * matrix_argb[4] + g * matrix_argb[5] +
35733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              r * matrix_argb[6] + a * matrix_argb[7]) >> 7;
35833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int sr = (b * matrix_argb[8] + g * matrix_argb[9] +
35933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              r * matrix_argb[10] + a * matrix_argb[11]) >> 7;
36033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sb < 0) {
36133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sb = 0;
36233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
36333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sb > 255) {
36433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sb = 255;
36533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
36633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sg < 0) {
36733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sg = 0;
36833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
36933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sg > 255) {
37033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sg = 255;
37133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
37233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sr < 0) {
37333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sr = 0;
37433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
37533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (sr > 255) {
37633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      sr = 255;
37733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
37833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = sb;
37933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = sg;
38033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = sr;
38133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
38233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
38333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
38433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
38533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Apply color table to a row of image.
38633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) {
38733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
38833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int b = dst_argb[0];
38933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int g = dst_argb[1];
39033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int r = dst_argb[2];
39133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int a = dst_argb[3];
39233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = table_argb[b * 4 + 0];
39333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = table_argb[g * 4 + 1];
39433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = table_argb[r * 4 + 2];
39533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = table_argb[a * 4 + 3];
39633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
39733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
39833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
39933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
40033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBQuantizeRow_C(uint8* dst_argb, int scale, int interval_size,
40133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                       int interval_offset, int width) {
40233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
40333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int b = dst_argb[0];
40433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int g = dst_argb[1];
40533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int r = dst_argb[2];
40633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = (b * scale >> 16) * interval_size + interval_offset;
40733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = (g * scale >> 16) * interval_size + interval_offset;
40833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = (r * scale >> 16) * interval_size + interval_offset;
40933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
41033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
41133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
41233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
41333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
41433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Copy a Y to RGB.
41533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
41633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint8 y = src_y[0];
41733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = dst_argb[1] = dst_argb[0] = y;
41833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = 255u;
41933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
42033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    ++src_y;
42133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
42233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
42333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
42433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// C reference code that mimics the YUV assembly.
42533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
42633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define YG 74 /* static_cast<int8>(1.164 * 64 + 0.5) */
42733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
42833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define UB 127 /* min(63,static_cast<int8>(2.018 * 64)) */
42933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define UG -25 /* static_cast<int8>(-0.391 * 64 - 0.5) */
43033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define UR 0
43133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
43233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define VB 0
43333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define VG -52 /* static_cast<int8>(-0.813 * 64 - 0.5) */
43433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define VR 102 /* static_cast<int8>(1.596 * 64 + 0.5) */
43533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
43633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Bias
43733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define BB UB * 128 + VB * 128
43833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define BG UG * 128 + VG * 128
43933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define BR UR * 128 + VR * 128
44033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
44133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic __inline uint32 Clip(int32 val) {
44233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (val < 0) {
44333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return static_cast<uint32>(0);
44433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  } else if (val > 255) {
44533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    return static_cast<uint32>(255);
44633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
44733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  return static_cast<uint32>(val);
44833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
44933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
45033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic __inline void YuvPixel(uint8 y, uint8 u, uint8 v, uint8* rgb_buf,
45133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                              int ashift, int rshift, int gshift, int bshift) {
45233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int32 y1 = (static_cast<int32>(y) - 16) * YG;
45333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  uint32 b = Clip(static_cast<int32>((u * UB + v * VB) - (BB) + y1) >> 6);
45433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  uint32 g = Clip(static_cast<int32>((u * UG + v * VG) - (BG) + y1) >> 6);
45533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  uint32 r = Clip(static_cast<int32>((u * UR + v * VR) - (BR) + y1) >> 6);
45633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  *reinterpret_cast<uint32*>(rgb_buf) = (b << bshift) |
45733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                                        (g << gshift) |
45833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                                        (r << rshift) |
45933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                                        (255u << ashift);
46033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
46133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
46233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic __inline void YuvPixel2(uint8 y, uint8 u, uint8 v,
46333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               uint8* b, uint8* g, uint8* r) {
46433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int32 y1 = (static_cast<int32>(y) - 16) * YG;
46533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  *b = Clip(static_cast<int32>((u * UB + v * VB) - (BB) + y1) >> 6);
46633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  *g = Clip(static_cast<int32>((u * UG + v * VG) - (BG) + y1) >> 6);
46733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  *r = Clip(static_cast<int32>((u * UR + v * VR) - (BR) + y1) >> 6);
46833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
46933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
47033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I444ToARGBRow_C(const uint8* y_buf,
47133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* u_buf,
47233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* v_buf,
47333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
47433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
47533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
47633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf, 24, 16, 8, 0);
47733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 1;
47833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
47933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
48033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 4;  // Advance 1 pixel.
48133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
48233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
48333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
48433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Also used for 420
48533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I422ToARGBRow_C(const uint8* y_buf,
48633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* u_buf,
48733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* v_buf,
48833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
48933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
49033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
49133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 24, 16, 8, 0);
49233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], u_buf[0], v_buf[0], rgb_buf + 4, 24, 16, 8, 0);
49333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
49433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
49533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
49633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 8;  // Advance 2 pixels.
49733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
49833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
49933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 24, 16, 8, 0);
50033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
50133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
50233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
50333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I422ToRGB24Row_C(const uint8* y_buf,
50433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      const uint8* u_buf,
50533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      const uint8* v_buf,
50633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      uint8* rgb_buf,
50733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      int width) {
50833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
50933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel2(y_buf[0], u_buf[0], v_buf[0],
51033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
51133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel2(y_buf[1], u_buf[0], v_buf[0],
51233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              rgb_buf + 3, rgb_buf + 4, rgb_buf + 5);
51333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
51433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
51533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
51633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 6;  // Advance 2 pixels.
51733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
51833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
51933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel2(y_buf[0], u_buf[0], v_buf[0],
52033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
52133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
52233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
52333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
52433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I422ToRAWRow_C(const uint8* y_buf,
52533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    const uint8* u_buf,
52633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    const uint8* v_buf,
52733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    uint8* rgb_buf,
52833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    int width) {
52933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
53033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel2(y_buf[0], u_buf[0], v_buf[0],
53133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              rgb_buf + 2, rgb_buf + 1, rgb_buf + 0);
53233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel2(y_buf[1], u_buf[0], v_buf[0],
53333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              rgb_buf + 5, rgb_buf + 4, rgb_buf + 3);
53433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
53533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
53633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
53733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 6;  // Advance 2 pixels.
53833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
53933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
54033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel2(y_buf[0], u_buf[0], v_buf[0],
54133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp              rgb_buf + 0, rgb_buf + 1, rgb_buf + 2);
54233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
54333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
54433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
54533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I411ToARGBRow_C(const uint8* y_buf,
54633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* u_buf,
54733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* v_buf,
54833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
54933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
55033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 3; x += 4) {
55133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 24, 16, 8, 0);
55233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], u_buf[0], v_buf[0], rgb_buf + 4, 24, 16, 8, 0);
55333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[2], u_buf[0], v_buf[0], rgb_buf + 8, 24, 16, 8, 0);
55433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[3], u_buf[0], v_buf[0], rgb_buf + 12, 24, 16, 8, 0);
55533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 4;
55633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
55733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
55833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 16;  // Advance 4 pixels.
55933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
56033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 2) {
56133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 24, 16, 8, 0);
56233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], u_buf[0], v_buf[0], rgb_buf + 4, 24, 16, 8, 0);
56333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
56433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 8;  // Advance 2 pixels.
56533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
56633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
56733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 24, 16, 8, 0);
56833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
56933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
57033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
57133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid NV12ToARGBRow_C(const uint8* y_buf,
57233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* uv_buf,
57333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
57433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
57533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
57633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], uv_buf[0], uv_buf[1], rgb_buf + 0, 24, 16, 8, 0);
57733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], uv_buf[0], uv_buf[1], rgb_buf + 4, 24, 16, 8, 0);
57833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
57933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uv_buf += 2;
58033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 8;  // Advance 2 pixels.
58133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
58233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
58333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], uv_buf[0], uv_buf[1], rgb_buf + 0, 24, 16, 8, 0);
58433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
58533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
58633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
58733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid NV21ToARGBRow_C(const uint8* y_buf,
58833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* vu_buf,
58933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
59033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
59133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
59233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], vu_buf[1], vu_buf[0], rgb_buf + 0, 24, 16, 8, 0);
59333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], vu_buf[1], vu_buf[0], rgb_buf + 4, 24, 16, 8, 0);
59433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
59533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    vu_buf += 2;
59633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 8;  // Advance 2 pixels.
59733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
59833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
59933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], vu_buf[1], vu_buf[0], rgb_buf + 0, 24, 16, 8, 0);
60033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
60133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
60233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
60333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I422ToBGRARow_C(const uint8* y_buf,
60433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* u_buf,
60533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* v_buf,
60633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
60733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
60833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
60933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 0, 8, 16, 24);
61033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], u_buf[0], v_buf[0], rgb_buf + 4, 0, 8, 16, 24);
61133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
61233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
61333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
61433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 8;  // Advance 2 pixels.
61533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
61633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
61733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf, 0, 8, 16, 24);
61833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
61933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
62033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
62133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I422ToABGRRow_C(const uint8* y_buf,
62233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* u_buf,
62333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* v_buf,
62433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
62533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
62633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
62733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 24, 0, 8, 16);
62833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], u_buf[0], v_buf[0], rgb_buf + 4, 24, 0, 8, 16);
62933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
63033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
63133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
63233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 8;  // Advance 2 pixels.
63333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
63433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
63533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 24, 0, 8, 16);
63633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
63733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
63833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
63933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid I422ToRGBARow_C(const uint8* y_buf,
64033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* u_buf,
64133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     const uint8* v_buf,
64233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* rgb_buf,
64333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     int width) {
64433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
64533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 0, 24, 16, 8);
64633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[1], u_buf[0], v_buf[0], rgb_buf + 4, 0, 24, 16, 8);
64733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 2;
64833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    u_buf += 1;
64933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    v_buf += 1;
65033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 8;  // Advance 2 pixels.
65133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
65233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
65333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], u_buf[0], v_buf[0], rgb_buf + 0, 0, 24, 16, 8);
65433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
65533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
65633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
65733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid YToARGBRow_C(const uint8* y_buf, uint8* rgb_buf, int width) {
65833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
65933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    YuvPixel(y_buf[0], 128, 128, rgb_buf, 24, 16, 8, 0);
66033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    y_buf += 1;
66133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    rgb_buf += 4;  // Advance 1 pixel.
66233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
66333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
66433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
66533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid MirrorRow_C(const uint8* src, uint8* dst, int width) {
66633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  src += width - 1;
66733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
66833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[x] = src[0];
66933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[x + 1] = src[-1];
67033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src -= 2;
67133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
67233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
67333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[width - 1] = src[0];
67433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
67533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
67633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
67733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid MirrorRowUV_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) {
67833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  src_uv += (width - 1) << 1;
67933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
68033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[x] = src_uv[0];
68133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[x + 1] = src_uv[-2];
68233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[x] = src_uv[1];
68333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[x + 1] = src_uv[-2 + 1];
68433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_uv -= 4;
68533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
68633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
68733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[width - 1] = src_uv[0];
68833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[width - 1] = src_uv[1];
68933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
69033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
69133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
69233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBMirrorRow_C(const uint8* src, uint8* dst, int width) {
69333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  const uint32* src32 = reinterpret_cast<const uint32*>(src);
69433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  uint32* dst32 = reinterpret_cast<uint32*>(dst);
69533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  src32 += width - 1;
69633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
69733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst32[x] = src32[0];
69833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst32[x + 1] = src32[-1];
69933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src32 -= 2;
70033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
70133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
70233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst32[width - 1] = src32[0];
70333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
70433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
70533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
70633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid SplitUV_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width) {
70733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
70833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[x] = src_uv[0];
70933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[x + 1] = src_uv[2];
71033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[x] = src_uv[1];
71133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[x + 1] = src_uv[3];
71233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_uv += 4;
71333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
71433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
71533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[width - 1] = src_uv[0];
71633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[width - 1] = src_uv[1];
71733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
71833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
71933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
72033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid CopyRow_C(const uint8* src, uint8* dst, int count) {
72133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  memcpy(dst, src, count);
72233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
72333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
72433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid SetRow8_C(uint8* dst, uint32 v8, int count) {
72533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef _MSC_VER
72633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // VC will generate rep stosb.
72733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < count; ++x) {
72833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[x] = v8;
72933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
73033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#else
73133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  memset(dst, v8, count);
73233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
73333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
73433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
73533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid SetRows32_C(uint8* dst, uint32 v32, int width,
73633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 int dst_stride, int height) {
73733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int y = 0; y < height; ++y) {
73833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32* d = reinterpret_cast<uint32*>(dst);
73933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    for (int x = 0; x < width; ++x) {
74033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      d[x] = v32;
74133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
74233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst += dst_stride;
74333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
74433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
74533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
74633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Filter 2 rows of YUY2 UV's (422) into U and V (420).
74733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid YUY2ToUVRow_C(const uint8* src_yuy2, int src_stride_yuy2,
74833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   uint8* dst_u, uint8* dst_v, int width) {
74933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Output a row of UV values, filtering 2 rows of YUY2.
75033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; x += 2) {
75133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[0] = (src_yuy2[1] + src_yuy2[src_stride_yuy2 + 1] + 1) >> 1;
75233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[0] = (src_yuy2[3] + src_yuy2[src_stride_yuy2 + 3] + 1) >> 1;
75333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_yuy2 += 4;
75433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u += 1;
75533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v += 1;
75633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
75733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
75833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
75933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Copy row of YUY2 UV's (422) into U and V (422).
76033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid YUY2ToUV422Row_C(const uint8* src_yuy2,
76133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      uint8* dst_u, uint8* dst_v, int width) {
76233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Output a row of UV values.
76333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; x += 2) {
76433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[0] = src_yuy2[1];
76533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[0] = src_yuy2[3];
76633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_yuy2 += 4;
76733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u += 1;
76833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v += 1;
76933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
77033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
77133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
77233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Copy row of YUY2 Y's (422) into Y (420/422).
77333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid YUY2ToYRow_C(const uint8* src_yuy2, uint8* dst_y, int width) {
77433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Output a row of Y values.
77533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
77633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y[x] = src_yuy2[0];
77733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y[x + 1] = src_yuy2[2];
77833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_yuy2 += 4;
77933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
78033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
78133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y[width - 1] = src_yuy2[0];
78233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
78333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
78433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
78533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Filter 2 rows of UYVY UV's (422) into U and V (420).
78633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid UYVYToUVRow_C(const uint8* src_uyvy, int src_stride_uyvy,
78733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                   uint8* dst_u, uint8* dst_v, int width) {
78833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Output a row of UV values.
78933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; x += 2) {
79033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[0] = (src_uyvy[0] + src_uyvy[src_stride_uyvy + 0] + 1) >> 1;
79133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[0] = (src_uyvy[2] + src_uyvy[src_stride_uyvy + 2] + 1) >> 1;
79233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_uyvy += 4;
79333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u += 1;
79433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v += 1;
79533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
79633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
79733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
79833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Copy row of UYVY UV's (422) into U and V (422).
79933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid UYVYToUV422Row_C(const uint8* src_uyvy,
80033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                      uint8* dst_u, uint8* dst_v, int width) {
80133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Output a row of UV values.
80233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; x += 2) {
80333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u[0] = src_uyvy[0];
80433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v[0] = src_uyvy[2];
80533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_uyvy += 4;
80633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_u += 1;
80733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_v += 1;
80833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
80933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
81033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
81133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Copy row of UYVY Y's (422) into Y (420/422).
81233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid UYVYToYRow_C(const uint8* src_uyvy, uint8* dst_y, int width) {
81333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Output a row of Y values.
81433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
81533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y[x] = src_uyvy[1];
81633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y[x + 1] = src_uyvy[3];
81733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_uyvy += 4;
81833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
81933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
82033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_y[width - 1] = src_uyvy[1];
82133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
82233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
82333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
82433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define BLEND(f, b, a) (((256 - a) * b) >> 8) + f
82533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
82633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Blend src_argb0 over src_argb1 and store to dst_argb.
82733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// dst_argb may be src_argb0 or src_argb1.
82833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// This code mimics the SSSE3 version for better testability.
82933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBBlendRow_C(const uint8* src_argb0, const uint8* src_argb1,
83033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    uint8* dst_argb, int width) {
83133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width - 1; x += 2) {
83233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 fb = src_argb0[0];
83333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 fg = src_argb0[1];
83433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 fr = src_argb0[2];
83533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 a = src_argb0[3];
83633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 bb = src_argb1[0];
83733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 bg = src_argb1[1];
83833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 br = src_argb1[2];
83933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = BLEND(fb, bb, a);
84033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = BLEND(fg, bg, a);
84133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = BLEND(fr, br, a);
84233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = 255u;
84333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
84433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    fb = src_argb0[4 + 0];
84533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    fg = src_argb0[4 + 1];
84633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    fr = src_argb0[4 + 2];
84733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    a = src_argb0[4 + 3];
84833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    bb = src_argb1[4 + 0];
84933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    bg = src_argb1[4 + 1];
85033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    br = src_argb1[4 + 2];
85133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[4 + 0] = BLEND(fb, bb, a);
85233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[4 + 1] = BLEND(fg, bg, a);
85333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[4 + 2] = BLEND(fr, br, a);
85433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[4 + 3] = 255u;
85533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb0 += 8;
85633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb1 += 8;
85733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 8;
85833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
85933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
86033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
86133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 fb = src_argb0[0];
86233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 fg = src_argb0[1];
86333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 fr = src_argb0[2];
86433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 a = src_argb0[3];
86533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 bb = src_argb1[0];
86633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 bg = src_argb1[1];
86733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 br = src_argb1[2];
86833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = BLEND(fb, bb, a);
86933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = BLEND(fg, bg, a);
87033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = BLEND(fr, br, a);
87133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = 255u;
87233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
87333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
87433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef BLEND
87533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define ATTENUATE(f, a) (a | (a << 8)) * (f | (f << 8)) >> 24
87633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
87733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Multiply source RGB by alpha and store to destination.
87833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// This code mimics the SSSE3 version for better testability.
87933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
88033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int i = 0; i < width - 1; i += 2) {
88133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 b = src_argb[0];
88233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 g = src_argb[1];
88333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 r = src_argb[2];
88433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 a = src_argb[3];
88533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = ATTENUATE(b, a);
88633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = ATTENUATE(g, a);
88733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = ATTENUATE(r, a);
88833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = a;
88933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    b = src_argb[4];
89033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    g = src_argb[5];
89133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    r = src_argb[6];
89233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    a = src_argb[7];
89333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[4] = ATTENUATE(b, a);
89433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[5] = ATTENUATE(g, a);
89533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[6] = ATTENUATE(r, a);
89633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[7] = a;
89733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 8;
89833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 8;
89933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
90033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
90133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  if (width & 1) {
90233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 b = src_argb[0];
90333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 g = src_argb[1];
90433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 r = src_argb[2];
90533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 a = src_argb[3];
90633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = ATTENUATE(b, a);
90733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = ATTENUATE(g, a);
90833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = ATTENUATE(r, a);
90933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = a;
91033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
91133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
91233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef ATTENUATE
91333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
91433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Divide source RGB by alpha and store to destination.
91533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// b = (b * 255 + (a / 2)) / a;
91633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// g = (g * 255 + (a / 2)) / a;
91733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// r = (r * 255 + (a / 2)) / a;
91833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Reciprocal method is off by 1 on some values. ie 125
91933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// 8.16 fixed point inverse table
92033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define T(a) 0x10000 / a
92133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampuint32 fixed_invtbl8[256] = {
92233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  0x0100, T(0x01), T(0x02), T(0x03), T(0x04), T(0x05), T(0x06), T(0x07),
92333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x08), T(0x09), T(0x0a), T(0x0b), T(0x0c), T(0x0d), T(0x0e), T(0x0f),
92433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x10), T(0x11), T(0x12), T(0x13), T(0x14), T(0x15), T(0x16), T(0x17),
92533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x18), T(0x19), T(0x1a), T(0x1b), T(0x1c), T(0x1d), T(0x1e), T(0x1f),
92633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x20), T(0x21), T(0x22), T(0x23), T(0x24), T(0x25), T(0x26), T(0x27),
92733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x28), T(0x29), T(0x2a), T(0x2b), T(0x2c), T(0x2d), T(0x2e), T(0x2f),
92833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x30), T(0x31), T(0x32), T(0x33), T(0x34), T(0x35), T(0x36), T(0x37),
92933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x38), T(0x39), T(0x3a), T(0x3b), T(0x3c), T(0x3d), T(0x3e), T(0x3f),
93033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x40), T(0x41), T(0x42), T(0x43), T(0x44), T(0x45), T(0x46), T(0x47),
93133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x48), T(0x49), T(0x4a), T(0x4b), T(0x4c), T(0x4d), T(0x4e), T(0x4f),
93233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x50), T(0x51), T(0x52), T(0x53), T(0x54), T(0x55), T(0x56), T(0x57),
93333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x58), T(0x59), T(0x5a), T(0x5b), T(0x5c), T(0x5d), T(0x5e), T(0x5f),
93433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x60), T(0x61), T(0x62), T(0x63), T(0x64), T(0x65), T(0x66), T(0x67),
93533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x68), T(0x69), T(0x6a), T(0x6b), T(0x6c), T(0x6d), T(0x6e), T(0x6f),
93633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x70), T(0x71), T(0x72), T(0x73), T(0x74), T(0x75), T(0x76), T(0x77),
93733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x78), T(0x79), T(0x7a), T(0x7b), T(0x7c), T(0x7d), T(0x7e), T(0x7f),
93833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x80), T(0x81), T(0x82), T(0x83), T(0x84), T(0x85), T(0x86), T(0x87),
93933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x88), T(0x89), T(0x8a), T(0x8b), T(0x8c), T(0x8d), T(0x8e), T(0x8f),
94033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x90), T(0x91), T(0x92), T(0x93), T(0x94), T(0x95), T(0x96), T(0x97),
94133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0x98), T(0x99), T(0x9a), T(0x9b), T(0x9c), T(0x9d), T(0x9e), T(0x9f),
94233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xa0), T(0xa1), T(0xa2), T(0xa3), T(0xa4), T(0xa5), T(0xa6), T(0xa7),
94333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xa8), T(0xa9), T(0xaa), T(0xab), T(0xac), T(0xad), T(0xae), T(0xaf),
94433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xb0), T(0xb1), T(0xb2), T(0xb3), T(0xb4), T(0xb5), T(0xb6), T(0xb7),
94533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xb8), T(0xb9), T(0xba), T(0xbb), T(0xbc), T(0xbd), T(0xbe), T(0xbf),
94633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xc0), T(0xc1), T(0xc2), T(0xc3), T(0xc4), T(0xc5), T(0xc6), T(0xc7),
94733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xc8), T(0xc9), T(0xca), T(0xcb), T(0xcc), T(0xcd), T(0xce), T(0xcf),
94833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xd0), T(0xd1), T(0xd2), T(0xd3), T(0xd4), T(0xd5), T(0xd6), T(0xd7),
94933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xd8), T(0xd9), T(0xda), T(0xdb), T(0xdc), T(0xdd), T(0xde), T(0xdf),
95033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xe0), T(0xe1), T(0xe2), T(0xe3), T(0xe4), T(0xe5), T(0xe6), T(0xe7),
95133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xe8), T(0xe9), T(0xea), T(0xeb), T(0xec), T(0xed), T(0xee), T(0xef),
95233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xf0), T(0xf1), T(0xf2), T(0xf3), T(0xf4), T(0xf5), T(0xf6), T(0xf7),
95333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  T(0xf8), T(0xf9), T(0xfa), T(0xfb), T(0xfc), T(0xfd), T(0xfe), 0x0100 };
95433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef T
95533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
95633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
95733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int i = 0; i < width; ++i) {
95833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 b = src_argb[0];
95933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 g = src_argb[1];
96033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uint32 r = src_argb[2];
96133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 a = src_argb[3];
96233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    if (a) {
96333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      const uint32 ia = fixed_invtbl8[a];  // 8.16 fixed point
96433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      b = (b * ia) >> 8;
96533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      g = (g * ia) >> 8;
96633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      r = (r * ia) >> 8;
96733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      // Clamping should not be necessary but is free in assembly.
96833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (b > 255) {
96933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        b = 255;
97033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
97133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (g > 255) {
97233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        g = 255;
97333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
97433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      if (r > 255) {
97533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        r = 255;
97633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      }
97733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
97833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = b;
97933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = g;
98033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = r;
98133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = a;
98233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 4;
98333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
98433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
98533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
98633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
98733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Wrappers to handle odd width
98833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define YANY(NAMEANY, I420TORGB_SSE, I420TORGB_C, UV_SHIFT)                    \
98933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    void NAMEANY(const uint8* y_buf,                                           \
99033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 const uint8* u_buf,                                           \
99133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 const uint8* v_buf,                                           \
99233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 uint8* rgb_buf,                                               \
99333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 int width) {                                                  \
99433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int n = width & ~7;                                                      \
99533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I420TORGB_SSE(y_buf, u_buf, v_buf, rgb_buf, n);                          \
99633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      I420TORGB_C(y_buf + n,                                                   \
99733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                  u_buf + (n >> UV_SHIFT),                                     \
99833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                  v_buf + (n >> UV_SHIFT),                                     \
99933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                  rgb_buf + n * 4, width & 7);                                 \
100033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
100133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
100233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Wrappers to handle odd width
100333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define Y2NY(NAMEANY, NV12TORGB_SSE, NV12TORGB_C, UV_SHIFT)                    \
100433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    void NAMEANY(const uint8* y_buf,                                           \
100533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 const uint8* uv_buf,                                          \
100633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 uint8* rgb_buf,                                               \
100733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 int width) {                                                  \
100833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int n = width & ~7;                                                      \
100933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      NV12TORGB_SSE(y_buf, uv_buf, rgb_buf, n);                                \
101033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      NV12TORGB_C(y_buf + n,                                                   \
101133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                  uv_buf + (n >> UV_SHIFT),                                    \
101233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                  rgb_buf + n * 4, width & 7);                                 \
101333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
101433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
101533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
101633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_I422TOARGBROW_SSSE3
101733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I444ToARGBRow_Any_SSSE3, I444ToARGBRow_Unaligned_SSSE3, I444ToARGBRow_C, 0)
101833cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToARGBRow_Any_SSSE3, I422ToARGBRow_Unaligned_SSSE3, I422ToARGBRow_C, 1)
101933cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I411ToARGBRow_Any_SSSE3, I411ToARGBRow_Unaligned_SSSE3, I411ToARGBRow_C, 2)
102033cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampY2NY(NV12ToARGBRow_Any_SSSE3, NV12ToARGBRow_Unaligned_SSSE3, NV12ToARGBRow_C, 0)
102133cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampY2NY(NV21ToARGBRow_Any_SSSE3, NV21ToARGBRow_Unaligned_SSSE3, NV21ToARGBRow_C, 0)
102233cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToBGRARow_Any_SSSE3, I422ToBGRARow_Unaligned_SSSE3, I422ToBGRARow_C, 1)
102333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToABGRRow_Any_SSSE3, I422ToABGRRow_Unaligned_SSSE3, I422ToABGRRow_C, 1)
102433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
102533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_I422TORGB24ROW_SSSE3
102633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToRGB24Row_Any_SSSE3, I422ToRGB24Row_Unaligned_SSSE3,                 \
102733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp     I422ToRGB24Row_C, 1)
102833cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToRAWRow_Any_SSSE3, I422ToRAWRow_Unaligned_SSSE3, I422ToRAWRow_C, 1)
102933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
103033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_I422TORGBAROW_SSSE3
103133cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToRGBARow_Any_SSSE3, I422ToRGBARow_Unaligned_SSSE3, I422ToRGBARow_C, 1)
103233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
103333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_I422TOARGBROW_NEON
103433cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToARGBRow_Any_NEON, I422ToARGBRow_NEON, I422ToARGBRow_C, 1)
103533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToBGRARow_Any_NEON, I422ToBGRARow_NEON, I422ToBGRARow_C, 1)
103633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToABGRRow_Any_NEON, I422ToABGRRow_NEON, I422ToABGRRow_C, 1)
103733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToRGBARow_Any_NEON, I422ToRGBARow_NEON, I422ToRGBARow_C, 1)
103833cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampY2NY(NV12ToARGBRow_Any_NEON, NV12ToARGBRow_NEON, NV12ToARGBRow_C, 0)
103933cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampY2NY(NV21ToARGBRow_Any_NEON, NV21ToARGBRow_NEON, NV21ToARGBRow_C, 0)
104033cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToRGB24Row_Any_NEON, I422ToRGB24Row_NEON, I422ToRGB24Row_C, 1)
104133cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(I422ToRAWRow_Any_NEON, I422ToRAWRow_NEON, I422ToRAWRow_C, 1)
104233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
104333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef YANY
104433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
104533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define RGBANY(NAMEANY, ARGBTORGB, BPP)                                        \
104633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    void NAMEANY(const uint8* argb_buf,                                        \
104733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 uint8* rgb_buf,                                               \
104833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 int width) {                                                  \
104933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      SIMD_ALIGNED(uint8 row[kMaxStride]);                                     \
105033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBTORGB(argb_buf, row, width);                                         \
105133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      memcpy(rgb_buf, row, width * BPP);                                       \
105233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
105333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
105433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_ARGBTORGB24ROW_SSSE3)
105533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampRGBANY(ARGBToRGB24Row_Any_SSSE3, ARGBToRGB24Row_SSSE3, 3)
105633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampRGBANY(ARGBToRAWRow_Any_SSSE3, ARGBToRAWRow_SSSE3, 3)
105733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampRGBANY(ARGBToRGB565Row_Any_SSE2, ARGBToRGB565Row_SSE2, 2)
105833cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampRGBANY(ARGBToARGB1555Row_Any_SSE2, ARGBToARGB1555Row_SSE2, 2)
105933cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampRGBANY(ARGBToARGB4444Row_Any_SSE2, ARGBToARGB4444Row_SSE2, 2)
106033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
106133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#if defined(HAS_ARGBTORGB24ROW_NEON)
106233cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampRGBANY(ARGBToRGB24Row_Any_NEON, ARGBToRGB24Row_NEON, 3)
106333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampRGBANY(ARGBToRAWRow_Any_NEON, ARGBToRAWRow_NEON, 3)
106433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
106533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef RGBANY
106633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
106733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define YANY(NAMEANY, ARGBTOY_SSE, BPP)                                        \
106833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    void NAMEANY(const uint8* src_argb, uint8* dst_y, int width) {             \
106933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBTOY_SSE(src_argb, dst_y, width - 16);                                \
107033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ARGBTOY_SSE(src_argb + (width - 16) * BPP, dst_y + (width - 16), 16);    \
107133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
107233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
107333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_ARGBTOYROW_SSSE3
107433cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(ARGBToYRow_Any_SSSE3, ARGBToYRow_Unaligned_SSSE3, 4)
107533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(BGRAToYRow_Any_SSSE3, BGRAToYRow_Unaligned_SSSE3, 4)
107633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(ABGRToYRow_Any_SSSE3, ABGRToYRow_Unaligned_SSSE3, 4)
107733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
107833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_RGBATOYROW_SSSE3
107933cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(RGBAToYRow_Any_SSSE3, RGBAToYRow_Unaligned_SSSE3, 4)
108033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
108133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_YUY2TOYROW_SSE2
108233cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(YUY2ToYRow_Any_SSE2, YUY2ToYRow_Unaligned_SSE2, 2)
108333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(UYVYToYRow_Any_SSE2, UYVYToYRow_Unaligned_SSE2, 2)
108433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
108533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_YUY2TOYROW_NEON
108633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(YUY2ToYRow_Any_NEON, YUY2ToYRow_NEON, 2)
108733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampYANY(UYVYToYRow_Any_NEON, UYVYToYRow_NEON, 2)
108833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
108933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef YANY
109033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
109133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define UVANY(NAMEANY, ANYTOUV_SSE, ANYTOUV_C, BPP)                            \
109233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    void NAMEANY(const uint8* src_argb, int src_stride_argb,                   \
109333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 uint8* dst_u, uint8* dst_v, int width) {                      \
109433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int n = width & ~15;                                                     \
109533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ANYTOUV_SSE(src_argb, src_stride_argb, dst_u, dst_v, n);                 \
109633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ANYTOUV_C(src_argb  + n * BPP, src_stride_argb,                          \
109733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 dst_u + (n >> 1),                                             \
109833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 dst_v + (n >> 1),                                             \
109933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 width & 15);                                                  \
110033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
110133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
110233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_ARGBTOUVROW_SSSE3
110333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(ARGBToUVRow_Any_SSSE3, ARGBToUVRow_Unaligned_SSSE3, ARGBToUVRow_C, 4)
110433cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(BGRAToUVRow_Any_SSSE3, BGRAToUVRow_Unaligned_SSSE3, BGRAToUVRow_C, 4)
110533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(ABGRToUVRow_Any_SSSE3, ABGRToUVRow_Unaligned_SSSE3, ABGRToUVRow_C, 4)
110633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
110733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_RGBATOYROW_SSSE3
110833cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(RGBAToUVRow_Any_SSSE3, RGBAToUVRow_Unaligned_SSSE3, RGBAToUVRow_C, 4)
110933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
111033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_YUY2TOUVROW_SSE2
111133cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(YUY2ToUVRow_Any_SSE2, YUY2ToUVRow_Unaligned_SSE2, YUY2ToUVRow_C, 2)
111233cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(UYVYToUVRow_Any_SSE2, UYVYToUVRow_Unaligned_SSE2, UYVYToUVRow_C, 2)
111333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
111433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_YUY2TOUVROW_NEON
111533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(YUY2ToUVRow_Any_NEON, YUY2ToUVRow_NEON, YUY2ToUVRow_C, 2)
111633cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUVANY(UYVYToUVRow_Any_NEON, UYVYToUVRow_NEON, UYVYToUVRow_C, 2)
111733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
111833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef UVANY
111933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
112033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define UV422ANY(NAMEANY, ANYTOUV_SSE, ANYTOUV_C, BPP)                         \
112133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    void NAMEANY(const uint8* src_argb,                                        \
112233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 uint8* dst_u, uint8* dst_v, int width) {                      \
112333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      int n = width & ~15;                                                     \
112433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ANYTOUV_SSE(src_argb, dst_u, dst_v, n);                                  \
112533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp      ANYTOUV_C(src_argb  + n * BPP,                                           \
112633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 dst_u + (n >> 1),                                             \
112733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 dst_v + (n >> 1),                                             \
112833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                 width & 15);                                                  \
112933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    }
113033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
113133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_YUY2TOUV422ROW_SSE2
113233cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUV422ANY(YUY2ToUV422Row_Any_SSE2, YUY2ToUV422Row_Unaligned_SSE2,               \
113333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp         YUY2ToUV422Row_C, 2)
113433cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUV422ANY(UYVYToUV422Row_Any_SSE2, UYVYToUV422Row_Unaligned_SSE2,               \
113533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp         UYVYToUV422Row_C, 2)
113633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
113733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef HAS_YUY2TOUV422ROW_NEON
113833cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUV422ANY(YUY2ToUV422Row_Any_NEON, YUY2ToUV422Row_NEON,                         \
113933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp         YUY2ToUV422Row_C, 2)
114033cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampUV422ANY(UYVYToUV422Row_Any_NEON, UYVYToUV422Row_NEON,                         \
114133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp         UYVYToUV422Row_C, 2)
114233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
114333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef UV422ANY
114433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
114533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ComputeCumulativeSumRow_C(const uint8* row, int32* cumsum,
114633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                               const int32* previous_cumsum, int width) {
114733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int32 row_sum[4] = {0, 0, 0, 0};
114833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int x = 0; x < width; ++x) {
114933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    row_sum[0] += row[x * 4 + 0];
115033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    row_sum[1] += row[x * 4 + 1];
115133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    row_sum[2] += row[x * 4 + 2];
115233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    row_sum[3] += row[x * 4 + 3];
115333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    cumsum[x * 4 + 0] = row_sum[0]  + previous_cumsum[x * 4 + 0];
115433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    cumsum[x * 4 + 1] = row_sum[1]  + previous_cumsum[x * 4 + 1];
115533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    cumsum[x * 4 + 2] = row_sum[2]  + previous_cumsum[x * 4 + 2];
115633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    cumsum[x * 4 + 3] = row_sum[3]  + previous_cumsum[x * 4 + 3];
115733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
115833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
115933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
116033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid CumulativeSumToAverage_C(const int32* tl, const int32* bl,
116133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                              int w, int area, uint8* dst, int count) {
116233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  float ooa = 1.0f / area;
116333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int i = 0; i < count; ++i) {
116433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[0] = static_cast<uint8>((bl[w + 0] + tl[0] - bl[0] - tl[w + 0]) * ooa);
116533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[1] = static_cast<uint8>((bl[w + 1] + tl[1] - bl[1] - tl[w + 1]) * ooa);
116633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[2] = static_cast<uint8>((bl[w + 2] + tl[2] - bl[2] - tl[w + 2]) * ooa);
116733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst[3] = static_cast<uint8>((bl[w + 3] + tl[3] - bl[3] - tl[w + 3]) * ooa);
116833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst += 4;
116933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    tl += 4;
117033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    bl += 4;
117133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
117233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
117333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
117433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define REPEAT8(v) (v) | ((v) << 8)
117533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#define SHADE(f, v) v * f >> 24
117633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
117733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBShadeRow_C(const uint8* src_argb, uint8* dst_argb, int width,
117833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                    uint32 value) {
117933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  const uint32 b_scale = REPEAT8(value & 0xff);
118033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  const uint32 g_scale = REPEAT8((value >> 8) & 0xff);
118133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  const uint32 r_scale = REPEAT8((value >> 16) & 0xff);
118233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  const uint32 a_scale = REPEAT8(value >> 24);
118333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
118433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int i = 0; i < width; ++i) {
118533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 b = REPEAT8(src_argb[0]);
118633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 g = REPEAT8(src_argb[1]);
118733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 r = REPEAT8(src_argb[2]);
118833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    const uint32 a = REPEAT8(src_argb[3]);
118933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[0] = SHADE(b, b_scale);
119033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[1] = SHADE(g, g_scale);
119133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[2] = SHADE(r, r_scale);
119233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb[3] = SHADE(a, a_scale);
119333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_argb += 4;
119433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
119533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
119633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
119733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef REPEAT8
119833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#undef SHADE
119933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
120033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// Copy pixels from rotated source to destination row with a slope.
120133cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampLIBYUV_API
120233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBAffineRow_C(const uint8* src_argb, int src_argb_stride,
120333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                     uint8* dst_argb, const float* uv_dudv, int width) {
120433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  // Render a row of pixels from source into a buffer.
120533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  float uv[2];
120633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  uv[0] = uv_dudv[0];
120733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  uv[1] = uv_dudv[1];
120833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  for (int i = 0; i < width; ++i) {
120933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int x = static_cast<int>(uv[0]);
121033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    int y = static_cast<int>(uv[1]);
121133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    *reinterpret_cast<uint32*>(dst_argb) =
121233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp        *reinterpret_cast<const uint32*>(src_argb + y * src_argb_stride +
121333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                                         x * 4);
121433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_argb += 4;
121533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uv[0] += uv_dudv[2];
121633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    uv[1] += uv_dudv[3];
121733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  }
121833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
121933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
122033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp// C version 2x2 -> 2x1.
122133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampvoid ARGBInterpolateRow_C(uint8* dst_ptr, const uint8* src_ptr,
122233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          ptrdiff_t src_stride,
122333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp                          int dst_width, int source_y_fraction) {
122433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int y1_fraction = source_y_fraction;
122533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  int y0_fraction = 256 - y1_fraction;
122633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  const uint8* src_ptr1 = src_ptr + src_stride;
122733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  uint8* end = dst_ptr + (dst_width << 2);
122833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  do {
122933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8;
123033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[1] = (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction) >> 8;
123133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[2] = (src_ptr[2] * y0_fraction + src_ptr1[2] * y1_fraction) >> 8;
123233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[3] = (src_ptr[3] * y0_fraction + src_ptr1[3] * y1_fraction) >> 8;
123333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[4] = (src_ptr[4] * y0_fraction + src_ptr1[4] * y1_fraction) >> 8;
123433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[5] = (src_ptr[5] * y0_fraction + src_ptr1[5] * y1_fraction) >> 8;
123533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[6] = (src_ptr[6] * y0_fraction + src_ptr1[6] * y1_fraction) >> 8;
123633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr[7] = (src_ptr[7] * y0_fraction + src_ptr1[7] * y1_fraction) >> 8;
123733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_ptr += 8;
123833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    src_ptr1 += 8;
123933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp    dst_ptr += 8;
124033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp  } while (dst_ptr < end);
124133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}
124233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp
124333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#ifdef __cplusplus
124433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}  // extern "C"
124533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp}  // namespace libyuv
124633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#endif
1247