1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "media/base/simd/convert_rgb_to_yuv.h"
6
7namespace media {
8
9static int clip_byte(int x) {
10  if (x > 255)
11    return 255;
12  else if (x < 0)
13    return 0;
14  else
15    return x;
16}
17
18void ConvertRGB32ToYUV_C(const uint8* rgbframe,
19                         uint8* yplane,
20                         uint8* uplane,
21                         uint8* vplane,
22                         int width,
23                         int height,
24                         int rgbstride,
25                         int ystride,
26                         int uvstride) {
27#if defined(OS_ANDROID)
28  const int r = 0;
29  const int g = 1;
30  const int b = 2;
31#else
32  const int r = 2;
33  const int g = 1;
34  const int b = 0;
35#endif
36
37  for (int i = 0; i < height; ++i) {
38    for (int j = 0; j < width; ++j) {
39      // Since the input pixel format is RGB32, there are 4 bytes per pixel.
40      const uint8* pixel = rgbframe + 4 * j;
41      yplane[j] = clip_byte(((pixel[r] * 66 + pixel[g] * 129 +
42                             pixel[b] * 25 + 128) >> 8) + 16);
43      if (i % 2 == 0 && j % 2 == 0) {
44        uplane[j / 2] = clip_byte(((pixel[r] * -38 + pixel[g] * -74 +
45                                   pixel[b] * 112 + 128) >> 8) + 128);
46        vplane[j / 2] = clip_byte(((pixel[r] * 112 + pixel[g] * -94 +
47                                    pixel[b] * -18 + 128) >> 8) + 128);
48      }
49    }
50    rgbframe += rgbstride;
51    yplane += ystride;
52    if (i % 2 == 0) {
53      uplane += uvstride;
54      vplane += uvstride;
55    }
56  }
57}
58
59void ConvertRGB24ToYUV_C(const uint8* rgbframe,
60                         uint8* yplane,
61                         uint8* uplane,
62                         uint8* vplane,
63                         int width,
64                         int height,
65                         int rgbstride,
66                         int ystride,
67                         int uvstride) {
68  for (int i = 0; i < height; ++i) {
69    for (int j = 0; j < width; ++j) {
70      // Since the input pixel format is RGB24, there are 3 bytes per pixel.
71      const uint8* pixel = rgbframe + 3 * j;
72      yplane[j] = clip_byte(((pixel[2] * 66 + pixel[1] * 129 +
73                              pixel[0] * 25 + 128) >> 8) + 16);
74      if (i % 2 == 0 && j % 2 == 0) {
75        uplane[j / 2] = clip_byte(((pixel[2] * -38 + pixel[1] * -74 +
76                                    pixel[0] * 112 + 128) >> 8) + 128);
77        vplane[j / 2] = clip_byte(((pixel[2] * 112 + pixel[1] * -94 +
78                                    pixel[0] * -18 + 128) >> 8) + 128);
79      }
80    }
81
82    rgbframe += rgbstride;
83    yplane += ystride;
84    if (i % 2 == 0) {
85      uplane += uvstride;
86      vplane += uvstride;
87    }
88  }
89}
90
91}  // namespace media
92