mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-08 01:36:47 +08:00
Make Bayer functions with same parameters as RGB conversions allowing consistant usage and testing. Functions are implemented with wrappers to single function for 4 fourccs. New I420ToBayer functions implemented similar to 2 step I420ToRGB565 etc.
BUG=none TEST=none Review URL: https://webrtc-codereview.appspot.com/367002 git-svn-id: http://libyuv.googlecode.com/svn/trunk@150 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
9460279178
commit
5343a7301b
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 149
|
||||
Version: 150
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -18,25 +18,127 @@ namespace libyuv {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Converts any Bayer RGB format to I420.
|
||||
int BayerRGBToI420(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint32 src_fourcc_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);
|
||||
// Convert Bayer RGB formats to I420.
|
||||
int BayerBGGRToI420(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);
|
||||
|
||||
// Converts any Bayer RGB format to ARGB.
|
||||
int BayerRGBToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint32 src_fourcc_bayer,
|
||||
uint8* dst_rgb, int dst_stride_rgb,
|
||||
int width, int height);
|
||||
int BayerGBRGToI420(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);
|
||||
|
||||
// Converts ARGB to any Bayer RGB format.
|
||||
int ARGBToBayerRGB(const uint8* src_rgb, int src_stride_rgb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
uint32 dst_fourcc_bayer,
|
||||
int width, int height);
|
||||
int BayerGRBGToI420(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);
|
||||
|
||||
int BayerRGGBToI420(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);
|
||||
|
||||
// Temporary API mapper
|
||||
#define BayerRGBToI420(b,bs,f,y,ys,u,us,v,vs,w,h) \
|
||||
BayerToI420(b,bs,y,ys,u,us,v,vs,w,h,f)
|
||||
|
||||
int 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);
|
||||
|
||||
// Convert I420 to Bayer RGB formats.
|
||||
int I420ToBayerBGGR(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_frame, int dst_stride_frame,
|
||||
int width, int height);
|
||||
|
||||
int I420ToBayerGBRG(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_frame, int dst_stride_frame,
|
||||
int width, int height);
|
||||
|
||||
int I420ToBayerGRBG(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_frame, int dst_stride_frame,
|
||||
int width, int height);
|
||||
|
||||
int I420ToBayerRGGB(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_frame, int dst_stride_frame,
|
||||
int width, int height);
|
||||
|
||||
// Temporary API mapper
|
||||
#define I420ToBayerRGB(y,ys,u,us,v,vs,b,bs,f,w,h) \
|
||||
I420ToBayer(y,ys,u,us,v,vs,b,bs,w,h,f)
|
||||
|
||||
int 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_frame, int dst_stride_frame,
|
||||
int width, int height,
|
||||
uint32 dst_fourcc_bayer);
|
||||
|
||||
// Convert Bayer RGB formats to ARGB.
|
||||
int BayerBGGRToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height);
|
||||
|
||||
int BayerGBRGToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height);
|
||||
|
||||
int BayerGRBGToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height);
|
||||
|
||||
int BayerRGGBToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height);
|
||||
|
||||
// Temporary API mapper
|
||||
#define BayerRGBToARGB(b,bs,f,a,as,w,h) BayerToARGB(b,bs,a,as,w,h,f)
|
||||
|
||||
int BayerToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height,
|
||||
uint32 src_fourcc_bayer);
|
||||
|
||||
// Converts ARGB to Bayer RGB formats.
|
||||
int ARGBToBayerBGGR(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
int width, int height);
|
||||
|
||||
int ARGBToBayerGBRG(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
int width, int height);
|
||||
|
||||
int ARGBToBayerGRBG(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
int width, int height);
|
||||
|
||||
int ARGBToBayerRGGB(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
int width, int height);
|
||||
|
||||
// Temporary API mapper
|
||||
#define ARGBToBayerRGB(a,as,b,bs,f,w,h) ARGBToBayer(b,bs,a,as,w,h,f)
|
||||
|
||||
int ARGBToBayer(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
int width, int height,
|
||||
uint32 dst_fourcc_bayer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@ -930,16 +930,44 @@ int ConvertToI420(const uint8* sample, size_t sample_size,
|
||||
v, v_stride,
|
||||
dst_width, inv_dst_height);
|
||||
break;
|
||||
// TODO(fbarchard): Support cropping Bayer by odd numbers
|
||||
// by adjusting fourcc.
|
||||
case FOURCC_BGGR:
|
||||
case FOURCC_RGGB:
|
||||
case FOURCC_GRBG:
|
||||
case FOURCC_GBRG:
|
||||
// TODO(fbarchard): Support cropping by odd numbers by adjusting fourcc.
|
||||
src = sample + (src_width * crop_y + crop_x);
|
||||
BayerRGBToI420(src, src_width, format,
|
||||
y, y_stride, u, u_stride, v, v_stride,
|
||||
dst_width, inv_dst_height);
|
||||
BayerBGGRToI420(src, src_width,
|
||||
y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_width, inv_dst_height);
|
||||
break;
|
||||
|
||||
case FOURCC_GBRG:
|
||||
src = sample + (src_width * crop_y + crop_x);
|
||||
BayerGBRGToI420(src, src_width,
|
||||
y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_width, inv_dst_height);
|
||||
break;
|
||||
|
||||
case FOURCC_GRBG:
|
||||
src = sample + (src_width * crop_y + crop_x);
|
||||
BayerGRBGToI420(src, src_width,
|
||||
y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_width, inv_dst_height);
|
||||
break;
|
||||
|
||||
case FOURCC_RGGB:
|
||||
src = sample + (src_width * crop_y + crop_x);
|
||||
BayerRGGBToI420(src, src_width,
|
||||
y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_width, inv_dst_height);
|
||||
break;
|
||||
|
||||
case FOURCC_I400:
|
||||
src = sample + src_width * crop_y + crop_x;
|
||||
I400ToI420(src, src_width,
|
||||
|
||||
@ -113,20 +113,38 @@ int ConvertFromI420(const uint8* y, int y_stride,
|
||||
dst_sample_stride ? dst_sample_stride : width * 4,
|
||||
width, height);
|
||||
break;
|
||||
#ifdef HAVEI420TOBAYER
|
||||
case FOURCC_BGGR:
|
||||
case FOURCC_RGGB:
|
||||
case FOURCC_GRBG:
|
||||
case FOURCC_GBRG:
|
||||
I420ToBayerRGB(y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width,
|
||||
format,
|
||||
width, height);
|
||||
I420ToBayerBGGR(y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width,
|
||||
width, height);
|
||||
break;
|
||||
case FOURCC_GBRG:
|
||||
I420ToBayerGBRG(y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width,
|
||||
width, height);
|
||||
break;
|
||||
case FOURCC_GRBG:
|
||||
I420ToBayerGRBG(y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width,
|
||||
width, height);
|
||||
break;
|
||||
case FOURCC_RGGB:
|
||||
I420ToBayerRGGB(y, y_stride,
|
||||
u, u_stride,
|
||||
v, v_stride,
|
||||
dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width,
|
||||
width, height);
|
||||
break;
|
||||
#endif
|
||||
case FOURCC_I400:
|
||||
I400Copy(y, y_stride,
|
||||
dst_sample,
|
||||
|
||||
@ -103,61 +103,67 @@ static uint32 GenerateSelector(int select0, int select1) {
|
||||
static_cast<uint32>((select1 + 12) << 24);
|
||||
}
|
||||
|
||||
// Converts 32 bit ARGB to any Bayer RGB format.
|
||||
int ARGBToBayerRGB(const uint8* src_rgb, int src_stride_rgb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
uint32 dst_fourcc_bayer,
|
||||
int width, int height) {
|
||||
static void MakeSelectors(const int blue_index,
|
||||
const int green_index,
|
||||
const int red_index,
|
||||
uint32 dst_fourcc_bayer,
|
||||
uint32 *index_map) {
|
||||
// Now build a lookup table containing the indices for the four pixels in each
|
||||
// 2x2 Bayer grid.
|
||||
switch (dst_fourcc_bayer) {
|
||||
default:
|
||||
assert(false);
|
||||
case FOURCC_BGGR:
|
||||
index_map[0] = GenerateSelector(blue_index, green_index);
|
||||
index_map[1] = GenerateSelector(green_index, red_index);
|
||||
break;
|
||||
case FOURCC_GBRG:
|
||||
index_map[0] = GenerateSelector(green_index, blue_index);
|
||||
index_map[1] = GenerateSelector(red_index, green_index);
|
||||
break;
|
||||
case FOURCC_RGGB:
|
||||
index_map[0] = GenerateSelector(red_index, green_index);
|
||||
index_map[1] = GenerateSelector(green_index, blue_index);
|
||||
break;
|
||||
case FOURCC_GRBG:
|
||||
index_map[0] = GenerateSelector(green_index, red_index);
|
||||
index_map[1] = GenerateSelector(blue_index, green_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Converts 32 bit ARGB to Bayer RGB formats.
|
||||
int ARGBToBayer(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_bayer, int dst_stride_bayer,
|
||||
int width, int height,
|
||||
uint32 dst_fourcc_bayer) {
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
src_rgb = src_rgb + (height - 1) * src_stride_rgb;
|
||||
src_stride_rgb = -src_stride_rgb;
|
||||
src_argb = src_argb + (height - 1) * src_stride_argb;
|
||||
src_stride_argb = -src_stride_argb;
|
||||
}
|
||||
void (*ARGBToBayerRow)(const uint8* src_argb,
|
||||
uint8* dst_bayer, uint32 selector, int pix);
|
||||
#if defined(HAS_ARGBTOBAYERROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3) &&
|
||||
IS_ALIGNED(width, 4) &&
|
||||
IS_ALIGNED(src_rgb, 16) && IS_ALIGNED(src_stride_rgb, 16)) {
|
||||
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
|
||||
ARGBToBayerRow = ARGBToBayerRow_SSSE3;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ARGBToBayerRow = ARGBToBayerRow_C;
|
||||
}
|
||||
|
||||
int blue_index = 0;
|
||||
int green_index = 1;
|
||||
int red_index = 2;
|
||||
|
||||
// Now build a lookup table containing the indices for the four pixels in each
|
||||
// 2x2 Bayer grid.
|
||||
const int blue_index = 0; // Offsets for ARGB format
|
||||
const int green_index = 1;
|
||||
const int red_index = 2;
|
||||
uint32 index_map[2];
|
||||
switch (dst_fourcc_bayer) {
|
||||
default:
|
||||
assert(false);
|
||||
case FOURCC_RGGB:
|
||||
index_map[0] = GenerateSelector(red_index, green_index);
|
||||
index_map[1] = GenerateSelector(green_index, blue_index);
|
||||
break;
|
||||
case FOURCC_BGGR:
|
||||
index_map[0] = GenerateSelector(blue_index, green_index);
|
||||
index_map[1] = GenerateSelector(green_index, red_index);
|
||||
break;
|
||||
case FOURCC_GRBG:
|
||||
index_map[0] = GenerateSelector(green_index, red_index);
|
||||
index_map[1] = GenerateSelector(blue_index, green_index);
|
||||
break;
|
||||
case FOURCC_GBRG:
|
||||
index_map[0] = GenerateSelector(green_index, blue_index);
|
||||
index_map[1] = GenerateSelector(red_index, green_index);
|
||||
break;
|
||||
}
|
||||
MakeSelectors(blue_index, green_index, red_index,
|
||||
dst_fourcc_bayer, index_map);
|
||||
|
||||
// Now convert.
|
||||
for (int y = 0; y < height; ++y) {
|
||||
ARGBToBayerRow(src_rgb, dst_bayer, index_map[y & 1], width);
|
||||
src_rgb += src_stride_rgb;
|
||||
ARGBToBayerRow(src_argb, dst_bayer, index_map[y & 1], width);
|
||||
src_argb += src_stride_argb;
|
||||
dst_bayer += dst_stride_bayer;
|
||||
}
|
||||
return 0;
|
||||
@ -166,185 +172,184 @@ int ARGBToBayerRGB(const uint8* src_rgb, int src_stride_rgb,
|
||||
#define AVG(a,b) (((a) + (b)) >> 1)
|
||||
|
||||
static void BayerRowBG(const uint8* src_bayer0, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix) {
|
||||
uint8* dst_argb, int pix) {
|
||||
const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
|
||||
uint8 g = src_bayer0[1];
|
||||
uint8 r = src_bayer1[1];
|
||||
for (int x = 0; x < pix - 2; x += 2) {
|
||||
dst_rgb[0] = src_bayer0[0];
|
||||
dst_rgb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_rgb[2] = AVG(r, src_bayer1[1]);
|
||||
dst_rgb[3] = 255U;
|
||||
dst_rgb[4] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_rgb[5] = src_bayer0[1];
|
||||
dst_rgb[6] = src_bayer1[1];
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[0] = src_bayer0[0];
|
||||
dst_argb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_argb[2] = AVG(r, src_bayer1[1]);
|
||||
dst_argb[3] = 255U;
|
||||
dst_argb[4] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_argb[5] = src_bayer0[1];
|
||||
dst_argb[6] = src_bayer1[1];
|
||||
dst_argb[7] = 255U;
|
||||
g = src_bayer0[1];
|
||||
r = src_bayer1[1];
|
||||
src_bayer0 += 2;
|
||||
src_bayer1 += 2;
|
||||
dst_rgb += 8;
|
||||
dst_argb += 8;
|
||||
}
|
||||
dst_rgb[0] = src_bayer0[0];
|
||||
dst_rgb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_rgb[2] = AVG(r, src_bayer1[1]);
|
||||
dst_rgb[3] = 255U;
|
||||
dst_argb[0] = src_bayer0[0];
|
||||
dst_argb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_argb[2] = AVG(r, src_bayer1[1]);
|
||||
dst_argb[3] = 255U;
|
||||
if (!(pix & 1)) {
|
||||
dst_rgb[4] = src_bayer0[0];
|
||||
dst_rgb[5] = src_bayer0[1];
|
||||
dst_rgb[6] = src_bayer1[1];
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[4] = src_bayer0[0];
|
||||
dst_argb[5] = src_bayer0[1];
|
||||
dst_argb[6] = src_bayer1[1];
|
||||
dst_argb[7] = 255U;
|
||||
}
|
||||
}
|
||||
|
||||
static void BayerRowRG(const uint8* src_bayer0, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix) {
|
||||
uint8* dst_argb, int pix) {
|
||||
const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
|
||||
uint8 g = src_bayer0[1];
|
||||
uint8 b = src_bayer1[1];
|
||||
for (int x = 0; x < pix - 2; x += 2) {
|
||||
dst_rgb[0] = AVG(b, src_bayer1[1]);
|
||||
dst_rgb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_rgb[2] = src_bayer0[0];
|
||||
dst_rgb[3] = 255U;
|
||||
dst_rgb[4] = src_bayer1[1];
|
||||
dst_rgb[5] = src_bayer0[1];
|
||||
dst_rgb[6] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[0] = AVG(b, src_bayer1[1]);
|
||||
dst_argb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_argb[2] = src_bayer0[0];
|
||||
dst_argb[3] = 255U;
|
||||
dst_argb[4] = src_bayer1[1];
|
||||
dst_argb[5] = src_bayer0[1];
|
||||
dst_argb[6] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_argb[7] = 255U;
|
||||
g = src_bayer0[1];
|
||||
b = src_bayer1[1];
|
||||
src_bayer0 += 2;
|
||||
src_bayer1 += 2;
|
||||
dst_rgb += 8;
|
||||
dst_argb += 8;
|
||||
}
|
||||
dst_rgb[0] = AVG(b, src_bayer1[1]);
|
||||
dst_rgb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_rgb[2] = src_bayer0[0];
|
||||
dst_rgb[3] = 255U;
|
||||
dst_argb[0] = AVG(b, src_bayer1[1]);
|
||||
dst_argb[1] = AVG(g, src_bayer0[1]);
|
||||
dst_argb[2] = src_bayer0[0];
|
||||
dst_argb[3] = 255U;
|
||||
if (!(pix & 1)) {
|
||||
dst_rgb[4] = src_bayer1[1];
|
||||
dst_rgb[5] = src_bayer0[1];
|
||||
dst_rgb[6] = src_bayer0[0];
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[4] = src_bayer1[1];
|
||||
dst_argb[5] = src_bayer0[1];
|
||||
dst_argb[6] = src_bayer0[0];
|
||||
dst_argb[7] = 255U;
|
||||
}
|
||||
}
|
||||
|
||||
static void BayerRowGB(const uint8* src_bayer0, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix) {
|
||||
uint8* dst_argb, int pix) {
|
||||
const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
|
||||
uint8 b = src_bayer0[1];
|
||||
for (int x = 0; x < pix - 2; x += 2) {
|
||||
dst_rgb[0] = AVG(b, src_bayer0[1]);
|
||||
dst_rgb[1] = src_bayer0[0];
|
||||
dst_rgb[2] = src_bayer1[0];
|
||||
dst_rgb[3] = 255U;
|
||||
dst_rgb[4] = src_bayer0[1];
|
||||
dst_rgb[5] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_rgb[6] = AVG(src_bayer1[0], src_bayer1[2]);
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[0] = AVG(b, src_bayer0[1]);
|
||||
dst_argb[1] = src_bayer0[0];
|
||||
dst_argb[2] = src_bayer1[0];
|
||||
dst_argb[3] = 255U;
|
||||
dst_argb[4] = src_bayer0[1];
|
||||
dst_argb[5] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_argb[6] = AVG(src_bayer1[0], src_bayer1[2]);
|
||||
dst_argb[7] = 255U;
|
||||
b = src_bayer0[1];
|
||||
src_bayer0 += 2;
|
||||
src_bayer1 += 2;
|
||||
dst_rgb += 8;
|
||||
dst_argb += 8;
|
||||
}
|
||||
dst_rgb[0] = AVG(b, src_bayer0[1]);
|
||||
dst_rgb[1] = src_bayer0[0];
|
||||
dst_rgb[2] = src_bayer1[0];
|
||||
dst_rgb[3] = 255U;
|
||||
dst_argb[0] = AVG(b, src_bayer0[1]);
|
||||
dst_argb[1] = src_bayer0[0];
|
||||
dst_argb[2] = src_bayer1[0];
|
||||
dst_argb[3] = 255U;
|
||||
if (!(pix & 1)) {
|
||||
dst_rgb[4] = src_bayer0[1];
|
||||
dst_rgb[5] = src_bayer0[0];
|
||||
dst_rgb[6] = src_bayer1[0];
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[4] = src_bayer0[1];
|
||||
dst_argb[5] = src_bayer0[0];
|
||||
dst_argb[6] = src_bayer1[0];
|
||||
dst_argb[7] = 255U;
|
||||
}
|
||||
}
|
||||
|
||||
static void BayerRowGR(const uint8* src_bayer0, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix) {
|
||||
uint8* dst_argb, int pix) {
|
||||
const uint8* src_bayer1 = src_bayer0 + src_stride_bayer;
|
||||
uint8 r = src_bayer0[1];
|
||||
for (int x = 0; x < pix - 2; x += 2) {
|
||||
dst_rgb[0] = src_bayer1[0];
|
||||
dst_rgb[1] = src_bayer0[0];
|
||||
dst_rgb[2] = AVG(r, src_bayer0[1]);
|
||||
dst_rgb[3] = 255U;
|
||||
dst_rgb[4] = AVG(src_bayer1[0], src_bayer1[2]);
|
||||
dst_rgb[5] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_rgb[6] = src_bayer0[1];
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[0] = src_bayer1[0];
|
||||
dst_argb[1] = src_bayer0[0];
|
||||
dst_argb[2] = AVG(r, src_bayer0[1]);
|
||||
dst_argb[3] = 255U;
|
||||
dst_argb[4] = AVG(src_bayer1[0], src_bayer1[2]);
|
||||
dst_argb[5] = AVG(src_bayer0[0], src_bayer0[2]);
|
||||
dst_argb[6] = src_bayer0[1];
|
||||
dst_argb[7] = 255U;
|
||||
r = src_bayer0[1];
|
||||
src_bayer0 += 2;
|
||||
src_bayer1 += 2;
|
||||
dst_rgb += 8;
|
||||
dst_argb += 8;
|
||||
}
|
||||
dst_rgb[0] = src_bayer1[0];
|
||||
dst_rgb[1] = src_bayer0[0];
|
||||
dst_rgb[2] = AVG(r, src_bayer0[1]);
|
||||
dst_rgb[3] = 255U;
|
||||
dst_argb[0] = src_bayer1[0];
|
||||
dst_argb[1] = src_bayer0[0];
|
||||
dst_argb[2] = AVG(r, src_bayer0[1]);
|
||||
dst_argb[3] = 255U;
|
||||
if (!(pix & 1)) {
|
||||
dst_rgb[4] = src_bayer1[0];
|
||||
dst_rgb[5] = src_bayer0[0];
|
||||
dst_rgb[6] = src_bayer0[1];
|
||||
dst_rgb[7] = 255U;
|
||||
dst_argb[4] = src_bayer1[0];
|
||||
dst_argb[5] = src_bayer0[0];
|
||||
dst_argb[6] = src_bayer0[1];
|
||||
dst_argb[7] = 255U;
|
||||
}
|
||||
}
|
||||
|
||||
// Converts any Bayer RGB format to ARGB.
|
||||
int BayerRGBToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint32 src_fourcc_bayer,
|
||||
uint8* dst_rgb, int dst_stride_rgb,
|
||||
int width, int height) {
|
||||
int BayerToARGB(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height,
|
||||
uint32 src_fourcc_bayer) {
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
dst_rgb = dst_rgb + (height - 1) * dst_stride_rgb;
|
||||
dst_stride_rgb = -dst_stride_rgb;
|
||||
dst_argb = dst_argb + (height - 1) * dst_stride_argb;
|
||||
dst_stride_argb = -dst_stride_argb;
|
||||
}
|
||||
void (*BayerRow0)(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix);
|
||||
uint8* dst_argb, int pix);
|
||||
void (*BayerRow1)(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix);
|
||||
|
||||
uint8* dst_argb, int pix);
|
||||
switch (src_fourcc_bayer) {
|
||||
default:
|
||||
assert(false);
|
||||
case FOURCC_RGGB:
|
||||
BayerRow0 = BayerRowRG;
|
||||
BayerRow1 = BayerRowGB;
|
||||
break;
|
||||
case FOURCC_BGGR:
|
||||
BayerRow0 = BayerRowBG;
|
||||
BayerRow1 = BayerRowGR;
|
||||
break;
|
||||
case FOURCC_GRBG:
|
||||
BayerRow0 = BayerRowGR;
|
||||
BayerRow1 = BayerRowBG;
|
||||
break;
|
||||
case FOURCC_GBRG:
|
||||
BayerRow0 = BayerRowGB;
|
||||
BayerRow1 = BayerRowRG;
|
||||
break;
|
||||
case FOURCC_GRBG:
|
||||
BayerRow0 = BayerRowGR;
|
||||
BayerRow1 = BayerRowBG;
|
||||
break;
|
||||
case FOURCC_RGGB:
|
||||
BayerRow0 = BayerRowRG;
|
||||
BayerRow1 = BayerRowGB;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int y = 0; y < height - 1; y += 2) {
|
||||
BayerRow0(src_bayer, src_stride_bayer, dst_rgb, width);
|
||||
BayerRow0(src_bayer, src_stride_bayer, dst_argb, width);
|
||||
BayerRow1(src_bayer + src_stride_bayer, -src_stride_bayer,
|
||||
dst_rgb + dst_stride_rgb, width);
|
||||
dst_argb + dst_stride_argb, width);
|
||||
src_bayer += src_stride_bayer * 2;
|
||||
dst_rgb += dst_stride_rgb * 2;
|
||||
dst_argb += dst_stride_argb * 2;
|
||||
}
|
||||
if (height & 1) {
|
||||
BayerRow0(src_bayer, -src_stride_bayer, dst_rgb, width);
|
||||
BayerRow0(src_bayer, -src_stride_bayer, dst_argb, width);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Converts any Bayer RGB format to ARGB.
|
||||
int BayerRGBToI420(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint32 src_fourcc_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) {
|
||||
int 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) {
|
||||
if (width * 4 > kMaxStride) {
|
||||
return -1;
|
||||
}
|
||||
@ -360,9 +365,9 @@ int BayerRGBToI420(const uint8* src_bayer, int src_stride_bayer,
|
||||
dst_stride_v = -dst_stride_v;
|
||||
}
|
||||
void (*BayerRow0)(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix);
|
||||
uint8* dst_argb, int pix);
|
||||
void (*BayerRow1)(const uint8* src_bayer, int src_stride_bayer,
|
||||
uint8* dst_rgb, int pix);
|
||||
uint8* dst_argb, int pix);
|
||||
void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix);
|
||||
void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb,
|
||||
uint8* dst_u, uint8* dst_v, int width);
|
||||
@ -390,21 +395,21 @@ int BayerRGBToI420(const uint8* src_bayer, int src_stride_bayer,
|
||||
switch (src_fourcc_bayer) {
|
||||
default:
|
||||
assert(false);
|
||||
case FOURCC_RGGB:
|
||||
BayerRow0 = BayerRowRG;
|
||||
BayerRow1 = BayerRowGB;
|
||||
break;
|
||||
case FOURCC_BGGR:
|
||||
BayerRow0 = BayerRowBG;
|
||||
BayerRow1 = BayerRowGR;
|
||||
break;
|
||||
case FOURCC_GBRG:
|
||||
BayerRow0 = BayerRowGB;
|
||||
BayerRow1 = BayerRowRG;
|
||||
break;
|
||||
case FOURCC_GRBG:
|
||||
BayerRow0 = BayerRowGR;
|
||||
BayerRow1 = BayerRowBG;
|
||||
break;
|
||||
case FOURCC_GBRG:
|
||||
BayerRow0 = BayerRowGB;
|
||||
BayerRow1 = BayerRowRG;
|
||||
case FOURCC_RGGB:
|
||||
BayerRow0 = BayerRowRG;
|
||||
BayerRow1 = BayerRowGB;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -428,6 +433,122 @@ int BayerRGBToI420(const uint8* src_bayer, int src_stride_bayer,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I420 to Bayer.
|
||||
int 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) {
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
int halfheight = (height + 1) >> 1;
|
||||
src_y = src_y + (height - 1) * src_stride_y;
|
||||
src_u = src_u + (halfheight - 1) * src_stride_u;
|
||||
src_v = src_v + (halfheight - 1) * src_stride_v;
|
||||
src_stride_y = -src_stride_y;
|
||||
src_stride_u = -src_stride_u;
|
||||
src_stride_v = -src_stride_v;
|
||||
}
|
||||
void (*FastConvertYUVToARGBRow)(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
int width);
|
||||
#if defined(HAS_FASTCONVERTYUVTOARGBROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
FastConvertYUVToARGBRow = FastConvertYUVToARGBRow_NEON;
|
||||
} else
|
||||
#elif defined(HAS_FASTCONVERTYUVTOARGBROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
FastConvertYUVToARGBRow = FastConvertYUVToARGBRow_SSSE3;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
FastConvertYUVToARGBRow = FastConvertYUVToARGBRow_C;
|
||||
}
|
||||
SIMD_ALIGNED(uint8 row[kMaxStride]);
|
||||
void (*ARGBToBayerRow)(const uint8* src_argb,
|
||||
uint8* dst_bayer, uint32 selector, int pix);
|
||||
#if defined(HAS_ARGBTOBAYERROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4)) {
|
||||
ARGBToBayerRow = ARGBToBayerRow_SSSE3;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ARGBToBayerRow = ARGBToBayerRow_C;
|
||||
}
|
||||
const int blue_index = 0; // Offsets for ARGB format
|
||||
const int green_index = 1;
|
||||
const int red_index = 2;
|
||||
uint32 index_map[2];
|
||||
MakeSelectors(blue_index, green_index, red_index,
|
||||
dst_fourcc_bayer, index_map);
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
FastConvertYUVToARGBRow(src_y, src_u, src_v, row, width);
|
||||
ARGBToBayerRow(row, dst_bayer, index_map[y & 1], width);
|
||||
dst_bayer += dst_stride_bayer;
|
||||
src_y += src_stride_y;
|
||||
if (y & 1) {
|
||||
src_u += src_stride_u;
|
||||
src_v += src_stride_v;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAKEBAYERFOURCC(BAYER) \
|
||||
int Bayer##BAYER##ToI420(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) { \
|
||||
return BayerToI420(src_bayer, src_stride_bayer, \
|
||||
dst_y, dst_stride_y, \
|
||||
dst_u, dst_stride_u, \
|
||||
dst_v, dst_stride_v, \
|
||||
width, height, \
|
||||
FOURCC_##BAYER); \
|
||||
} \
|
||||
\
|
||||
int I420ToBayer##BAYER(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) { \
|
||||
return I420ToBayer(src_y, src_stride_y, \
|
||||
src_u, src_stride_u, \
|
||||
src_v, src_stride_v, \
|
||||
dst_bayer, dst_stride_bayer, \
|
||||
width, height, \
|
||||
FOURCC_##BAYER); \
|
||||
} \
|
||||
\
|
||||
int ARGBToBayer##BAYER(const uint8* src_argb, int src_stride_argb, \
|
||||
uint8* dst_bayer, int dst_stride_bayer, \
|
||||
int width, int height) { \
|
||||
return ARGBToBayer(src_argb, src_stride_argb, \
|
||||
dst_bayer, dst_stride_bayer, \
|
||||
width, height, \
|
||||
FOURCC_##BAYER); \
|
||||
} \
|
||||
\
|
||||
int Bayer##BAYER##ToARGB(const uint8* src_bayer, int src_stride_bayer, \
|
||||
uint8* dst_argb, int dst_stride_argb, \
|
||||
int width, int height) { \
|
||||
return BayerToARGB(src_bayer, src_stride_bayer, \
|
||||
dst_argb, dst_stride_argb, \
|
||||
width, height, \
|
||||
FOURCC_##BAYER); \
|
||||
}
|
||||
|
||||
MAKEBAYERFOURCC(BGGR)
|
||||
MAKEBAYERFOURCC(GBRG)
|
||||
MAKEBAYERFOURCC(GRBG)
|
||||
MAKEBAYERFOURCC(RGGB)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // namespace libyuv
|
||||
|
||||
@ -1615,10 +1615,10 @@ int I420ToABGR(const uint8* src_y, int src_stride_y,
|
||||
|
||||
// Convert I420 to RGB24.
|
||||
int I420ToRGB24(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_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
const uint8* src_u, int src_stride_u,
|
||||
const uint8* src_v, int src_stride_v,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
@ -1781,10 +1781,10 @@ int I420ToRGB565(const uint8* src_y, int src_stride_y,
|
||||
|
||||
// Convert I420 to ARGB1555.
|
||||
int I420ToARGB1555(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_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
const uint8* src_u, int src_stride_u,
|
||||
const uint8* src_v, int src_stride_v,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
@ -1835,10 +1835,10 @@ int I420ToARGB1555(const uint8* src_y, int src_stride_y,
|
||||
|
||||
// Convert I420 to ARGB4444.
|
||||
int I420ToARGB4444(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_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
const uint8* src_u, int src_stride_u,
|
||||
const uint8* src_v, int src_stride_v,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user