提交 2a877875 编写于 作者: F Fabrice Bellard

added missing formats in all functions - added monoblack, monowhite and gray8...

added missing formats in all functions - added monoblack, monowhite and gray8 support for most conversions

Originally committed as revision 1435 to svn://svn.ffmpeg.org/ffmpeg/trunk
上级 5915a6dc
...@@ -129,6 +129,103 @@ const char *avcodec_get_pix_fmt_name(int pix_fmt) ...@@ -129,6 +129,103 @@ const char *avcodec_get_pix_fmt_name(int pix_fmt)
return pix_fmt_info[pix_fmt].name; return pix_fmt_info[pix_fmt].name;
} }
/* Picture field are filled with 'ptr' addresses. Also return size */
int avpicture_fill(AVPicture *picture, UINT8 *ptr,
int pix_fmt, int width, int height)
{
int size;
size = width * height;
switch(pix_fmt) {
case PIX_FMT_YUV420P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 4;
picture->linesize[0] = width;
picture->linesize[1] = width / 2;
picture->linesize[2] = width / 2;
return (size * 3) / 2;
case PIX_FMT_RGB24:
case PIX_FMT_BGR24:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = width * 3;
return size * 3;
case PIX_FMT_YUV422P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 2;
picture->linesize[0] = width;
picture->linesize[1] = width / 2;
picture->linesize[2] = width / 2;
return (size * 2);
case PIX_FMT_YUV444P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size;
picture->linesize[0] = width;
picture->linesize[1] = width;
picture->linesize[2] = width;
return size * 3;
case PIX_FMT_RGBA32:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = width * 4;
return size * 4;
case PIX_FMT_YUV410P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 16;
picture->linesize[0] = width;
picture->linesize[1] = width / 4;
picture->linesize[2] = width / 4;
return size + (size / 8);
case PIX_FMT_YUV411P:
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 4;
picture->linesize[0] = width;
picture->linesize[1] = width / 4;
picture->linesize[2] = width / 4;
return size + (size / 2);
case PIX_FMT_RGB555:
case PIX_FMT_RGB565:
case PIX_FMT_YUV422:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = width * 2;
return size * 2;
case PIX_FMT_GRAY8:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = width;
return size;
case PIX_FMT_MONOWHITE:
case PIX_FMT_MONOBLACK:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->linesize[0] = (width + 7) >> 3;
return picture->linesize[0] * height;
default:
picture->data[0] = NULL;
picture->data[1] = NULL;
picture->data[2] = NULL;
return -1;
}
}
int avpicture_get_size(int pix_fmt, int width, int height)
{
AVPicture dummy_pict;
return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
}
/* XXX: totally non optimized */ /* XXX: totally non optimized */
static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src, static void yuv422_to_yuv420p(AVPicture *dst, AVPicture *src,
...@@ -720,8 +817,8 @@ static void gray_to_rgb24(AVPicture *dst, AVPicture *src, ...@@ -720,8 +817,8 @@ static void gray_to_rgb24(AVPicture *dst, AVPicture *src,
} }
} }
static void monowhite_to_rgb24(AVPicture *dst, AVPicture *src, static void mono_to_gray(AVPicture *dst, AVPicture *src,
int width, int height) int width, int height, int xor_mask)
{ {
const unsigned char *p; const unsigned char *p;
unsigned char *q; unsigned char *q;
...@@ -732,26 +829,27 @@ static void monowhite_to_rgb24(AVPicture *dst, AVPicture *src, ...@@ -732,26 +829,27 @@ static void monowhite_to_rgb24(AVPicture *dst, AVPicture *src,
src_wrap = src->linesize[0] - ((width + 7) >> 3); src_wrap = src->linesize[0] - ((width + 7) >> 3);
q = dst->data[0]; q = dst->data[0];
dst_wrap = dst->linesize[0] - 3 * width; dst_wrap = dst->linesize[0] - width;
for(y=0;y<height;y++) { for(y=0;y<height;y++) {
w = width; w = width;
while (w >= 8) { while (w >= 8) {
v = *p++ ^ 0xff; v = *p++ ^ xor_mask;
q[0] = q[1] = q[2] = -(v >> 7); q += 3; q[0] = -(v >> 7);
q[0] = q[1] = q[2] = -((v >> 6) & 1); q += 3; q[1] = -((v >> 6) & 1);
q[0] = q[1] = q[2] = -((v >> 5) & 1); q += 3; q[2] = -((v >> 5) & 1);
q[0] = q[1] = q[2] = -((v >> 4) & 1); q += 3; q[3] = -((v >> 4) & 1);
q[0] = q[1] = q[2] = -((v >> 3) & 1); q += 3; q[4] = -((v >> 3) & 1);
q[0] = q[1] = q[2] = -((v >> 2) & 1); q += 3; q[5] = -((v >> 2) & 1);
q[0] = q[1] = q[2] = -((v >> 1) & 1); q += 3; q[6] = -((v >> 1) & 1);
q[0] = q[1] = q[2] = -((v >> 0) & 1); q += 3; q[7] = -((v >> 0) & 1);
w -= 8; w -= 8;
q += 8;
} }
if (w > 0) { if (w > 0) {
v = *p++ ^ 0xff; v = *p++ ^ xor_mask;
do { do {
q[0] = q[1] = q[2] = -((v >> 7) & 1); q += 3; q[0] = -((v >> 7) & 1);
q++;
v <<= 1; v <<= 1;
} while (--w); } while (--w);
} }
...@@ -760,46 +858,75 @@ static void monowhite_to_rgb24(AVPicture *dst, AVPicture *src, ...@@ -760,46 +858,75 @@ static void monowhite_to_rgb24(AVPicture *dst, AVPicture *src,
} }
} }
static void monoblack_to_rgb24(AVPicture *dst, AVPicture *src, static void monowhite_to_gray(AVPicture *dst, AVPicture *src,
int width, int height) int width, int height)
{ {
const unsigned char *p; mono_to_gray(dst, src, width, height, 0xff);
unsigned char *q; }
int v, dst_wrap, src_wrap;
int y, w;
p = src->data[0]; static void monoblack_to_gray(AVPicture *dst, AVPicture *src,
src_wrap = src->linesize[0] - ((width + 7) >> 3); int width, int height)
{
mono_to_gray(dst, src, width, height, 0x00);
}
q = dst->data[0]; static void gray_to_mono(AVPicture *dst, AVPicture *src,
dst_wrap = dst->linesize[0] - 3 * width; int width, int height, int xor_mask)
{
int n;
const UINT8 *s;
UINT8 *d;
int j, b, v, n1, src_wrap, dst_wrap, y;
s = src->data[0];
src_wrap = src->linesize[0] - width;
d = dst->data[0];
dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
printf("%d %d\n", width, height);
for(y=0;y<height;y++) { for(y=0;y<height;y++) {
w = width; n = width;
while (w >= 8) { while (n >= 8) {
v = *p++; v = 0;
q[0] = q[1] = q[2] = -(v >> 7); q += 3; for(j=0;j<8;j++) {
q[0] = q[1] = q[2] = -((v >> 6) & 1); q += 3; b = s[0];
q[0] = q[1] = q[2] = -((v >> 5) & 1); q += 3; s++;
q[0] = q[1] = q[2] = -((v >> 4) & 1); q += 3; v = (v << 1) | (b >> 7);
q[0] = q[1] = q[2] = -((v >> 3) & 1); q += 3; }
q[0] = q[1] = q[2] = -((v >> 2) & 1); q += 3; d[0] = v ^ xor_mask;
q[0] = q[1] = q[2] = -((v >> 1) & 1); q += 3; d++;
q[0] = q[1] = q[2] = -((v >> 0) & 1); q += 3; n -= 8;
w -= 8;
} }
if (w > 0) { if (n > 0) {
v = *p++; n1 = n;
do { v = 0;
q[0] = q[1] = q[2] = -((v >> 7) & 1); q += 3; while (n > 0) {
v <<= 1; b = s[0];
} while (--w); s++;
v = (v << 1) | (b >> 7);
n--;
}
d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
d++;
} }
p += src_wrap; s += src_wrap;
q += dst_wrap; d += dst_wrap;
} }
} }
static void gray_to_monowhite(AVPicture *dst, AVPicture *src,
int width, int height)
{
gray_to_mono(dst, src, width, height, 0xff);
}
static void gray_to_monoblack(AVPicture *dst, AVPicture *src,
int width, int height)
{
gray_to_mono(dst, src, width, height, 0x00);
}
typedef struct ConvertEntry { typedef struct ConvertEntry {
void (*convert)(AVPicture *dst, AVPicture *src, int width, int height); void (*convert)(AVPicture *dst, AVPicture *src, int width, int height);
} ConvertEntry; } ConvertEntry;
...@@ -887,15 +1014,21 @@ static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = { ...@@ -887,15 +1014,21 @@ static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
[PIX_FMT_RGB24] = { [PIX_FMT_RGB24] = {
convert: gray_to_rgb24 convert: gray_to_rgb24
}, },
[PIX_FMT_MONOWHITE] = {
convert: gray_to_monowhite
},
[PIX_FMT_MONOBLACK] = {
convert: gray_to_monoblack
},
}, },
[PIX_FMT_MONOWHITE] = { [PIX_FMT_MONOWHITE] = {
[PIX_FMT_RGB24] = { [PIX_FMT_GRAY8] = {
convert: monowhite_to_rgb24 convert: monowhite_to_gray
}, },
}, },
[PIX_FMT_MONOBLACK] = { [PIX_FMT_MONOBLACK] = {
[PIX_FMT_RGB24] = { [PIX_FMT_GRAY8] = {
convert: monoblack_to_rgb24 convert: monoblack_to_gray
}, },
}, },
}; };
...@@ -929,7 +1062,7 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, ...@@ -929,7 +1062,7 @@ int img_convert(AVPicture *dst, int dst_pix_fmt,
AVPicture *src, int src_pix_fmt, AVPicture *src, int src_pix_fmt,
int src_width, int src_height) int src_width, int src_height)
{ {
int i, ret, dst_width, dst_height; int i, ret, dst_width, dst_height, int_pix_fmt;
PixFmtInfo *src_pix, *dst_pix; PixFmtInfo *src_pix, *dst_pix;
ConvertEntry *ce; ConvertEntry *ce;
AVPicture tmp1, *tmp = &tmp1; AVPicture tmp1, *tmp = &tmp1;
...@@ -946,6 +1079,7 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, ...@@ -946,6 +1079,7 @@ int img_convert(AVPicture *dst, int dst_pix_fmt,
dst_pix = &pix_fmt_info[dst_pix_fmt]; dst_pix = &pix_fmt_info[dst_pix_fmt];
src_pix = &pix_fmt_info[src_pix_fmt]; src_pix = &pix_fmt_info[src_pix_fmt];
if (src_pix_fmt == dst_pix_fmt) { if (src_pix_fmt == dst_pix_fmt) {
/* XXX: incorrect */
/* same format: just copy */ /* same format: just copy */
for(i = 0; i < dst_pix->nb_components; i++) { for(i = 0; i < dst_pix->nb_components; i++) {
int w, h; int w, h;
...@@ -969,24 +1103,6 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, ...@@ -969,24 +1103,6 @@ int img_convert(AVPicture *dst, int dst_pix_fmt,
return 0; return 0;
} }
/* if both format are not YUV, try to use RGB24 as common
format */
if (!dst_pix->is_yuv && !src_pix->is_yuv) {
if (avpicture_alloc(tmp, PIX_FMT_RGB24, dst_width, dst_height) < 0)
return -1;
ret = -1;
if (img_convert(tmp, PIX_FMT_RGB24,
src, src_pix_fmt, src_width, src_height) < 0)
goto fail1;
if (img_convert(dst, dst_pix_fmt,
tmp, PIX_FMT_RGB24, dst_width, dst_height) < 0)
goto fail1;
ret = 0;
fail1:
avpicture_free(tmp);
return ret;
}
/* gray to YUV */ /* gray to YUV */
if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) { if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) {
int w, h, y; int w, h, y;
...@@ -1002,8 +1118,8 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, ...@@ -1002,8 +1118,8 @@ int img_convert(AVPicture *dst, int dst_pix_fmt,
h >>= dst_pix->y_chroma_shift; h >>= dst_pix->y_chroma_shift;
for(i = 1; i <= 2; i++) { for(i = 1; i <= 2; i++) {
d = dst->data[i]; d = dst->data[i];
for(y = 0; y<h; y++) { for(y = 0; y< h; y++) {
memset(d, 128, 0); memset(d, 128, w);
d += dst->linesize[i]; d += dst->linesize[i];
} }
} }
...@@ -1063,9 +1179,28 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, ...@@ -1063,9 +1179,28 @@ int img_convert(AVPicture *dst, int dst_pix_fmt,
w, h); w, h);
} }
/* cannot convert yet */ /* try to use an intermediate format */
if (src_pix_fmt == PIX_FMT_MONOWHITE ||
return -1; src_pix_fmt == PIX_FMT_MONOBLACK ||
dst_pix_fmt == PIX_FMT_MONOWHITE ||
dst_pix_fmt == PIX_FMT_MONOBLACK) {
int_pix_fmt = PIX_FMT_GRAY8;
} else {
int_pix_fmt = PIX_FMT_RGB24;
}
if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
return -1;
ret = -1;
if (img_convert(tmp, int_pix_fmt,
src, src_pix_fmt, src_width, src_height) < 0)
goto fail1;
if (img_convert(dst, dst_pix_fmt,
tmp, int_pix_fmt, dst_width, dst_height) < 0)
goto fail1;
ret = 0;
fail1:
avpicture_free(tmp);
return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册