X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fimgconvert.c;h=9826a6a35882be3c97d561450658918c9df6dfd4;hb=b07781b6e4f6267f20aec4e7f1d390ddb223af46;hp=952ddcb566f8c44c9b129fe259c6a1888a3a3d3a;hpb=369122dd775c906be06b9c96f03eaedaedb91658;p=ffmpeg diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index 952ddcb566f..9826a6a3588 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -1,6 +1,6 @@ /* * Misc image conversion routines - * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. + * Copyright (c) 2001, 2002, 2003 Fabrice Bellard * * This file is part of FFmpeg. * @@ -20,7 +20,7 @@ */ /** - * @file imgconvert.c + * @file libavcodec/imgconvert.c * misc image conversion routines */ @@ -34,7 +34,7 @@ #include "dsputil.h" #include "colorspace.h" -#ifdef HAVE_MMX +#if HAVE_MMX #include "x86/mmx.h" #include "x86/dsputil_mmx.h" #endif @@ -57,6 +57,7 @@ typedef struct PixFmtInfo { uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */ uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */ uint8_t is_alpha : 1; /**< true if alpha can be specified */ + uint8_t is_hwaccel : 1; /**< true if this is an HW accelerated format */ uint8_t x_chroma_shift; /**< X chroma subsampling factor is 2 ^ shift */ uint8_t y_chroma_shift; /**< Y chroma subsampling factor is 2 ^ shift */ uint8_t depth; /**< bit depth of the color components */ @@ -129,6 +130,55 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 1, }, + [PIX_FMT_YUV420P16LE] = { + .name = "yuv420p16le", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 16, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_YUV422P16LE] = { + .name = "yuv422p16le", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 16, + .x_chroma_shift = 1, .y_chroma_shift = 0, + }, + [PIX_FMT_YUV444P16LE] = { + .name = "yuv444p16le", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 16, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_YUV420P16BE] = { + .name = "yuv420p16be", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 16, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_YUV422P16BE] = { + .name = "yuv422p16be", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 16, + .x_chroma_shift = 1, .y_chroma_shift = 0, + }, + [PIX_FMT_YUV444P16BE] = { + .name = "yuv444p16be", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 16, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + /* YUV formats with alpha plane */ [PIX_FMT_YUVA420P] = { @@ -191,24 +241,56 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, - [PIX_FMT_RGB32] = { - .name = "rgb32", + [PIX_FMT_ARGB] = { + .name = "argb", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, - [PIX_FMT_RGB565] = { - .name = "rgb565", + [PIX_FMT_RGB48BE] = { + .name = "rgb48be", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 16, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_RGB48LE] = { + .name = "rgb48le", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 16, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_RGB565BE] = { + .name = "rgb565be", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 5, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_RGB565LE] = { + .name = "rgb565le", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 5, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_RGB555BE] = { + .name = "rgb555be", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, - [PIX_FMT_RGB555] = { - .name = "rgb555", + [PIX_FMT_RGB555LE] = { + .name = "rgb555le", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, @@ -263,12 +345,36 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { }, [PIX_FMT_XVMC_MPEG2_MC] = { .name = "xvmcmc", + .is_hwaccel = 1, }, [PIX_FMT_XVMC_MPEG2_IDCT] = { .name = "xvmcidct", + .is_hwaccel = 1, + }, + [PIX_FMT_VDPAU_MPEG1] = { + .name = "vdpau_mpeg1", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_VDPAU_MPEG2] = { + .name = "vdpau_mpeg2", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_VDPAU_H264] = { .name = "vdpau_h264", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_VDPAU_WMV3] = { + .name = "vdpau_wmv3", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_VDPAU_VC1] = { + .name = "vdpau_vc1", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_UYYVYY411] = { .name = "uyyvyy411", @@ -278,24 +384,40 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { .depth = 8, .x_chroma_shift = 2, .y_chroma_shift = 0, }, - [PIX_FMT_BGR32] = { - .name = "bgr32", + [PIX_FMT_ABGR] = { + .name = "abgr", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, - [PIX_FMT_BGR565] = { - .name = "bgr565", + [PIX_FMT_BGR565BE] = { + .name = "bgr565be", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 5, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_BGR565LE] = { + .name = "bgr565le", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 5, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_BGR555BE] = { + .name = "bgr555be", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, - [PIX_FMT_BGR555] = { - .name = "bgr555", + [PIX_FMT_BGR555LE] = { + .name = "bgr555le", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, @@ -367,31 +489,48 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { .x_chroma_shift = 1, .y_chroma_shift = 1, }, - [PIX_FMT_BGR32_1] = { - .name = "bgr32_1", + [PIX_FMT_BGRA] = { + .name = "bgra", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, - [PIX_FMT_RGB32_1] = { - .name = "rgb32_1", + [PIX_FMT_RGBA] = { + .name = "rgba", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, + + /* VA API formats */ + [PIX_FMT_VAAPI_MOCO] = { + .name = "vaapi_moco", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_VAAPI_IDCT] = { + .name = "vaapi_idct", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_VAAPI_VLD] = { + .name = "vaapi_vld", + .is_hwaccel = 1, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, }; -void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) +void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift) { *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; } -const char *avcodec_get_pix_fmt_name(int pix_fmt) +const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt) { if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) return NULL; @@ -399,17 +538,41 @@ const char *avcodec_get_pix_fmt_name(int pix_fmt) return pix_fmt_info[pix_fmt].name; } -enum PixelFormat avcodec_get_pix_fmt(const char* name) +static enum PixelFormat avcodec_get_pix_fmt_internal(const char *name) { int i; for (i=0; i < PIX_FMT_NB; i++) - if (!strcmp(pix_fmt_info[i].name, name)) - return i; + if (pix_fmt_info[i].name && !strcmp(pix_fmt_info[i].name, name)) + return i; return PIX_FMT_NONE; } -void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt) +#if HAVE_BIGENDIAN +# define X_NE(be, le) be +#else +# define X_NE(be, le) le +#endif + +enum PixelFormat avcodec_get_pix_fmt(const char *name) +{ + enum PixelFormat pix_fmt; + + if (!strcmp(name, "rgb32")) + name = X_NE("argb", "bgra"); + else if (!strcmp(name, "bgr32")) + name = X_NE("abgr", "rgba"); + + pix_fmt = avcodec_get_pix_fmt_internal(name); + if (pix_fmt == PIX_FMT_NONE) { + char name2[32]; + snprintf(name2, sizeof(name2), "%s%s", name, X_NE("be", "le")); + pix_fmt = avcodec_get_pix_fmt_internal(name2); + } + return pix_fmt; +} + +void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt) { /* print header */ if (pix_fmt < 0) @@ -422,7 +585,7 @@ void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt) char is_alpha_char= info.is_alpha ? 'y' : 'n'; snprintf (buf, buf_size, - "%-10s" " %1d " " %2d " " %c ", + "%-11s %5d %9d %6c", info.name, info.nb_channels, info.depth, @@ -431,7 +594,51 @@ void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt) } } -int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width) +int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt) +{ + return pix_fmt_info[pix_fmt].is_hwaccel; +} + +int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){ + int i; + + for(i=0; i<256; i++){ + int r,g,b; + + switch(pix_fmt) { + case PIX_FMT_RGB8: + r= (i>>5 )*36; + g= ((i>>2)&7)*36; + b= (i&3 )*85; + break; + case PIX_FMT_BGR8: + b= (i>>6 )*85; + g= ((i>>3)&7)*36; + r= (i&7 )*36; + break; + case PIX_FMT_RGB4_BYTE: + r= (i>>3 )*255; + g= ((i>>1)&3)*85; + b= (i&1 )*255; + break; + case PIX_FMT_BGR4_BYTE: + b= (i>>3 )*255; + g= ((i>>1)&3)*85; + r= (i&1 )*255; + break; + case PIX_FMT_GRAY8: + r=b=g= i; + break; + default: + return -1; + } + pal[i] = b + (g<<8) + (r<<16); + } + + return 0; +} + +int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width) { int w2; const PixFmtInfo *pinfo; @@ -455,6 +662,17 @@ int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width) picture->linesize[1] = w2; picture->linesize[2] = w2; break; + case PIX_FMT_YUV420P16LE: + case PIX_FMT_YUV422P16LE: + case PIX_FMT_YUV444P16LE: + case PIX_FMT_YUV420P16BE: + case PIX_FMT_YUV422P16BE: + case PIX_FMT_YUV444P16BE: + w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; + picture->linesize[0] = 2*width; + picture->linesize[1] = 2*w2; + picture->linesize[2] = 2*w2; + break; case PIX_FMT_YUVA420P: w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; picture->linesize[0] = width; @@ -472,18 +690,26 @@ int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width) case PIX_FMT_BGR24: picture->linesize[0] = width * 3; break; - case PIX_FMT_RGB32: - case PIX_FMT_BGR32: - case PIX_FMT_RGB32_1: - case PIX_FMT_BGR32_1: + case PIX_FMT_ARGB: + case PIX_FMT_ABGR: + case PIX_FMT_RGBA: + case PIX_FMT_BGRA: picture->linesize[0] = width * 4; break; + case PIX_FMT_RGB48BE: + case PIX_FMT_RGB48LE: + picture->linesize[0] = width * 6; + break; case PIX_FMT_GRAY16BE: case PIX_FMT_GRAY16LE: - case PIX_FMT_BGR555: - case PIX_FMT_BGR565: - case PIX_FMT_RGB555: - case PIX_FMT_RGB565: + case PIX_FMT_BGR555BE: + case PIX_FMT_BGR555LE: + case PIX_FMT_BGR565BE: + case PIX_FMT_BGR565LE: + case PIX_FMT_RGB555BE: + case PIX_FMT_RGB555LE: + case PIX_FMT_RGB565BE: + case PIX_FMT_RGB565LE: case PIX_FMT_YUYV422: picture->linesize[0] = width * 2; break; @@ -493,13 +719,6 @@ int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width) case PIX_FMT_UYYVYY411: picture->linesize[0] = width + width/2; break; - case PIX_FMT_RGB8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB4_BYTE: - case PIX_FMT_BGR4_BYTE: - case PIX_FMT_GRAY8: - picture->linesize[0] = width; - break; case PIX_FMT_RGB4: case PIX_FMT_BGR4: picture->linesize[0] = width / 2; @@ -509,8 +728,12 @@ int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width) picture->linesize[0] = (width + 7) >> 3; break; case PIX_FMT_PAL8: + case PIX_FMT_RGB8: + case PIX_FMT_BGR8: + case PIX_FMT_RGB4_BYTE: + case PIX_FMT_BGR4_BYTE: + case PIX_FMT_GRAY8: picture->linesize[0] = width; - picture->linesize[1] = 4; break; default: return -1; @@ -518,7 +741,7 @@ int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width) return 0; } -int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, +int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, int height) { int size, h2, size2; @@ -537,6 +760,12 @@ int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, case PIX_FMT_YUVJ422P: case PIX_FMT_YUVJ444P: case PIX_FMT_YUVJ440P: + case PIX_FMT_YUV420P16LE: + case PIX_FMT_YUV422P16LE: + case PIX_FMT_YUV444P16LE: + case PIX_FMT_YUV420P16BE: + case PIX_FMT_YUV422P16BE: + case PIX_FMT_YUV444P16BE: h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; size2 = picture->linesize[1] * h2; picture->data[0] = ptr; @@ -563,24 +792,25 @@ int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, return size + 2 * size2; case PIX_FMT_RGB24: case PIX_FMT_BGR24: - case PIX_FMT_RGB32: - case PIX_FMT_BGR32: - case PIX_FMT_RGB32_1: - case PIX_FMT_BGR32_1: + case PIX_FMT_ARGB: + case PIX_FMT_ABGR: + case PIX_FMT_RGBA: + case PIX_FMT_BGRA: + case PIX_FMT_RGB48BE: + case PIX_FMT_RGB48LE: case PIX_FMT_GRAY16BE: case PIX_FMT_GRAY16LE: - case PIX_FMT_BGR555: - case PIX_FMT_BGR565: - case PIX_FMT_RGB555: - case PIX_FMT_RGB565: + case PIX_FMT_BGR555BE: + case PIX_FMT_BGR555LE: + case PIX_FMT_BGR565BE: + case PIX_FMT_BGR565LE: + case PIX_FMT_RGB555BE: + case PIX_FMT_RGB555LE: + case PIX_FMT_RGB565BE: + case PIX_FMT_RGB565LE: case PIX_FMT_YUYV422: case PIX_FMT_UYVY422: case PIX_FMT_UYYVYY411: - case PIX_FMT_RGB8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB4_BYTE: - case PIX_FMT_BGR4_BYTE: - case PIX_FMT_GRAY8: case PIX_FMT_RGB4: case PIX_FMT_BGR4: case PIX_FMT_MONOWHITE: @@ -591,6 +821,11 @@ int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, picture->data[3] = NULL; return size; case PIX_FMT_PAL8: + case PIX_FMT_RGB8: + case PIX_FMT_BGR8: + case PIX_FMT_RGB4_BYTE: + case PIX_FMT_BGR4_BYTE: + case PIX_FMT_GRAY8: size2 = (size + 3) & ~3; picture->data[0] = ptr; picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */ @@ -607,7 +842,7 @@ int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, } int avpicture_fill(AVPicture *picture, uint8_t *ptr, - int pix_fmt, int width, int height) + enum PixelFormat pix_fmt, int width, int height) { if(avcodec_check_dimensions(NULL, width, height)) @@ -619,11 +854,11 @@ int avpicture_fill(AVPicture *picture, uint8_t *ptr, return ff_fill_pointer(picture, ptr, pix_fmt, height); } -int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, +int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, unsigned char *dest, int dest_size) { const PixFmtInfo* pf = &pix_fmt_info[pix_fmt]; - int i, j, w, h, data_planes; + int i, j, w, ow, h, oh, data_planes; const unsigned char* s; int size = avpicture_get_size(pix_fmt, width, height); @@ -633,10 +868,14 @@ int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) { if (pix_fmt == PIX_FMT_YUYV422 || pix_fmt == PIX_FMT_UYVY422 || - pix_fmt == PIX_FMT_BGR565 || - pix_fmt == PIX_FMT_BGR555 || - pix_fmt == PIX_FMT_RGB565 || - pix_fmt == PIX_FMT_RGB555) + pix_fmt == PIX_FMT_BGR565BE || + pix_fmt == PIX_FMT_BGR565LE || + pix_fmt == PIX_FMT_BGR555BE || + pix_fmt == PIX_FMT_BGR555LE || + pix_fmt == PIX_FMT_RGB565BE || + pix_fmt == PIX_FMT_RGB565LE || + pix_fmt == PIX_FMT_RGB555BE || + pix_fmt == PIX_FMT_RGB555LE) w = width * 2; else if (pix_fmt == PIX_FMT_UYYVYY411) w = width + width/2; @@ -653,10 +892,16 @@ int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, h = height; } + ow = w; + oh = h; + for (i=0; i> pf->x_chroma_shift; + w = ((width >> pf->x_chroma_shift) * pf->depth + 7) / 8; h = height >> pf->y_chroma_shift; + } else if (i == 3) { + w = ow; + h = oh; } s = src->data[i]; for(j=0; jdepth < ps->depth || - (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565)) + ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE) && + (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE))) loss |= FF_LOSS_DEPTH; if (pf->x_chroma_shift > ps->x_chroma_shift || pf->y_chroma_shift > ps->y_chroma_shift) @@ -733,7 +989,7 @@ int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, return loss; } -static int avg_bits_per_pixel(int pix_fmt) +static int avg_bits_per_pixel(enum PixelFormat pix_fmt) { int bits; const PixFmtInfo *pf; @@ -744,10 +1000,14 @@ static int avg_bits_per_pixel(int pix_fmt) switch(pix_fmt) { case PIX_FMT_YUYV422: case PIX_FMT_UYVY422: - case PIX_FMT_RGB565: - case PIX_FMT_RGB555: - case PIX_FMT_BGR565: - case PIX_FMT_BGR555: + case PIX_FMT_RGB565BE: + case PIX_FMT_RGB565LE: + case PIX_FMT_RGB555BE: + case PIX_FMT_RGB555LE: + case PIX_FMT_BGR565BE: + case PIX_FMT_BGR565LE: + case PIX_FMT_BGR555BE: + case PIX_FMT_BGR555LE: bits = 16; break; case PIX_FMT_UYYVYY411: @@ -776,12 +1036,13 @@ static int avg_bits_per_pixel(int pix_fmt) return bits; } -static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask, - int src_pix_fmt, +static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask, + enum PixelFormat src_pix_fmt, int has_alpha, int loss_mask) { - int dist, i, loss, min_dist, dst_pix_fmt; + int dist, i, loss, min_dist; + enum PixelFormat dst_pix_fmt; /* find exact color match with smallest size */ dst_pix_fmt = -1; @@ -801,10 +1062,11 @@ static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask, return dst_pix_fmt; } -int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt, +enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) { - int dst_pix_fmt, loss_mask, i; + enum PixelFormat dst_pix_fmt; + int loss_mask, i; static const int loss_mask_order[] = { ~0, /* no loss first */ ~FF_LOSS_ALPHA, @@ -857,10 +1119,14 @@ int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane) switch(pix_fmt) { case PIX_FMT_YUYV422: case PIX_FMT_UYVY422: - case PIX_FMT_RGB565: - case PIX_FMT_RGB555: - case PIX_FMT_BGR565: - case PIX_FMT_BGR555: + case PIX_FMT_RGB565BE: + case PIX_FMT_RGB565LE: + case PIX_FMT_RGB555BE: + case PIX_FMT_RGB555LE: + case PIX_FMT_BGR565BE: + case PIX_FMT_BGR565LE: + case PIX_FMT_BGR555BE: + case PIX_FMT_BGR555LE: bits = 16; break; case PIX_FMT_UYYVYY411: @@ -888,12 +1154,11 @@ int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane) } void av_picture_copy(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height) + enum PixelFormat pix_fmt, int width, int height) { int i; const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; - pf = &pix_fmt_info[pix_fmt]; switch(pf->pixel_type) { case FF_PIXEL_PACKED: case FF_PIXEL_PLANAR: @@ -921,357 +1186,6 @@ void av_picture_copy(AVPicture *dst, const AVPicture *src, } } -/* XXX: totally non optimized */ - -static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - - for(;height >= 1; height -= 2) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[0]; - cb[0] = p[1]; - lum[1] = p[2]; - cr[0] = p[3]; - p += 4; - lum += 2; - cb++; - cr++; - } - if (w) { - lum[0] = p[0]; - cb[0] = p[1]; - cr[0] = p[3]; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - if (height>1) { - p = p1; - lum = lum1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[0]; - lum[1] = p[2]; - p += 4; - lum += 2; - } - if (w) { - lum[0] = p[0]; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - } - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - -static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - - for(;height >= 1; height -= 2) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[1]; - cb[0] = p[0]; - lum[1] = p[3]; - cr[0] = p[2]; - p += 4; - lum += 2; - cb++; - cr++; - } - if (w) { - lum[0] = p[1]; - cb[0] = p[0]; - cr[0] = p[2]; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - if (height>1) { - p = p1; - lum = lum1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[1]; - lum[1] = p[3]; - p += 4; - lum += 2; - } - if (w) { - lum[0] = p[1]; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - } - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - - -static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[1]; - cb[0] = p[0]; - lum[1] = p[3]; - cr[0] = p[2]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - - -static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[0]; - cb[0] = p[1]; - lum[1] = p[2]; - cr[0] = p[3]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - -static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - uint8_t *p, *p1; - const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = dst->data[0]; - lum1 = src->data[0]; - cb1 = src->data[1]; - cr1 = src->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - p[0] = lum[0]; - p[1] = cb[0]; - p[2] = lum[1]; - p[3] = cr[0]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += dst->linesize[0]; - lum1 += src->linesize[0]; - cb1 += src->linesize[1]; - cr1 += src->linesize[2]; - } -} - -static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - uint8_t *p, *p1; - const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = dst->data[0]; - lum1 = src->data[0]; - cb1 = src->data[1]; - cr1 = src->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - p[1] = lum[0]; - p[0] = cb[0]; - p[3] = lum[1]; - p[2] = cr[0]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += dst->linesize[0]; - lum1 += src->linesize[0]; - cb1 += src->linesize[1]; - cr1 += src->linesize[2]; - } -} - -static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 4; w -= 4) { - cb[0] = p[0]; - lum[0] = p[1]; - lum[1] = p[2]; - cr[0] = p[3]; - lum[2] = p[4]; - lum[3] = p[5]; - p += 6; - lum += 4; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - - -static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - int w, h; - uint8_t *line1, *line2, *linesrc = dst->data[0]; - uint8_t *lum1, *lum2, *lumsrc = src->data[0]; - uint8_t *cb1, *cb2 = src->data[1]; - uint8_t *cr1, *cr2 = src->data[2]; - - for(h = height / 2; h--;) { - line1 = linesrc; - line2 = linesrc + dst->linesize[0]; - - lum1 = lumsrc; - lum2 = lumsrc + src->linesize[0]; - - cb1 = cb2; - cr1 = cr2; - - for(w = width / 2; w--;) { - *line1++ = *lum1++; *line2++ = *lum2++; - *line1++ = *line2++ = *cb1++; - *line1++ = *lum1++; *line2++ = *lum2++; - *line1++ = *line2++ = *cr1++; - } - - linesrc += dst->linesize[0] * 2; - lumsrc += src->linesize[0] * 2; - cb2 += src->linesize[1]; - cr2 += src->linesize[2]; - } -} - -static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - int w, h; - uint8_t *line1, *line2, *linesrc = dst->data[0]; - uint8_t *lum1, *lum2, *lumsrc = src->data[0]; - uint8_t *cb1, *cb2 = src->data[1]; - uint8_t *cr1, *cr2 = src->data[2]; - - for(h = height / 2; h--;) { - line1 = linesrc; - line2 = linesrc + dst->linesize[0]; - - lum1 = lumsrc; - lum2 = lumsrc + src->linesize[0]; - - cb1 = cb2; - cr1 = cr2; - - for(w = width / 2; w--;) { - *line1++ = *line2++ = *cb1++; - *line1++ = *lum1++; *line2++ = *lum2++; - *line1++ = *line2++ = *cr1++; - *line1++ = *lum1++; *line2++ = *lum2++; - } - - linesrc += dst->linesize[0] * 2; - lumsrc += src->linesize[0] * 2; - cb2 += src->linesize[1]; - cr2 += src->linesize[2]; - } -} - /* 2x2 -> 1x1 */ void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, @@ -1358,645 +1272,32 @@ void ff_shrink88(uint8_t *dst, int dst_wrap, } } -/* XXX: add jpeg quantize code */ - -#define TRANSP_INDEX (6*6*6) -/* this is maybe slow, but allows for extensions */ -static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b) +int avpicture_alloc(AVPicture *picture, + enum PixelFormat pix_fmt, int width, int height) { - return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6); -} + int size; + void *ptr; -static void build_rgb_palette(uint8_t *palette, int has_alpha) -{ - uint32_t *pal; - static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff }; - int i, r, g, b; + size = avpicture_fill(picture, NULL, pix_fmt, width, height); + if(size<0) + goto fail; + ptr = av_malloc(size); + if (!ptr) + goto fail; + avpicture_fill(picture, ptr, pix_fmt, width, height); + if(picture->data[1] && !picture->data[2]) + ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt); - pal = (uint32_t *)palette; - i = 0; - for(r = 0; r < 6; r++) { - for(g = 0; g < 6; g++) { - for(b = 0; b < 6; b++) { - pal[i++] = (0xff << 24) | (pal_value[r] << 16) | - (pal_value[g] << 8) | pal_value[b]; - } - } - } - if (has_alpha) - pal[i++] = 0; - while (i < 256) - pal[i++] = 0xff000000; + return 0; + fail: + memset(picture, 0, sizeof(AVPicture)); + return -1; } -/* copy bit n to bits 0 ... n - 1 */ -static inline unsigned int bitcopy_n(unsigned int a, int n) +void avpicture_free(AVPicture *picture) { - int mask; - mask = (1 << n) - 1; - return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask); -} - -/* rgb555 handling */ - -#define RGB_NAME rgb555 - -#define RGB_IN(r, g, b, s)\ -{\ - unsigned int v = ((const uint16_t *)(s))[0];\ - r = bitcopy_n(v >> (10 - 3), 3);\ - g = bitcopy_n(v >> (5 - 3), 3);\ - b = bitcopy_n(v << 3, 3);\ -} - - -#define RGB_OUT(d, r, g, b)\ -{\ - ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\ -} - -#define BPP 2 - -#include "imgconvert_template.c" - -/* rgb565 handling */ - -#define RGB_NAME rgb565 - -#define RGB_IN(r, g, b, s)\ -{\ - unsigned int v = ((const uint16_t *)(s))[0];\ - r = bitcopy_n(v >> (11 - 3), 3);\ - g = bitcopy_n(v >> (5 - 2), 2);\ - b = bitcopy_n(v << 3, 3);\ -} - -#define RGB_OUT(d, r, g, b)\ -{\ - ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\ -} - -#define BPP 2 - -#include "imgconvert_template.c" - -/* bgr24 handling */ - -#define RGB_NAME bgr24 - -#define RGB_IN(r, g, b, s)\ -{\ - b = (s)[0];\ - g = (s)[1];\ - r = (s)[2];\ -} - -#define RGB_OUT(d, r, g, b)\ -{\ - (d)[0] = b;\ - (d)[1] = g;\ - (d)[2] = r;\ -} - -#define BPP 3 - -#include "imgconvert_template.c" - -#undef RGB_IN -#undef RGB_OUT -#undef BPP - -/* rgb24 handling */ - -#define RGB_NAME rgb24 -#define FMT_RGB24 - -#define RGB_IN(r, g, b, s)\ -{\ - r = (s)[0];\ - g = (s)[1];\ - b = (s)[2];\ -} - -#define RGB_OUT(d, r, g, b)\ -{\ - (d)[0] = r;\ - (d)[1] = g;\ - (d)[2] = b;\ -} - -#define BPP 3 - -#include "imgconvert_template.c" - -/* rgb32 handling */ - -#define RGB_NAME rgb32 -#define FMT_RGB32 - -#define RGB_IN(r, g, b, s)\ -{\ - unsigned int v = ((const uint32_t *)(s))[0];\ - r = (v >> 16) & 0xff;\ - g = (v >> 8) & 0xff;\ - b = v & 0xff;\ -} - -#define RGBA_IN(r, g, b, a, s)\ -{\ - unsigned int v = ((const uint32_t *)(s))[0];\ - a = (v >> 24) & 0xff;\ - r = (v >> 16) & 0xff;\ - g = (v >> 8) & 0xff;\ - b = v & 0xff;\ -} - -#define RGBA_OUT(d, r, g, b, a)\ -{\ - ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\ -} - -#define BPP 4 - -#include "imgconvert_template.c" - -static void mono_to_gray(AVPicture *dst, const AVPicture *src, - int width, int height, int xor_mask) -{ - const unsigned char *p; - unsigned char *q; - int v, dst_wrap, src_wrap; - int y, w; - - p = src->data[0]; - src_wrap = src->linesize[0] - ((width + 7) >> 3); - - q = dst->data[0]; - dst_wrap = dst->linesize[0] - width; - for(y=0;y= 8) { - v = *p++ ^ xor_mask; - q[0] = -(v >> 7); - q[1] = -((v >> 6) & 1); - q[2] = -((v >> 5) & 1); - q[3] = -((v >> 4) & 1); - q[4] = -((v >> 3) & 1); - q[5] = -((v >> 2) & 1); - q[6] = -((v >> 1) & 1); - q[7] = -((v >> 0) & 1); - w -= 8; - q += 8; - } - if (w > 0) { - v = *p++ ^ xor_mask; - do { - q[0] = -((v >> 7) & 1); - q++; - v <<= 1; - } while (--w); - } - p += src_wrap; - q += dst_wrap; - } -} - -static void monowhite_to_gray(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - mono_to_gray(dst, src, width, height, 0xff); -} - -static void monoblack_to_gray(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - mono_to_gray(dst, src, width, height, 0x00); -} - -static void gray_to_mono(AVPicture *dst, const AVPicture *src, - int width, int height, int xor_mask) -{ - int n; - const uint8_t *s; - uint8_t *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); - - for(y=0;y= 8) { - v = 0; - for(j=0;j<8;j++) { - b = s[0]; - s++; - v = (v << 1) | (b >> 7); - } - d[0] = v ^ xor_mask; - d++; - n -= 8; - } - if (n > 0) { - n1 = n; - v = 0; - while (n > 0) { - b = s[0]; - s++; - v = (v << 1) | (b >> 7); - n--; - } - d[0] = (v << (8 - (n1 & 7))) ^ xor_mask; - d++; - } - s += src_wrap; - d += dst_wrap; - } -} - -static void gray_to_monowhite(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - gray_to_mono(dst, src, width, height, 0xff); -} - -static void gray_to_monoblack(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - gray_to_mono(dst, src, width, height, 0x00); -} - -static void gray_to_gray16(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - int x, y, src_wrap, dst_wrap; - uint8_t *s, *d; - s = src->data[0]; - src_wrap = src->linesize[0] - width; - d = dst->data[0]; - dst_wrap = dst->linesize[0] - width * 2; - for(y=0; ydata[0]; - src_wrap = src->linesize[0] - width * 2; - d = dst->data[0]; - dst_wrap = dst->linesize[0] - width; - for(y=0; ydata[0]; - src_wrap = (src->linesize[0] - width * 2)/2; - d = (uint16_t*)dst->data[0]; - dst_wrap = (dst->linesize[0] - width * 2)/2; - for(y=0; ydata[0]); + av_free(picture->data[0]); } /* return true if yuv planar */ @@ -2008,7 +1309,7 @@ static inline int is_yuv_planar(const PixFmtInfo *ps) } int av_picture_crop(AVPicture *dst, const AVPicture *src, - int pix_fmt, int top_band, int left_band) + enum PixelFormat pix_fmt, int top_band, int left_band) { int y_shift; int x_shift; @@ -2030,7 +1331,7 @@ int av_picture_crop(AVPicture *dst, const AVPicture *src, } int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, - int pix_fmt, int padtop, int padbottom, int padleft, int padright, + enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright, int *color) { uint8_t *optr; @@ -2089,528 +1390,6 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, return 0; } -#ifndef CONFIG_SWSCALE -static uint8_t y_ccir_to_jpeg[256]; -static uint8_t y_jpeg_to_ccir[256]; -static uint8_t c_ccir_to_jpeg[256]; -static uint8_t c_jpeg_to_ccir[256]; - -/* init various conversion tables */ -static void img_convert_init(void) -{ - int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - for(i = 0;i < 256; i++) { - y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i); - y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i); - c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i); - c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i); - } -} - -/* apply to each pixel the given table */ -static void img_apply_table(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height, const uint8_t *table1) -{ - int n; - const uint8_t *s; - uint8_t *d; - const uint8_t *table; - - table = table1; - for(;height > 0; height--) { - s = src; - d = dst; - n = width; - while (n >= 4) { - d[0] = table[s[0]]; - d[1] = table[s[1]]; - d[2] = table[s[2]]; - d[3] = table[s[3]]; - d += 4; - s += 4; - n -= 4; - } - while (n > 0) { - d[0] = table[s[0]]; - d++; - s++; - n--; - } - dst += dst_wrap; - src += src_wrap; - } -} - -/* XXX: use generic filter ? */ -/* XXX: in most cases, the sampling position is incorrect */ - -/* 4x1 -> 1x1 */ -static void shrink41(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - const uint8_t *s; - uint8_t *d; - - for(;height > 0; height--) { - s = src; - d = dst; - for(w = width;w > 0; w--) { - d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2; - s += 4; - d++; - } - src += src_wrap; - dst += dst_wrap; - } -} - -/* 2x1 -> 1x1 */ -static void shrink21(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - const uint8_t *s; - uint8_t *d; - - for(;height > 0; height--) { - s = src; - d = dst; - for(w = width;w > 0; w--) { - d[0] = (s[0] + s[1]) >> 1; - s += 2; - d++; - } - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x2 -> 1x1 */ -static void shrink12(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - uint8_t *d; - const uint8_t *s1, *s2; - - for(;height > 0; height--) { - s1 = src; - s2 = s1 + src_wrap; - d = dst; - for(w = width;w >= 4; w-=4) { - d[0] = (s1[0] + s2[0]) >> 1; - d[1] = (s1[1] + s2[1]) >> 1; - d[2] = (s1[2] + s2[2]) >> 1; - d[3] = (s1[3] + s2[3]) >> 1; - s1 += 4; - s2 += 4; - d += 4; - } - for(;w > 0; w--) { - d[0] = (s1[0] + s2[0]) >> 1; - s1++; - s2++; - d++; - } - src += 2 * src_wrap; - dst += dst_wrap; - } -} - -static void grow21_line(uint8_t *dst, const uint8_t *src, - int width) -{ - int w; - const uint8_t *s1; - uint8_t *d; - - s1 = src; - d = dst; - for(w = width;w >= 4; w-=4) { - d[1] = d[0] = s1[0]; - d[3] = d[2] = s1[1]; - s1 += 2; - d += 4; - } - for(;w >= 2; w -= 2) { - d[1] = d[0] = s1[0]; - s1 ++; - d += 2; - } - /* only needed if width is not a multiple of two */ - /* XXX: veryfy that */ - if (w) { - d[0] = s1[0]; - } -} - -static void grow41_line(uint8_t *dst, const uint8_t *src, - int width) -{ - int w, v; - const uint8_t *s1; - uint8_t *d; - - s1 = src; - d = dst; - for(w = width;w >= 4; w-=4) { - v = s1[0]; - d[0] = v; - d[1] = v; - d[2] = v; - d[3] = v; - s1 ++; - d += 4; - } -} - -/* 1x1 -> 2x1 */ -static void grow21(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow21_line(dst, src, width); - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x1 -> 1x2 */ -static void grow12(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height-=2) { - memcpy(dst, src, width); - dst += dst_wrap; - memcpy(dst, src, width); - dst += dst_wrap; - src += src_wrap; - } -} - -/* 1x1 -> 2x2 */ -static void grow22(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow21_line(dst, src, width); - if (height%2) - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x1 -> 4x1 */ -static void grow41(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow41_line(dst, src, width); - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x1 -> 4x4 */ -static void grow44(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow41_line(dst, src, width); - if ((height & 3) == 1) - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x2 -> 2x1 */ -static void conv411(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w, c; - const uint8_t *s1, *s2; - uint8_t *d; - - width>>=1; - - for(;height > 0; height--) { - s1 = src; - s2 = src + src_wrap; - d = dst; - for(w = width;w > 0; w--) { - c = (s1[0] + s2[0]) >> 1; - d[0] = c; - d[1] = c; - s1++; - s2++; - d += 2; - } - src += src_wrap * 2; - dst += dst_wrap; - } -} - -/* XXX: always use linesize. Return -1 if not supported */ -int img_convert(AVPicture *dst, int dst_pix_fmt, - const AVPicture *src, int src_pix_fmt, - int src_width, int src_height) -{ - static int initialized; - int i, ret, dst_width, dst_height, int_pix_fmt; - const PixFmtInfo *src_pix, *dst_pix; - const ConvertEntry *ce; - AVPicture tmp1, *tmp = &tmp1; - - if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB || - dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB) - return -1; - if (src_width <= 0 || src_height <= 0) - return 0; - - if (!initialized) { - initialized = 1; - img_convert_init(); - } - - dst_width = src_width; - dst_height = src_height; - - dst_pix = &pix_fmt_info[dst_pix_fmt]; - src_pix = &pix_fmt_info[src_pix_fmt]; - if (src_pix_fmt == dst_pix_fmt) { - /* no conversion needed: just copy */ - av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height); - return 0; - } - - ce = &convert_table[src_pix_fmt][dst_pix_fmt]; - if (ce->convert) { - /* specific conversion routine */ - ce->convert(dst, src, dst_width, dst_height); - return 0; - } - - /* gray to YUV */ - if (is_yuv_planar(dst_pix) && - src_pix_fmt == PIX_FMT_GRAY8) { - int w, h, y; - uint8_t *d; - - if (dst_pix->color_type == FF_COLOR_YUV_JPEG) { - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height); - } else { - img_apply_table(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height, - y_jpeg_to_ccir); - } - /* fill U and V with 128 */ - w = dst_width; - h = dst_height; - w >>= dst_pix->x_chroma_shift; - h >>= dst_pix->y_chroma_shift; - for(i = 1; i <= 2; i++) { - d = dst->data[i]; - for(y = 0; y< h; y++) { - memset(d, 128, w); - d += dst->linesize[i]; - } - } - return 0; - } - - /* YUV to gray */ - if (is_yuv_planar(src_pix) && - dst_pix_fmt == PIX_FMT_GRAY8) { - if (src_pix->color_type == FF_COLOR_YUV_JPEG) { - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height); - } else { - img_apply_table(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height, - y_ccir_to_jpeg); - } - return 0; - } - - /* YUV to YUV planar */ - if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) { - int x_shift, y_shift, w, h, xy_shift; - void (*resize_func)(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height); - - /* compute chroma size of the smallest dimensions */ - w = dst_width; - h = dst_height; - if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift) - w >>= dst_pix->x_chroma_shift; - else - w >>= src_pix->x_chroma_shift; - if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift) - h >>= dst_pix->y_chroma_shift; - else - h >>= src_pix->y_chroma_shift; - - x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift); - y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift); - xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf); - /* there must be filters for conversion at least from and to - YUV444 format */ - switch(xy_shift) { - case 0x00: - resize_func = ff_img_copy_plane; - break; - case 0x10: - resize_func = shrink21; - break; - case 0x20: - resize_func = shrink41; - break; - case 0x01: - resize_func = shrink12; - break; - case 0x11: - resize_func = ff_shrink22; - break; - case 0x22: - resize_func = ff_shrink44; - break; - case 0xf0: - resize_func = grow21; - break; - case 0x0f: - resize_func = grow12; - break; - case 0xe0: - resize_func = grow41; - break; - case 0xff: - resize_func = grow22; - break; - case 0xee: - resize_func = grow44; - break; - case 0xf1: - resize_func = conv411; - break; - default: - /* currently not handled */ - goto no_chroma_filter; - } - - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height); - - for(i = 1;i <= 2; i++) - resize_func(dst->data[i], dst->linesize[i], - src->data[i], src->linesize[i], - dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift); - /* if yuv color space conversion is needed, we do it here on - the destination image */ - if (dst_pix->color_type != src_pix->color_type) { - const uint8_t *y_table, *c_table; - if (dst_pix->color_type == FF_COLOR_YUV) { - y_table = y_jpeg_to_ccir; - c_table = c_jpeg_to_ccir; - } else { - y_table = y_ccir_to_jpeg; - c_table = c_ccir_to_jpeg; - } - img_apply_table(dst->data[0], dst->linesize[0], - dst->data[0], dst->linesize[0], - dst_width, dst_height, - y_table); - - for(i = 1;i <= 2; i++) - img_apply_table(dst->data[i], dst->linesize[i], - dst->data[i], dst->linesize[i], - dst_width>>dst_pix->x_chroma_shift, - dst_height>>dst_pix->y_chroma_shift, - c_table); - } - return 0; - } - no_chroma_filter: - - /* try to use an intermediate format */ - if (src_pix_fmt == PIX_FMT_YUYV422 || - dst_pix_fmt == PIX_FMT_YUYV422) { - /* specific case: convert to YUV422P first */ - int_pix_fmt = PIX_FMT_YUV422P; - } else if (src_pix_fmt == PIX_FMT_UYVY422 || - dst_pix_fmt == PIX_FMT_UYVY422) { - /* specific case: convert to YUV422P first */ - int_pix_fmt = PIX_FMT_YUV422P; - } else if (src_pix_fmt == PIX_FMT_UYYVYY411 || - dst_pix_fmt == PIX_FMT_UYYVYY411) { - /* specific case: convert to YUV411P first */ - int_pix_fmt = PIX_FMT_YUV411P; - } else if ((src_pix->color_type == FF_COLOR_GRAY && - src_pix_fmt != PIX_FMT_GRAY8) || - (dst_pix->color_type == FF_COLOR_GRAY && - dst_pix_fmt != PIX_FMT_GRAY8)) { - /* gray8 is the normalized format */ - int_pix_fmt = PIX_FMT_GRAY8; - } else if ((is_yuv_planar(src_pix) && - src_pix_fmt != PIX_FMT_YUV444P && - src_pix_fmt != PIX_FMT_YUVJ444P)) { - /* yuv444 is the normalized format */ - if (src_pix->color_type == FF_COLOR_YUV_JPEG) - int_pix_fmt = PIX_FMT_YUVJ444P; - else - int_pix_fmt = PIX_FMT_YUV444P; - } else if ((is_yuv_planar(dst_pix) && - dst_pix_fmt != PIX_FMT_YUV444P && - dst_pix_fmt != PIX_FMT_YUVJ444P)) { - /* yuv444 is the normalized format */ - if (dst_pix->color_type == FF_COLOR_YUV_JPEG) - int_pix_fmt = PIX_FMT_YUVJ444P; - else - int_pix_fmt = PIX_FMT_YUV444P; - } else { - /* the two formats are rgb or gray8 or yuv[j]444p */ - if (src_pix->is_alpha && dst_pix->is_alpha) - int_pix_fmt = PIX_FMT_RGB32; - else - int_pix_fmt = PIX_FMT_RGB24; - } - if (src_pix_fmt == int_pix_fmt) - return -1; - 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; -} -#endif - /* NOTE: we scan all the pixels to have an exact information */ static int get_alpha_info_pal8(const AVPicture *src, int width, int height) { @@ -2638,19 +1417,15 @@ static int get_alpha_info_pal8(const AVPicture *src, int width, int height) } int img_get_alpha_info(const AVPicture *src, - int pix_fmt, int width, int height) + enum PixelFormat pix_fmt, int width, int height) { const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; int ret; - pf = &pix_fmt_info[pix_fmt]; /* no alpha can be represented in format */ if (!pf->is_alpha) return 0; switch(pix_fmt) { - case PIX_FMT_RGB32: - ret = get_alpha_info_rgb32(src, width, height); - break; case PIX_FMT_PAL8: ret = get_alpha_info_pal8(src, width, height); break; @@ -2662,7 +1437,7 @@ int img_get_alpha_info(const AVPicture *src, return ret; } -#ifdef HAVE_MMX +#if HAVE_MMX #define DEINT_INPLACE_LINE_LUM \ movd_m2r(lum_m4[0],mm0);\ movd_m2r(lum_m3[0],mm1);\ @@ -2716,7 +1491,7 @@ static void deinterlace_line(uint8_t *dst, const uint8_t *lum, int size) { -#ifndef HAVE_MMX +#if !HAVE_MMX uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int sum; @@ -2754,7 +1529,7 @@ static void deinterlace_line(uint8_t *dst, static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size) { -#ifndef HAVE_MMX +#if !HAVE_MMX uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int sum; @@ -2847,7 +1622,7 @@ static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, } int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height) + enum PixelFormat pix_fmt, int width, int height) { int i;