media/libyuv/source/format_conversion.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright 2011 The LibYuv Project Authors. All rights reserved.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license
michael@0 5 * that can be found in the LICENSE file in the root of the source
michael@0 6 * tree. An additional intellectual property rights grant can be found
michael@0 7 * in the file PATENTS. All contributing project authors may
michael@0 8 * be found in the AUTHORS file in the root of the source tree.
michael@0 9 */
michael@0 10
michael@0 11 #include "libyuv/format_conversion.h"
michael@0 12
michael@0 13 #include "libyuv/basic_types.h"
michael@0 14 #include "libyuv/cpu_id.h"
michael@0 15 #include "libyuv/video_common.h"
michael@0 16 #include "libyuv/row.h"
michael@0 17
michael@0 18 #ifdef __cplusplus
michael@0 19 namespace libyuv {
michael@0 20 extern "C" {
michael@0 21 #endif
michael@0 22
michael@0 23 // generate a selector mask useful for pshufb
michael@0 24 static uint32 GenerateSelector(int select0, int select1) {
michael@0 25 return (uint32)(select0) |
michael@0 26 (uint32)((select1 + 4) << 8) |
michael@0 27 (uint32)((select0 + 8) << 16) |
michael@0 28 (uint32)((select1 + 12) << 24);
michael@0 29 }
michael@0 30
michael@0 31 static int MakeSelectors(const int blue_index,
michael@0 32 const int green_index,
michael@0 33 const int red_index,
michael@0 34 uint32 dst_fourcc_bayer,
michael@0 35 uint32* index_map) {
michael@0 36 // Now build a lookup table containing the indices for the four pixels in each
michael@0 37 // 2x2 Bayer grid.
michael@0 38 switch (dst_fourcc_bayer) {
michael@0 39 case FOURCC_BGGR:
michael@0 40 index_map[0] = GenerateSelector(blue_index, green_index);
michael@0 41 index_map[1] = GenerateSelector(green_index, red_index);
michael@0 42 break;
michael@0 43 case FOURCC_GBRG:
michael@0 44 index_map[0] = GenerateSelector(green_index, blue_index);
michael@0 45 index_map[1] = GenerateSelector(red_index, green_index);
michael@0 46 break;
michael@0 47 case FOURCC_RGGB:
michael@0 48 index_map[0] = GenerateSelector(red_index, green_index);
michael@0 49 index_map[1] = GenerateSelector(green_index, blue_index);
michael@0 50 break;
michael@0 51 case FOURCC_GRBG:
michael@0 52 index_map[0] = GenerateSelector(green_index, red_index);
michael@0 53 index_map[1] = GenerateSelector(blue_index, green_index);
michael@0 54 break;
michael@0 55 default:
michael@0 56 return -1; // Bad FourCC
michael@0 57 }
michael@0 58 return 0;
michael@0 59 }
michael@0 60
michael@0 61 // Converts 32 bit ARGB to Bayer RGB formats.
michael@0 62 LIBYUV_API
michael@0 63 int ARGBToBayer(const uint8* src_argb, int src_stride_argb,
michael@0 64 uint8* dst_bayer, int dst_stride_bayer,
michael@0 65 int width, int height,
michael@0 66 uint32 dst_fourcc_bayer) {
michael@0 67 if (height < 0) {
michael@0 68 height = -height;
michael@0 69 src_argb = src_argb + (height - 1) * src_stride_argb;
michael@0 70 src_stride_argb = -src_stride_argb;
michael@0 71 }
michael@0 72 void (*ARGBToBayerRow)(const uint8* src_argb, uint8* dst_bayer,
michael@0 73 uint32 selector, int pix) = ARGBToBayerRow_C;
michael@0 74 #if defined(HAS_ARGBTOBAYERROW_SSSE3)
michael@0 75 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8 &&
michael@0 76 IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
michael@0 77 ARGBToBayerRow = ARGBToBayerRow_Any_SSSE3;
michael@0 78 if (IS_ALIGNED(width, 8)) {
michael@0 79 ARGBToBayerRow = ARGBToBayerRow_SSSE3;
michael@0 80 }
michael@0 81 }
michael@0 82 #elif defined(HAS_ARGBTOBAYERROW_NEON)
michael@0 83 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 84 ARGBToBayerRow = ARGBToBayerRow_Any_NEON;
michael@0 85 if (IS_ALIGNED(width, 8)) {
michael@0 86 ARGBToBayerRow = ARGBToBayerRow_NEON;
michael@0 87 }
michael@0 88 }
michael@0 89 #endif
michael@0 90 const int blue_index = 0; // Offsets for ARGB format
michael@0 91 const int green_index = 1;
michael@0 92 const int red_index = 2;
michael@0 93 uint32 index_map[2];
michael@0 94 if (MakeSelectors(blue_index, green_index, red_index,
michael@0 95 dst_fourcc_bayer, index_map)) {
michael@0 96 return -1; // Bad FourCC
michael@0 97 }
michael@0 98
michael@0 99 for (int y = 0; y < height; ++y) {
michael@0 100 ARGBToBayerRow(src_argb, dst_bayer, index_map[y & 1], width);
michael@0 101 src_argb += src_stride_argb;
michael@0 102 dst_bayer += dst_stride_bayer;
michael@0 103 }
michael@0 104 return 0;
michael@0 105 }
michael@0 106
michael@0 107 #define AVG(a, b) (((a) + (b)) >> 1)
michael@0 108
michael@0 109 static void BayerRowBG(const uint8* src_bayer0, int src_stride_bayer,
michael@0 110 uint8* dst_argb, int pix) {
michael@0 111 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
michael@0 112 uint8 g = src_bayer0[1];
michael@0 113 uint8 r = src_bayer1[1];
michael@0 114 for (int x = 0; x < pix - 2; x += 2) {
michael@0 115 dst_argb[0] = src_bayer0[0];
michael@0 116 dst_argb[1] = AVG(g, src_bayer0[1]);
michael@0 117 dst_argb[2] = AVG(r, src_bayer1[1]);
michael@0 118 dst_argb[3] = 255U;
michael@0 119 dst_argb[4] = AVG(src_bayer0[0], src_bayer0[2]);
michael@0 120 dst_argb[5] = src_bayer0[1];
michael@0 121 dst_argb[6] = src_bayer1[1];
michael@0 122 dst_argb[7] = 255U;
michael@0 123 g = src_bayer0[1];
michael@0 124 r = src_bayer1[1];
michael@0 125 src_bayer0 += 2;
michael@0 126 src_bayer1 += 2;
michael@0 127 dst_argb += 8;
michael@0 128 }
michael@0 129 dst_argb[0] = src_bayer0[0];
michael@0 130 dst_argb[1] = AVG(g, src_bayer0[1]);
michael@0 131 dst_argb[2] = AVG(r, src_bayer1[1]);
michael@0 132 dst_argb[3] = 255U;
michael@0 133 if (!(pix & 1)) {
michael@0 134 dst_argb[4] = src_bayer0[0];
michael@0 135 dst_argb[5] = src_bayer0[1];
michael@0 136 dst_argb[6] = src_bayer1[1];
michael@0 137 dst_argb[7] = 255U;
michael@0 138 }
michael@0 139 }
michael@0 140
michael@0 141 static void BayerRowRG(const uint8* src_bayer0, int src_stride_bayer,
michael@0 142 uint8* dst_argb, int pix) {
michael@0 143 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
michael@0 144 uint8 g = src_bayer0[1];
michael@0 145 uint8 b = src_bayer1[1];
michael@0 146 for (int x = 0; x < pix - 2; x += 2) {
michael@0 147 dst_argb[0] = AVG(b, src_bayer1[1]);
michael@0 148 dst_argb[1] = AVG(g, src_bayer0[1]);
michael@0 149 dst_argb[2] = src_bayer0[0];
michael@0 150 dst_argb[3] = 255U;
michael@0 151 dst_argb[4] = src_bayer1[1];
michael@0 152 dst_argb[5] = src_bayer0[1];
michael@0 153 dst_argb[6] = AVG(src_bayer0[0], src_bayer0[2]);
michael@0 154 dst_argb[7] = 255U;
michael@0 155 g = src_bayer0[1];
michael@0 156 b = src_bayer1[1];
michael@0 157 src_bayer0 += 2;
michael@0 158 src_bayer1 += 2;
michael@0 159 dst_argb += 8;
michael@0 160 }
michael@0 161 dst_argb[0] = AVG(b, src_bayer1[1]);
michael@0 162 dst_argb[1] = AVG(g, src_bayer0[1]);
michael@0 163 dst_argb[2] = src_bayer0[0];
michael@0 164 dst_argb[3] = 255U;
michael@0 165 if (!(pix & 1)) {
michael@0 166 dst_argb[4] = src_bayer1[1];
michael@0 167 dst_argb[5] = src_bayer0[1];
michael@0 168 dst_argb[6] = src_bayer0[0];
michael@0 169 dst_argb[7] = 255U;
michael@0 170 }
michael@0 171 }
michael@0 172
michael@0 173 static void BayerRowGB(const uint8* src_bayer0, int src_stride_bayer,
michael@0 174 uint8* dst_argb, int pix) {
michael@0 175 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
michael@0 176 uint8 b = src_bayer0[1];
michael@0 177 for (int x = 0; x < pix - 2; x += 2) {
michael@0 178 dst_argb[0] = AVG(b, src_bayer0[1]);
michael@0 179 dst_argb[1] = src_bayer0[0];
michael@0 180 dst_argb[2] = src_bayer1[0];
michael@0 181 dst_argb[3] = 255U;
michael@0 182 dst_argb[4] = src_bayer0[1];
michael@0 183 dst_argb[5] = AVG(src_bayer0[0], src_bayer0[2]);
michael@0 184 dst_argb[6] = AVG(src_bayer1[0], src_bayer1[2]);
michael@0 185 dst_argb[7] = 255U;
michael@0 186 b = src_bayer0[1];
michael@0 187 src_bayer0 += 2;
michael@0 188 src_bayer1 += 2;
michael@0 189 dst_argb += 8;
michael@0 190 }
michael@0 191 dst_argb[0] = AVG(b, src_bayer0[1]);
michael@0 192 dst_argb[1] = src_bayer0[0];
michael@0 193 dst_argb[2] = src_bayer1[0];
michael@0 194 dst_argb[3] = 255U;
michael@0 195 if (!(pix & 1)) {
michael@0 196 dst_argb[4] = src_bayer0[1];
michael@0 197 dst_argb[5] = src_bayer0[0];
michael@0 198 dst_argb[6] = src_bayer1[0];
michael@0 199 dst_argb[7] = 255U;
michael@0 200 }
michael@0 201 }
michael@0 202
michael@0 203 static void BayerRowGR(const uint8* src_bayer0, int src_stride_bayer,
michael@0 204 uint8* dst_argb, int pix) {
michael@0 205 const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
michael@0 206 uint8 r = src_bayer0[1];
michael@0 207 for (int x = 0; x < pix - 2; x += 2) {
michael@0 208 dst_argb[0] = src_bayer1[0];
michael@0 209 dst_argb[1] = src_bayer0[0];
michael@0 210 dst_argb[2] = AVG(r, src_bayer0[1]);
michael@0 211 dst_argb[3] = 255U;
michael@0 212 dst_argb[4] = AVG(src_bayer1[0], src_bayer1[2]);
michael@0 213 dst_argb[5] = AVG(src_bayer0[0], src_bayer0[2]);
michael@0 214 dst_argb[6] = src_bayer0[1];
michael@0 215 dst_argb[7] = 255U;
michael@0 216 r = src_bayer0[1];
michael@0 217 src_bayer0 += 2;
michael@0 218 src_bayer1 += 2;
michael@0 219 dst_argb += 8;
michael@0 220 }
michael@0 221 dst_argb[0] = src_bayer1[0];
michael@0 222 dst_argb[1] = src_bayer0[0];
michael@0 223 dst_argb[2] = AVG(r, src_bayer0[1]);
michael@0 224 dst_argb[3] = 255U;
michael@0 225 if (!(pix & 1)) {
michael@0 226 dst_argb[4] = src_bayer1[0];
michael@0 227 dst_argb[5] = src_bayer0[0];
michael@0 228 dst_argb[6] = src_bayer0[1];
michael@0 229 dst_argb[7] = 255U;
michael@0 230 }
michael@0 231 }
michael@0 232
michael@0 233 // Converts any Bayer RGB format to ARGB.
michael@0 234 LIBYUV_API
michael@0 235 int BayerToARGB(const uint8* src_bayer, int src_stride_bayer,
michael@0 236 uint8* dst_argb, int dst_stride_argb,
michael@0 237 int width, int height,
michael@0 238 uint32 src_fourcc_bayer) {
michael@0 239 if (height < 0) {
michael@0 240 height = -height;
michael@0 241 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 242 dst_stride_argb = -dst_stride_argb;
michael@0 243 }
michael@0 244 void (*BayerRow0)(const uint8* src_bayer, int src_stride_bayer,
michael@0 245 uint8* dst_argb, int pix);
michael@0 246 void (*BayerRow1)(const uint8* src_bayer, int src_stride_bayer,
michael@0 247 uint8* dst_argb, int pix);
michael@0 248 switch (src_fourcc_bayer) {
michael@0 249 case FOURCC_BGGR:
michael@0 250 BayerRow0 = BayerRowBG;
michael@0 251 BayerRow1 = BayerRowGR;
michael@0 252 break;
michael@0 253 case FOURCC_GBRG:
michael@0 254 BayerRow0 = BayerRowGB;
michael@0 255 BayerRow1 = BayerRowRG;
michael@0 256 break;
michael@0 257 case FOURCC_GRBG:
michael@0 258 BayerRow0 = BayerRowGR;
michael@0 259 BayerRow1 = BayerRowBG;
michael@0 260 break;
michael@0 261 case FOURCC_RGGB:
michael@0 262 BayerRow0 = BayerRowRG;
michael@0 263 BayerRow1 = BayerRowGB;
michael@0 264 break;
michael@0 265 default:
michael@0 266 return -1; // Bad FourCC
michael@0 267 }
michael@0 268
michael@0 269 for (int y = 0; y < height - 1; y += 2) {
michael@0 270 BayerRow0(src_bayer, src_stride_bayer, dst_argb, width);
michael@0 271 BayerRow1(src_bayer + src_stride_bayer, -src_stride_bayer,
michael@0 272 dst_argb + dst_stride_argb, width);
michael@0 273 src_bayer += src_stride_bayer * 2;
michael@0 274 dst_argb += dst_stride_argb * 2;
michael@0 275 }
michael@0 276 if (height & 1) {
michael@0 277 BayerRow0(src_bayer, src_stride_bayer, dst_argb, width);
michael@0 278 }
michael@0 279 return 0;
michael@0 280 }
michael@0 281
michael@0 282 // Converts any Bayer RGB format to ARGB.
michael@0 283 LIBYUV_API
michael@0 284 int BayerToI420(const uint8* src_bayer, int src_stride_bayer,
michael@0 285 uint8* dst_y, int dst_stride_y,
michael@0 286 uint8* dst_u, int dst_stride_u,
michael@0 287 uint8* dst_v, int dst_stride_v,
michael@0 288 int width, int height,
michael@0 289 uint32 src_fourcc_bayer) {
michael@0 290 // Negative height means invert the image.
michael@0 291 if (height < 0) {
michael@0 292 height = -height;
michael@0 293 int halfheight = (height + 1) >> 1;
michael@0 294 dst_y = dst_y + (height - 1) * dst_stride_y;
michael@0 295 dst_u = dst_u + (halfheight - 1) * dst_stride_u;
michael@0 296 dst_v = dst_v + (halfheight - 1) * dst_stride_v;
michael@0 297 dst_stride_y = -dst_stride_y;
michael@0 298 dst_stride_u = -dst_stride_u;
michael@0 299 dst_stride_v = -dst_stride_v;
michael@0 300 }
michael@0 301 void (*BayerRow0)(const uint8* src_bayer, int src_stride_bayer,
michael@0 302 uint8* dst_argb, int pix);
michael@0 303 void (*BayerRow1)(const uint8* src_bayer, int src_stride_bayer,
michael@0 304 uint8* dst_argb, int pix);
michael@0 305
michael@0 306 void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
michael@0 307 uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C;
michael@0 308 void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) =
michael@0 309 ARGBToYRow_C;
michael@0 310 #if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3)
michael@0 311 if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) {
michael@0 312 ARGBToUVRow = ARGBToUVRow_Any_SSSE3;
michael@0 313 ARGBToYRow = ARGBToYRow_Any_SSSE3;
michael@0 314 if (IS_ALIGNED(width, 16)) {
michael@0 315 ARGBToYRow = ARGBToYRow_Unaligned_SSSE3;
michael@0 316 ARGBToUVRow = ARGBToUVRow_SSSE3;
michael@0 317 if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) {
michael@0 318 ARGBToYRow = ARGBToYRow_SSSE3;
michael@0 319 }
michael@0 320 }
michael@0 321 }
michael@0 322 #elif defined(HAS_ARGBTOYROW_NEON)
michael@0 323 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 324 ARGBToYRow = ARGBToYRow_Any_NEON;
michael@0 325 if (IS_ALIGNED(width, 8)) {
michael@0 326 ARGBToYRow = ARGBToYRow_NEON;
michael@0 327 }
michael@0 328 if (width >= 16) {
michael@0 329 ARGBToUVRow = ARGBToUVRow_Any_NEON;
michael@0 330 if (IS_ALIGNED(width, 16)) {
michael@0 331 ARGBToUVRow = ARGBToUVRow_NEON;
michael@0 332 }
michael@0 333 }
michael@0 334 }
michael@0 335 #endif
michael@0 336
michael@0 337 switch (src_fourcc_bayer) {
michael@0 338 case FOURCC_BGGR:
michael@0 339 BayerRow0 = BayerRowBG;
michael@0 340 BayerRow1 = BayerRowGR;
michael@0 341 break;
michael@0 342 case FOURCC_GBRG:
michael@0 343 BayerRow0 = BayerRowGB;
michael@0 344 BayerRow1 = BayerRowRG;
michael@0 345 break;
michael@0 346 case FOURCC_GRBG:
michael@0 347 BayerRow0 = BayerRowGR;
michael@0 348 BayerRow1 = BayerRowBG;
michael@0 349 break;
michael@0 350 case FOURCC_RGGB:
michael@0 351 BayerRow0 = BayerRowRG;
michael@0 352 BayerRow1 = BayerRowGB;
michael@0 353 break;
michael@0 354 default:
michael@0 355 return -1; // Bad FourCC
michael@0 356 }
michael@0 357
michael@0 358 // Allocate 2 rows of ARGB.
michael@0 359 const int kRowSize = (width * 4 + 15) & ~15;
michael@0 360 align_buffer_64(row, kRowSize * 2);
michael@0 361 for (int y = 0; y < height - 1; y += 2) {
michael@0 362 BayerRow0(src_bayer, src_stride_bayer, row, width);
michael@0 363 BayerRow1(src_bayer + src_stride_bayer, -src_stride_bayer,
michael@0 364 row + kRowSize, width);
michael@0 365 ARGBToUVRow(row, kRowSize, dst_u, dst_v, width);
michael@0 366 ARGBToYRow(row, dst_y, width);
michael@0 367 ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width);
michael@0 368 src_bayer += src_stride_bayer * 2;
michael@0 369 dst_y += dst_stride_y * 2;
michael@0 370 dst_u += dst_stride_u;
michael@0 371 dst_v += dst_stride_v;
michael@0 372 }
michael@0 373 if (height & 1) {
michael@0 374 BayerRow0(src_bayer, src_stride_bayer, row, width);
michael@0 375 ARGBToUVRow(row, 0, dst_u, dst_v, width);
michael@0 376 ARGBToYRow(row, dst_y, width);
michael@0 377 }
michael@0 378 free_aligned_buffer_64(row);
michael@0 379 return 0;
michael@0 380 }
michael@0 381
michael@0 382 // Convert I420 to Bayer.
michael@0 383 LIBYUV_API
michael@0 384 int I420ToBayer(const uint8* src_y, int src_stride_y,
michael@0 385 const uint8* src_u, int src_stride_u,
michael@0 386 const uint8* src_v, int src_stride_v,
michael@0 387 uint8* dst_bayer, int dst_stride_bayer,
michael@0 388 int width, int height,
michael@0 389 uint32 dst_fourcc_bayer) {
michael@0 390 // Negative height means invert the image.
michael@0 391 if (height < 0) {
michael@0 392 height = -height;
michael@0 393 int halfheight = (height + 1) >> 1;
michael@0 394 src_y = src_y + (height - 1) * src_stride_y;
michael@0 395 src_u = src_u + (halfheight - 1) * src_stride_u;
michael@0 396 src_v = src_v + (halfheight - 1) * src_stride_v;
michael@0 397 src_stride_y = -src_stride_y;
michael@0 398 src_stride_u = -src_stride_u;
michael@0 399 src_stride_v = -src_stride_v;
michael@0 400 }
michael@0 401 void (*I422ToARGBRow)(const uint8* y_buf,
michael@0 402 const uint8* u_buf,
michael@0 403 const uint8* v_buf,
michael@0 404 uint8* rgb_buf,
michael@0 405 int width) = I422ToARGBRow_C;
michael@0 406 #if defined(HAS_I422TOARGBROW_SSSE3)
michael@0 407 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 408 I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
michael@0 409 if (IS_ALIGNED(width, 8)) {
michael@0 410 I422ToARGBRow = I422ToARGBRow_SSSE3;
michael@0 411 }
michael@0 412 }
michael@0 413 #endif
michael@0 414 #if defined(HAS_I422TOARGBROW_AVX2)
michael@0 415 if (TestCpuFlag(kCpuHasAVX2) && width >= 16) {
michael@0 416 I422ToARGBRow = I422ToARGBRow_Any_AVX2;
michael@0 417 if (IS_ALIGNED(width, 16)) {
michael@0 418 I422ToARGBRow = I422ToARGBRow_AVX2;
michael@0 419 }
michael@0 420 }
michael@0 421 #endif
michael@0 422 #if defined(HAS_I422TOARGBROW_NEON)
michael@0 423 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 424 I422ToARGBRow = I422ToARGBRow_Any_NEON;
michael@0 425 if (IS_ALIGNED(width, 8)) {
michael@0 426 I422ToARGBRow = I422ToARGBRow_NEON;
michael@0 427 }
michael@0 428 }
michael@0 429 #endif
michael@0 430 #if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
michael@0 431 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
michael@0 432 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
michael@0 433 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
michael@0 434 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2)) {
michael@0 435 I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
michael@0 436 }
michael@0 437 #endif
michael@0 438
michael@0 439 void (*ARGBToBayerRow)(const uint8* src_argb, uint8* dst_bayer,
michael@0 440 uint32 selector, int pix) = ARGBToBayerRow_C;
michael@0 441 #if defined(HAS_ARGBTOBAYERROW_SSSE3)
michael@0 442 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 443 ARGBToBayerRow = ARGBToBayerRow_Any_SSSE3;
michael@0 444 if (IS_ALIGNED(width, 8)) {
michael@0 445 ARGBToBayerRow = ARGBToBayerRow_SSSE3;
michael@0 446 }
michael@0 447 }
michael@0 448 #elif defined(HAS_ARGBTOBAYERROW_NEON)
michael@0 449 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 450 ARGBToBayerRow = ARGBToBayerRow_Any_NEON;
michael@0 451 if (IS_ALIGNED(width, 8)) {
michael@0 452 ARGBToBayerRow = ARGBToBayerRow_NEON;
michael@0 453 }
michael@0 454 }
michael@0 455 #endif
michael@0 456
michael@0 457 const int blue_index = 0; // Offsets for ARGB format
michael@0 458 const int green_index = 1;
michael@0 459 const int red_index = 2;
michael@0 460 uint32 index_map[2];
michael@0 461 if (MakeSelectors(blue_index, green_index, red_index,
michael@0 462 dst_fourcc_bayer, index_map)) {
michael@0 463 return -1; // Bad FourCC
michael@0 464 }
michael@0 465 // Allocate a row of ARGB.
michael@0 466 align_buffer_64(row, width * 4);
michael@0 467 for (int y = 0; y < height; ++y) {
michael@0 468 I422ToARGBRow(src_y, src_u, src_v, row, width);
michael@0 469 ARGBToBayerRow(row, dst_bayer, index_map[y & 1], width);
michael@0 470 dst_bayer += dst_stride_bayer;
michael@0 471 src_y += src_stride_y;
michael@0 472 if (y & 1) {
michael@0 473 src_u += src_stride_u;
michael@0 474 src_v += src_stride_v;
michael@0 475 }
michael@0 476 }
michael@0 477 free_aligned_buffer_64(row);
michael@0 478 return 0;
michael@0 479 }
michael@0 480
michael@0 481 #define MAKEBAYERFOURCC(BAYER) \
michael@0 482 LIBYUV_API \
michael@0 483 int Bayer##BAYER##ToI420(const uint8* src_bayer, int src_stride_bayer, \
michael@0 484 uint8* dst_y, int dst_stride_y, \
michael@0 485 uint8* dst_u, int dst_stride_u, \
michael@0 486 uint8* dst_v, int dst_stride_v, \
michael@0 487 int width, int height) { \
michael@0 488 return BayerToI420(src_bayer, src_stride_bayer, \
michael@0 489 dst_y, dst_stride_y, \
michael@0 490 dst_u, dst_stride_u, \
michael@0 491 dst_v, dst_stride_v, \
michael@0 492 width, height, \
michael@0 493 FOURCC_##BAYER); \
michael@0 494 } \
michael@0 495 \
michael@0 496 LIBYUV_API \
michael@0 497 int I420ToBayer##BAYER(const uint8* src_y, int src_stride_y, \
michael@0 498 const uint8* src_u, int src_stride_u, \
michael@0 499 const uint8* src_v, int src_stride_v, \
michael@0 500 uint8* dst_bayer, int dst_stride_bayer, \
michael@0 501 int width, int height) { \
michael@0 502 return I420ToBayer(src_y, src_stride_y, \
michael@0 503 src_u, src_stride_u, \
michael@0 504 src_v, src_stride_v, \
michael@0 505 dst_bayer, dst_stride_bayer, \
michael@0 506 width, height, \
michael@0 507 FOURCC_##BAYER); \
michael@0 508 } \
michael@0 509 \
michael@0 510 LIBYUV_API \
michael@0 511 int ARGBToBayer##BAYER(const uint8* src_argb, int src_stride_argb, \
michael@0 512 uint8* dst_bayer, int dst_stride_bayer, \
michael@0 513 int width, int height) { \
michael@0 514 return ARGBToBayer(src_argb, src_stride_argb, \
michael@0 515 dst_bayer, dst_stride_bayer, \
michael@0 516 width, height, \
michael@0 517 FOURCC_##BAYER); \
michael@0 518 } \
michael@0 519 \
michael@0 520 LIBYUV_API \
michael@0 521 int Bayer##BAYER##ToARGB(const uint8* src_bayer, int src_stride_bayer, \
michael@0 522 uint8* dst_argb, int dst_stride_argb, \
michael@0 523 int width, int height) { \
michael@0 524 return BayerToARGB(src_bayer, src_stride_bayer, \
michael@0 525 dst_argb, dst_stride_argb, \
michael@0 526 width, height, \
michael@0 527 FOURCC_##BAYER); \
michael@0 528 }
michael@0 529
michael@0 530 MAKEBAYERFOURCC(BGGR)
michael@0 531 MAKEBAYERFOURCC(GBRG)
michael@0 532 MAKEBAYERFOURCC(GRBG)
michael@0 533 MAKEBAYERFOURCC(RGGB)
michael@0 534
michael@0 535 #ifdef __cplusplus
michael@0 536 } // extern "C"
michael@0 537 } // namespace libyuv
michael@0 538 #endif

mercurial