Commit c9911bcb authored by fbarchard@google.com's avatar fbarchard@google.com

more functions added for convertFromI420

BUG=none
TEST=none
Review URL: http://webrtc-codereview.appspot.com/333015

git-svn-id: http://libyuv.googlecode.com/svn/trunk@118 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 52f5bb91
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 117
Version: 118
License: BSD
License File: LICENSE
......
......@@ -19,12 +19,20 @@ namespace libyuv {
extern "C" {
#endif
// RGB24 is also known as 24BG and BGR3
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_frame, int dst_stride_frame,
int width, int height);
// RAW is also known as RGB3
int I420ToRAW(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 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,
......
......@@ -63,6 +63,15 @@ int I444ToI420(const uint8* src_y, int src_stride_y,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert I420 to I444.
int I420ToI444(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_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert I400 (grey) to I420.
int I400ToI420(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
......@@ -70,6 +79,11 @@ int I400ToI420(const uint8* src_y, int src_stride_y,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Copy to I400. Source can be I420,422,444,400,NV12,NV21
int I400Copy(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
int width, int height);
// Convert NV12 to I420. Also used for NV21.
int NV12ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_uv, int src_stride_uv,
......
......@@ -39,6 +39,7 @@ static __inline uint8 Clip(int32 val) {
return (uint8) val;
}
// TODO(fbarchard): rewrite with row functions
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,
......@@ -108,7 +109,79 @@ int I420ToRGB24(const uint8* src_y, int src_stride_y,
return 0;
}
// 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,
const uint8* src_v, int src_stride_v,
uint8* dst_frame, int dst_stride_frame,
int width, int height) {
if (src_y == NULL || src_u == NULL || src_v == NULL || dst_frame == NULL) {
return -1;
}
// RGB orientation - bottom up
// TODO(fbarchard): support inversion
uint8* out = dst_frame + dst_stride_frame * height - dst_stride_frame;
uint8* out2 = out - dst_stride_frame;
int h, w;
int tmp_r, tmp_g, tmp_b;
const uint8 *y1, *y2 ,*u, *v;
y1 = src_y;
y2 = y1 + src_stride_y;
u = src_u;
v = src_v;
for (h = ((height + 1) >> 1); h > 0; h--){
// 2 rows at a time, 2 y's at a time
for (w = 0; w < ((width + 1) >> 1); w++){
// Vertical and horizontal sub-sampling
tmp_r = (int32)((mapYc[y1[0]] + mapVcr[v[0]] + 128) >> 8);
tmp_g = (int32)((mapYc[y1[0]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmp_b = (int32)((mapYc[y1[0]] + mapUcb[u[0]] + 128) >> 8);
out[0] = Clip(tmp_r);
out[1] = Clip(tmp_g);
out[2] = Clip(tmp_b);
tmp_r = (int32)((mapYc[y1[1]] + mapVcr[v[0]] + 128) >> 8);
tmp_g = (int32)((mapYc[y1[1]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmp_b = (int32)((mapYc[y1[1]] + mapUcb[u[0]] + 128) >> 8);
out[3] = Clip(tmp_r);
out[4] = Clip(tmp_g);
out[5] = Clip(tmp_b);
tmp_r = (int32)((mapYc[y2[0]] + mapVcr[v[0]] + 128) >> 8);
tmp_g = (int32)((mapYc[y2[0]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmp_b = (int32)((mapYc[y2[0]] + mapUcb[u[0]] + 128) >> 8);
out2[0] = Clip(tmp_r);
out2[1] = Clip(tmp_g);
out2[2] = Clip(tmp_b);
tmp_r = (int32)((mapYc[y2[1]] + mapVcr[v[0]] + 128) >> 8);
tmp_g = (int32)((mapYc[y2[1]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmp_b = (int32)((mapYc[y2[1]] + mapUcb[u[0]] + 128) >> 8);
out2[3] = Clip(tmp_r);
out2[4] = Clip(tmp_g);
out2[5] = Clip(tmp_b);
out += 6;
out2 += 6;
y1 += 2;
y2 += 2;
u++;
v++;
}
y1 += src_stride_y + src_stride_y - width;
y2 += src_stride_y + src_stride_y - width;
u += src_stride_u - ((width + 1) >> 1);
v += src_stride_v - ((width + 1) >> 1);
out -= dst_stride_frame * 3;
out2 -= dst_stride_frame * 3;
} // end height for
return 0;
}
// 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,
const uint8* src_v, int src_stride_v,
......@@ -175,7 +248,7 @@ int I420ToARGB4444(const uint8* src_y, int src_stride_y,
return 0;
}
// TODO(fbarchard): rewrite with row functions
int I420ToRGB565(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
......@@ -254,7 +327,7 @@ int I420ToRGB565(const uint8* src_y, int src_stride_y,
return 0;
}
// TODO(fbarchard): rewrite with row functions
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,
......
......@@ -57,7 +57,6 @@ int ConvertFromI420(const uint8* y, int y_stride,
dst_sample, width * 3,
width, height);
break;
#ifdef HAVEI420TOBAYER
case FOURCC_RAW:
I420ToRAW(y, y_stride,
u, u_stride,
......@@ -65,7 +64,6 @@ int ConvertFromI420(const uint8* y, int y_stride,
dst_sample, width * 3,
width, height);
break;
#endif
case FOURCC_ARGB:
I420ToARGB(y, y_stride,
u, u_stride,
......@@ -99,15 +97,11 @@ int ConvertFromI420(const uint8* y, int y_stride,
width, height);
break;
#endif
#ifdef HAVEI420TOI400
case FOURCC_I400:
I420ToI400(y, y_stride,
u, u_stride,
v, v_stride,
dst_sample, width,
width, height);
I400Copy(y, y_stride,
dst_sample, width,
width, height);
break;
#endif
// Triplanar formats
case FOURCC_I420:
case FOURCC_YV12: {
......@@ -152,7 +146,6 @@ int ConvertFromI420(const uint8* y, int y_stride,
width, height);
break;
}
#ifdef HAVEI420TOI444
case FOURCC_I444:
case FOURCC_YV24: {
uint8* dst_u;
......@@ -173,7 +166,7 @@ int ConvertFromI420(const uint8* y, int y_stride,
width, height);
break;
}
#endif
// Formats not supported - MJPG, biplanar, some rgb formats.
default:
return -1; // unknown fourcc - return failure code.
......
......@@ -557,7 +557,6 @@ void ScaleRowDown2Int_SSE2(const uint8* src_ptr, int src_stride,
void ScaleRowDown2Int_C(const uint8* src_ptr, int src_stride,
uint8* dst_ptr, int dst_width);
// Half Width and Height
int I444ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
......@@ -623,6 +622,53 @@ int I444ToI420(const uint8* src_y, int src_stride_y,
return 0;
}
// use Bilinear for upsampling chroma
void ScalePlaneBilinear(int src_width, int src_height,
int dst_width, int dst_height,
int src_stride, int dst_stride,
const uint8* src_ptr, uint8* dst_ptr);
int I420ToI444(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_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_y = dst_y + (height - 1) * dst_stride_y;
dst_u = dst_u + (height - 1) * dst_stride_u;
dst_v = dst_v + (height - 1) * dst_stride_v;
dst_stride_y = -dst_stride_y;
dst_stride_u = -dst_stride_u;
dst_stride_v = -dst_stride_v;
}
// Copy Y plane
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
// Upsample U plane.
ScalePlaneBilinear(halfwidth, halfheight,
width, height,
src_stride_u,
dst_stride_u,
src_u, dst_u);
// Upsample V plane.
ScalePlaneBilinear(halfwidth, halfheight,
width, height,
src_stride_v,
dst_stride_v,
src_v, dst_v);
return 0;
}
static void CopyPlane2(const uint8* src, int src_stride_0, int src_stride_1,
uint8* dst, int dst_stride_frame,
int width, int height) {
......@@ -2089,6 +2135,20 @@ int I400ToI420(const uint8* src_y, int src_stride_y,
return 0;
}
// Copy to I400. Source can be I420,422,444,400,NV12,NV21
int I400Copy(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
int width, int height) {
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_y = src_y + (height - 1) * src_stride_y;
src_stride_y = -src_stride_y;
}
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
return 0;
}
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
......
......@@ -3449,10 +3449,10 @@ static void ScalePlaneBilinearSimple(int src_width, int src_height,
* Scale plane to/from any dimensions, with bilinear
* interpolation.
*/
static void ScalePlaneBilinear(int src_width, int src_height,
int dst_width, int dst_height,
int src_stride, int dst_stride,
const uint8* src_ptr, uint8* dst_ptr) {
void ScalePlaneBilinear(int src_width, int src_height,
int dst_width, int dst_height,
int src_stride, int dst_stride,
const uint8* src_ptr, uint8* dst_ptr) {
assert(dst_width > 0);
assert(dst_height > 0);
int dy = (src_height << 16) / dst_height;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment