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