mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
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
This commit is contained in:
parent
52f5bb91be
commit
c9911bcba1
@ -1,6 +1,6 @@
|
||||
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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user