From a7d977ceae6215332f359ab289a93460a24dc1e0 Mon Sep 17 00:00:00 2001 From: "fbarchard@google.com" Date: Mon, 9 Jan 2012 20:01:08 +0000 Subject: [PATCH] RGBP, RGBO, R444 fourcc support BUG=none TEST=camtool with xo175 Review URL: http://webrtc-codereview.appspot.com/347001 git-svn-id: http://libyuv.googlecode.com/svn/trunk@128 16f28f9a-4ce2-e073-06de-1de4eb20be90 --- README.chromium | 2 +- include/libyuv/convert.h | 18 ++++ include/libyuv/video_common.h | 17 +-- source/convert.cc | 190 +++++++++++++++++++++++++++++++++- source/convertfrom.cc | 21 ++++ source/planar_functions.cc | 1 - source/row.h | 34 ++++++ source/row_common.cc | 130 ++++++++++++++++++++++- 8 files changed, 402 insertions(+), 11 deletions(-) diff --git a/README.chromium b/README.chromium index 6fa90e921..f20edd477 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 126 +Version: 128 License: BSD License File: LICENSE diff --git a/include/libyuv/convert.h b/include/libyuv/convert.h index c61d04d5f..35663f0f5 100644 --- a/include/libyuv/convert.h +++ b/include/libyuv/convert.h @@ -86,6 +86,24 @@ int RAWToI420(const uint8* src_frame, int src_stride_frame, uint8* dst_v, int dst_stride_v, int width, int height); +int RGB565ToI420(const uint8* src_frame, int src_stride_frame, + 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 ARGB1555ToI420(const uint8* src_frame, int src_stride_frame, + 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 ARGB4444ToI420(const uint8* src_frame, int src_stride_frame, + 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 ABGRToI420(const uint8* src_frame, int src_stride_frame, uint8* dst_y, int dst_stride_y, uint8* dst_u, int dst_stride_u, diff --git a/include/libyuv/video_common.h b/include/libyuv/video_common.h index cd1b3076a..75f0c7b4f 100644 --- a/include/libyuv/video_common.h +++ b/include/libyuv/video_common.h @@ -23,19 +23,20 @@ extern "C" { #endif ////////////////////////////////////////////////////////////////////////////// -// Definition of fourcc. +// Definition of FourCC codes ////////////////////////////////////////////////////////////////////////////// -// Convert four characters to a fourcc code. +// Convert four characters to a FourCC code. // Needs to be a macro otherwise the OS X compiler complains when the kFormat* // constants are used in a switch. -#define FOURCC(a, b, c, d) (\ +#define FOURCC(a, b, c, d) ( \ (static_cast(a)) | (static_cast(b) << 8) | \ (static_cast(c) << 16) | (static_cast(d) << 24)) -// Some good pages discussing FourCC codes: -// http://developer.apple.com/quicktime/icefloe/dispatch020.html +// Some pages discussing FourCC codes: // http://www.fourcc.org/yuv.php -// http://linuxtv.org/downloads/v4l-dvb-apis/pixfmt.html +// http://v4l2spec.bytesex.org/spec/book1.htm +// http://developer.apple.com/quicktime/icefloe/dispatch020.html + enum FourCC { // Canonical fourcc codes used in our code. FOURCC_I420 = FOURCC('I', '4', '2', '0'), @@ -53,6 +54,9 @@ enum FourCC { FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'), FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'), FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'), + FOURCC_RGBP = FOURCC('R', 'G', 'B', 'P'), // bgr565 + FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // abgr1555 + FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444 FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'), FOURCC_RAW = FOURCC('r', 'a', 'w', ' '), FOURCC_NV21 = FOURCC('N', 'V', '2', '1'), @@ -75,6 +79,7 @@ enum FourCC { FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'), // Alias for UYVY FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'), // Alias for UYVY FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'), // Alias for MJPG + FOURCC_DMB1 = FOURCC('d', 'm', 'b', '1'), // Alias for MJPG on Mac FOURCC_BA81 = FOURCC('B', 'A', '8', '1'), // Alias for BGGR FOURCC_RGB3 = FOURCC('R', 'G', 'B', '3'), // Alias for RAW FOURCC_BGR3 = FOURCC('B', 'G', 'R', '3'), // Alias for 24BG diff --git a/source/convert.cc b/source/convert.cc index d6f06f265..2eb120732 100644 --- a/source/convert.cc +++ b/source/convert.cc @@ -39,6 +39,7 @@ static __inline uint8 Clip(int32 val) { return (uint8) val; } +// FourCC is 24BG. bgr in memory // TODO(fbarchard): rewrite with row functions int I420ToRGB24(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -107,7 +108,7 @@ int I420ToRGB24(const uint8* src_y, int src_stride_y, return 0; } -// same as RGB24 but r,g,b instead of b,g,r +// FourCC is RAW. Same as RGB24 but r,g,b instead of b,g,r // TODO(fbarchard): rewrite with row functions int I420ToRAW(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -178,7 +179,7 @@ int I420ToRAW(const uint8* src_y, int src_stride_y, return 0; } -// Little Endian... +// FourCC is R444. Little Endian... // TODO(fbarchard): rewrite with row functions int I420ToARGB4444(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -246,6 +247,7 @@ int I420ToARGB4444(const uint8* src_y, int src_stride_y, return 0; } +// FourCC RGBP little endian rgb565 // TODO(fbarchard): rewrite with row functions int I420ToRGB565(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -325,6 +327,7 @@ int I420ToRGB565(const uint8* src_y, int src_stride_y, return 0; } +// FourCC RGBO little endian rgb565 // TODO(fbarchard): rewrite with row functions int I420ToARGB1555(const uint8* src_y, int src_stride_y, const uint8* src_u, int src_stride_u, @@ -1045,6 +1048,165 @@ int RAWToI420(const uint8* src_frame, int src_stride_frame, return 0; } +int RGB565ToI420(const uint8* src_frame, int src_stride_frame, + 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) { + if (height < 0) { + height = -height; + src_frame = src_frame + (height - 1) * src_stride_frame; + src_stride_frame = -src_stride_frame; + } + 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); +#if defined(HAS_RGB565TOYROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && + IS_ALIGNED(width, 16) && + IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && + IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { + ARGBToYRow = RGB565ToYRow_SSSE3; + } else +#endif + { + ARGBToYRow = RGB565ToYRow_C; + } +#if defined(HAS_RGB565TOUVROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && + IS_ALIGNED(width, 16) && + IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && + IS_ALIGNED(dst_u, 8) && IS_ALIGNED(dst_stride_u, 8) && + IS_ALIGNED(dst_v, 8) && IS_ALIGNED(dst_stride_v, 8)) { + ARGBToUVRow = RGB565ToUVRow_SSSE3; + } else +#endif + { + ARGBToUVRow = RGB565ToUVRow_C; + } + + for (int y = 0; y < (height - 1); y += 2) { + ARGBToUVRow(src_frame, src_stride_frame, dst_u, dst_v, width); + ARGBToYRow(src_frame, dst_y, width); + ARGBToYRow(src_frame + src_stride_frame, dst_y + dst_stride_y, width); + src_frame += src_stride_frame * 2; + dst_y += dst_stride_y * 2; + dst_u += dst_stride_u; + dst_v += dst_stride_v; + } + if (height & 1) { + ARGBToUVRow(src_frame, 0, dst_u, dst_v, width); + ARGBToYRow(src_frame, dst_y, width); + } + return 0; +} + +int ARGB1555ToI420(const uint8* src_frame, int src_stride_frame, + 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) { + if (height < 0) { + height = -height; + src_frame = src_frame + (height - 1) * src_stride_frame; + src_stride_frame = -src_stride_frame; + } + 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); +#if defined(HAS_ARGB1555TOYROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && + IS_ALIGNED(width, 16) && + IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && + IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { + ARGBToYRow = ARGB1555ToYRow_SSSE3; + } else +#endif + { + ARGBToYRow = ARGB1555ToYRow_C; + } +#if defined(HAS_ARGB1555TOUVROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && + IS_ALIGNED(width, 16) && + IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && + IS_ALIGNED(dst_u, 8) && IS_ALIGNED(dst_stride_u, 8) && + IS_ALIGNED(dst_v, 8) && IS_ALIGNED(dst_stride_v, 8)) { + ARGBToUVRow = ARGB1555ToUVRow_SSSE3; + } else +#endif + { + ARGBToUVRow = ARGB1555ToUVRow_C; + } + + for (int y = 0; y < (height - 1); y += 2) { + ARGBToUVRow(src_frame, src_stride_frame, dst_u, dst_v, width); + ARGBToYRow(src_frame, dst_y, width); + ARGBToYRow(src_frame + src_stride_frame, dst_y + dst_stride_y, width); + src_frame += src_stride_frame * 2; + dst_y += dst_stride_y * 2; + dst_u += dst_stride_u; + dst_v += dst_stride_v; + } + if (height & 1) { + ARGBToUVRow(src_frame, 0, dst_u, dst_v, width); + ARGBToYRow(src_frame, dst_y, width); + } + return 0; +} + +int ARGB4444ToI420(const uint8* src_frame, int src_stride_frame, + 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) { + if (height < 0) { + height = -height; + src_frame = src_frame + (height - 1) * src_stride_frame; + src_stride_frame = -src_stride_frame; + } + 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); +#if defined(HAS_ARGB4444TOYROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && + IS_ALIGNED(width, 16) && + IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && + IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { + ARGBToYRow = ARGB4444ToYRow_SSSE3; + } else +#endif + { + ARGBToYRow = ARGB4444ToYRow_C; + } +#if defined(HAS_ARGB4444TOUVROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3) && + IS_ALIGNED(width, 16) && + IS_ALIGNED(src_frame, 16) && IS_ALIGNED(src_stride_frame, 16) && + IS_ALIGNED(dst_u, 8) && IS_ALIGNED(dst_stride_u, 8) && + IS_ALIGNED(dst_v, 8) && IS_ALIGNED(dst_stride_v, 8)) { + ARGBToUVRow = ARGB4444ToUVRow_SSSE3; + } else +#endif + { + ARGBToUVRow = ARGB4444ToUVRow_C; + } + + for (int y = 0; y < (height - 1); y += 2) { + ARGBToUVRow(src_frame, src_stride_frame, dst_u, dst_v, width); + ARGBToYRow(src_frame, dst_y, width); + ARGBToYRow(src_frame + src_stride_frame, dst_y + dst_stride_y, width); + src_frame += src_stride_frame * 2; + dst_y += dst_stride_y * 2; + dst_u += dst_stride_u; + dst_v += dst_stride_v; + } + if (height & 1) { + ARGBToUVRow(src_frame, 0, dst_u, dst_v, width); + ARGBToYRow(src_frame, dst_y, width); + } + return 0; +} + // Convert camera sample to I420 with cropping, rotation and vertical flip. // src_width is used for source stride computation // src_height is used to compute location of planes, and indicate inversion @@ -1130,6 +1292,30 @@ int ConvertToI420(const uint8* sample, size_t sample_size, v, v_stride, dst_width, inv_dst_height); break; + case FOURCC_RGBP: + src = sample + (src_width * crop_y + crop_x) * 4; + RGB565ToI420(src, src_width * 4, + y, y_stride, + u, u_stride, + v, v_stride, + dst_width, inv_dst_height); + break; + case FOURCC_RGBO: + src = sample + (src_width * crop_y + crop_x) * 4; + ARGB1555ToI420(src, src_width * 4, + y, y_stride, + u, u_stride, + v, v_stride, + dst_width, inv_dst_height); + break; + case FOURCC_R444: + src = sample + (src_width * crop_y + crop_x) * 4; + ARGB4444ToI420(src, src_width * 4, + y, y_stride, + u, u_stride, + v, v_stride, + dst_width, inv_dst_height); + break; case FOURCC_BGGR: case FOURCC_RGGB: case FOURCC_GRBG: diff --git a/source/convertfrom.cc b/source/convertfrom.cc index b4a51e957..5297131ec 100644 --- a/source/convertfrom.cc +++ b/source/convertfrom.cc @@ -50,6 +50,27 @@ int ConvertFromI420(const uint8* y, int y_stride, dst_sample, width * 2, width, height); break; + case FOURCC_RGBP: + I420ToRGB565(y, y_stride, + u, u_stride, + v, v_stride, + dst_sample, width * 2, + width, height); + break; + case FOURCC_RGBO: + I420ToARGB1555(y, y_stride, + u, u_stride, + v, v_stride, + dst_sample, width * 2, + width, height); + break; + case FOURCC_R444: + I420ToARGB4444(y, y_stride, + u, u_stride, + v, v_stride, + dst_sample, width * 2, + width, height); + break; case FOURCC_24BG: I420ToRGB24(y, y_stride, u, u_stride, diff --git a/source/planar_functions.cc b/source/planar_functions.cc index 7401c8ff6..7bde26623 100644 --- a/source/planar_functions.cc +++ b/source/planar_functions.cc @@ -1845,7 +1845,6 @@ void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix); return 0; } - // Convert RAW to ARGB. int RAWToARGB(const uint8* src_raw, int src_stride_raw, uint8* dst_argb, int dst_stride_argb, diff --git a/source/row.h b/source/row.h index 0081b1ac5..dfac1dd9b 100644 --- a/source/row.h +++ b/source/row.h @@ -37,6 +37,12 @@ #define HAS_ARGBTOUVROW_SSSE3 #define HAS_BGRATOUVROW_SSSE3 #define HAS_ABGRTOUVROW_SSSE3 +#define HAS_RGB565TOYROW_SSSE3 +#define HAS_ARGB1555TOYROW_SSSE3 +#define HAS_ARGB4444TOYROW_SSSE3 +#define HAS_RGB565TOUVROW_SSSE3 +#define HAS_ARGB1555TOUVROW_SSSE3 +#define HAS_ARGB4444TOUVROW_SSSE3 #define HAS_I400TOARGBROW_SSE2 #define HAS_FASTCONVERTYTOARGBROW_SSE2 #define HAS_FASTCONVERTYUVTOARGBROW_SSSE3 @@ -99,10 +105,21 @@ void ABGRToUVRow_SSSE3(const uint8* src_argb0, int src_stride_argb, #ifdef HASRGB24TOYROW_SSSE3 void RGB24ToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix); void RAWToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix); +void RGB565ToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix); +void ARGB1555ToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix); +void ARGB4444ToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix); + void RGB24ToUVRow_SSSE3(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, uint8* dst_v, int width); void RAWToUVRow_SSSE3(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, uint8* dst_v, int width); +void RGB565ToUVRow_SSSE3(const uint8* src_argb0, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int width); +void ARGB1555ToUVRow_SSSE3(const uint8* src_argb0, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int width); +void ARGB4444ToUVRow_SSSE3(const uint8* src_argb0, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int width); + #endif #ifdef HAS_REVERSE_ROW_SSSE3 void ReverseRow_SSSE3(const uint8* src, uint8* dst, int width); @@ -120,6 +137,10 @@ void BGRAToYRow_C(const uint8* src_argb, uint8* dst_y, int pix); void ABGRToYRow_C(const uint8* src_argb, uint8* dst_y, int pix); void RGB24ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix); void RAWToYRow_C(const uint8* src_argb, uint8* dst_y, int pix); +void RGB565ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix); +void ARGB1555ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix); +void ARGB4444ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix); + void ARGBToUVRow_C(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, uint8* dst_v, int width); void BGRAToUVRow_C(const uint8* src_argb0, int src_stride_argb, @@ -130,17 +151,30 @@ void RGB24ToUVRow_C(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, uint8* dst_v, int width); void RAWToUVRow_C(const uint8* src_argb0, int src_stride_argb, uint8* dst_u, uint8* dst_v, int width); +void RGB565ToUVRow_C(const uint8* src_argb0, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int width); +void ARGB1555ToUVRow_C(const uint8* src_argb0, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int width); +void ARGB4444ToUVRow_C(const uint8* src_argb0, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int width); #ifdef HAS_BG24TOARGBROW_SSSE3 void ABGRToARGBRow_SSSE3(const uint8* src_abgr, uint8* dst_argb, int pix); void BGRAToARGBRow_SSSE3(const uint8* src_bgra, uint8* dst_argb, int pix); void BG24ToARGBRow_SSSE3(const uint8* src_bg24, uint8* dst_argb, int pix); void RAWToARGBRow_SSSE3(const uint8* src_bg24, uint8* dst_argb, int pix); +// TODO(fbarchard): SSE2 565 etc +//void RGB565ToARGBRow_SSE2(const uint8* src_rgb, uint8* dst_argb, int pix); +//void ARGB1555ToARGBRow_SSE2(const uint8* src_argb, uint8* dst_argb, int pix); +//void ARGB4444ToARGBRow_SSE2(const uint8* src_argb, uint8* dst_argb, int pix); #endif void ABGRToARGBRow_C(const uint8* src_abgr, uint8* dst_argb, int pix); void BGRAToARGBRow_C(const uint8* src_bgra, uint8* dst_argb, int pix); void BG24ToARGBRow_C(const uint8* src_bg24, uint8* dst_argb, int pix); void RAWToARGBRow_C(const uint8* src_bg24, uint8* dst_argb, int pix); +void RGB565ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int pix); +void ARGB1555ToARGBRow_C(const uint8* src_argb, uint8* dst_argb, int pix); +void ARGB4444ToARGBRow_C(const uint8* src_argb, uint8* dst_argb, int pix); #ifdef HAS_I400TOARGBROW_SSE2 void I400ToARGBRow_SSE2(const uint8* src_y, uint8* dst_argb, int pix); diff --git a/source/row_common.cc b/source/row_common.cc index db7fb779d..f94014f05 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -72,12 +72,55 @@ void BG24ToARGBRow_C(const uint8* src_bg24, uint8* dst_argb, int pix) { dst_argb[1] = g; dst_argb[2] = r; dst_argb[3] = 255u; - dst_argb[3] = 255u; dst_argb += 4; src_bg24 += 3; } } +void RGB565ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int pix) { + for (int x = 0; x < pix; ++x) { + uint8 b = src_rgb[0] & 0x1f; + uint8 g = (src_rgb[0] >> 5) | ((src_rgb[1] & 0x07) << 3); + uint8 r = src_rgb[1] >> 3; + dst_argb[0] = (b << 3) | (b >> 2); + dst_argb[1] = (g << 2) | (g >> 4); + dst_argb[2] = (r << 3) | (r >> 2); + dst_argb[3] = 255u; + dst_argb += 4; + src_rgb += 2; + } +} + +void ARGB1555ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int pix) { + for (int x = 0; x < pix; ++x) { + uint8 b = src_rgb[0] & 0x1f; + uint8 g = (src_rgb[0] >> 5) | ((src_rgb[1] & 0x03) << 3); + uint8 r = (src_rgb[1] & 0x7c) >> 2; + uint8 a = src_rgb[1] >> 7; + dst_argb[0] = (b << 3) | (b >> 2); + dst_argb[1] = (g << 3) | (g >> 2); + dst_argb[2] = (r << 3) | (r >> 2); + dst_argb[3] = a ? 255u : 0u; + dst_argb += 4; + src_rgb += 2; + } +} + +void ARGB4444ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int pix) { + for (int x = 0; x < pix; ++x) { + uint8 b = src_rgb[0] & 0x1f; + uint8 g = src_rgb[0] >> 4; + uint8 r = src_rgb[1] & 0x1f; + uint8 a = src_rgb[1] >> 4; + dst_argb[0] = (b << 4) | b; + dst_argb[1] = (g << 4) | g; + dst_argb[2] = (r << 4) | r; + dst_argb[3] = (a << 4) | a; + dst_argb += 4; + src_rgb += 2; + } +} + // C versions do the same void RGB24ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix) { SIMD_ALIGNED(uint8 row[kMaxStride]); @@ -91,6 +134,24 @@ void RAWToYRow_C(const uint8* src_argb, uint8* dst_y, int pix) { ARGBToYRow_C(row, dst_y, pix); } +void RGB565ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride]); + RGB565ToARGBRow_C(src_argb, row, pix); + ARGBToYRow_C(row, dst_y, pix); +} + +void ARGB1555ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride]); + ARGB1555ToARGBRow_C(src_argb, row, pix); + ARGBToYRow_C(row, dst_y, pix); +} + +void ARGB4444ToYRow_C(const uint8* src_argb, uint8* dst_y, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride]); + ARGB4444ToARGBRow_C(src_argb, row, pix); + ARGBToYRow_C(row, dst_y, pix); +} + void RGB24ToUVRow_C(const uint8* src_argb, int src_stride_argb, uint8* dst_u, uint8* dst_v, int pix) { SIMD_ALIGNED(uint8 row[kMaxStride * 2]); @@ -107,6 +168,30 @@ void RAWToUVRow_C(const uint8* src_argb, int src_stride_argb, ARGBToUVRow_C(row, kMaxStride, dst_u, dst_v, pix); } +void RGB565ToUVRow_C(const uint8* src_argb, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride * 2]); + RGB565ToARGBRow_C(src_argb, row, pix); + RGB565ToARGBRow_C(src_argb + src_stride_argb, row + kMaxStride, pix); + ARGBToUVRow_C(row, kMaxStride, dst_u, dst_v, pix); +} + +void ARGB1555ToUVRow_C(const uint8* src_argb, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride * 2]); + ARGB1555ToARGBRow_C(src_argb, row, pix); + ARGB1555ToARGBRow_C(src_argb + src_stride_argb, row + kMaxStride, pix); + ARGBToUVRow_C(row, kMaxStride, dst_u, dst_v, pix); +} + +void ARGB4444ToUVRow_C(const uint8* src_argb, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride * 2]); + ARGB4444ToARGBRow_C(src_argb, row, pix); + ARGB4444ToARGBRow_C(src_argb + src_stride_argb, row + kMaxStride, pix); + ARGBToUVRow_C(row, kMaxStride, dst_u, dst_v, pix); +} + static __inline int RGBToY(uint8 r, uint8 g, uint8 b) { return (( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16; } @@ -170,6 +255,24 @@ void RAWToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) { ARGBToYRow_SSSE3(row, dst_y, pix); } +// TODO(fbarchard): RGB565ToARGBRow_SSE2 for rgb conversion +void RGB565ToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride]); + RGB565ToARGBRow_C(src_argb, row, pix); + ARGBToYRow_SSSE3(row, dst_y, pix); +} + +void ARGB1555ToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride]); + ARGB1555ToARGBRow_C(src_argb, row, pix); + ARGBToYRow_SSSE3(row, dst_y, pix); +} + +void ARGB4444ToYRow_SSSE3(const uint8* src_argb, uint8* dst_y, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride]); + ARGB4444ToARGBRow_C(src_argb, row, pix); + ARGBToYRow_SSSE3(row, dst_y, pix); +} #endif #if defined(HAS_RAWTOUVROW_SSSE3) @@ -190,6 +293,31 @@ void RAWToUVRow_SSSE3(const uint8* src_argb, int src_stride_argb, ARGBToUVRow_SSSE3(row, kMaxStride, dst_u, dst_v, pix); } +// TODO(fbarchard): RGB565ToARGBRow_SSE2 for rgb conversion +void RGB565ToUVRow_SSSE3(const uint8* src_argb, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride * 2]); + RGB565ToARGBRow_C(src_argb, row, pix); + RGB565ToARGBRow_C(src_argb + src_stride_argb, row + kMaxStride, pix); + ARGBToUVRow_SSSE3(row, kMaxStride, dst_u, dst_v, pix); +} + +void ARGB1555ToUVRow_SSSE3(const uint8* src_argb, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride * 2]); + ARGB1555ToARGBRow_C(src_argb, row, pix); + ARGB1555ToARGBRow_C(src_argb + src_stride_argb, row + kMaxStride, pix); + ARGBToUVRow_SSSE3(row, kMaxStride, dst_u, dst_v, pix); +} + +void ARGB4444ToUVRow_SSSE3(const uint8* src_argb, int src_stride_argb, + uint8* dst_u, uint8* dst_v, int pix) { + SIMD_ALIGNED(uint8 row[kMaxStride * 2]); + ARGB4444ToARGBRow_C(src_argb, row, pix); + ARGB4444ToARGBRow_C(src_argb + src_stride_argb, row + kMaxStride, pix); + ARGBToUVRow_SSSE3(row, kMaxStride, dst_u, dst_v, pix); +} + #else void RGB24ToUVRow_SSSE3(const uint8* src_argb, int src_stride_argb,