⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imgconvert.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* return true if yuv planar */static inline int is_yuv_planar(PixFmtInfo *ps){    return (ps->color_type == FF_COLOR_YUV ||            ps->color_type == FF_COLOR_YUV_JPEG) &&         ps->pixel_type == FF_PIXEL_PLANAR;}/* 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 inited;    int i, ret, dst_width, dst_height, int_pix_fmt;    PixFmtInfo *src_pix, *dst_pix;    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 (!inited) {        inited = 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 */        img_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 convertion 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) {            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) {            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 = 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 = shrink22;            break;        case 0x22:            resize_func = shrink44;            break;        case 0xf0:            resize_func = grow21;            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;        }        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_YUV422 ||        dst_pix_fmt == PIX_FMT_YUV422) {        /* specific case: convert to YUV422P first */        int_pix_fmt = PIX_FMT_YUV422P;    } 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_RGBA32;        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;}/* NOTE: we scan all the pixels to have an exact information */static int get_alpha_info_pal8(const AVPicture *src, int width, int height){    const unsigned char *p;    int src_wrap, ret, x, y;    unsigned int a;    uint32_t *palette = (uint32_t *)src->data[1];        p = src->data[0];    src_wrap = src->linesize[0] - width;    ret = 0;    for(y=0;y<height;y++) {        for(x=0;x<width;x++) {            a = palette[p[0]] >> 24;            if (a == 0x00) {                ret |= FF_ALPHA_TRANSP;            } else if (a != 0xff) {                ret |= FF_ALPHA_SEMI_TRANSP;            }            p++;        }        p += src_wrap;    }    return ret;}/** * Tell if an image really has transparent alpha values. * @return ored mask of FF_ALPHA_xxx constants */int img_get_alpha_info(const AVPicture *src,		       int pix_fmt, int width, int height){    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_RGBA32:        ret = get_alpha_info_rgba32(src, width, height);        break;    case PIX_FMT_RGB555:        ret = get_alpha_info_rgb555(src, width, height);        break;    case PIX_FMT_PAL8:        ret = get_alpha_info_pal8(src, width, height);        break;    default:        /* we do not know, so everything is indicated */        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;        break;    }    return ret;}#ifdef HAVE_MMX#define DEINT_INPLACE_LINE_LUM \                    movd_m2r(lum_m4[0],mm0);\                    movd_m2r(lum_m3[0],mm1);\                    movd_m2r(lum_m2[0],mm2);\                    movd_m2r(lum_m1[0],mm3);\                    movd_m2r(lum[0],mm4);\                    punpcklbw_r2r(mm7,mm0);\                    movd_r2m(mm2,lum_m4[0]);\                    punpcklbw_r2r(mm7,mm1);\                    punpcklbw_r2r(mm7,mm2);\                    punpcklbw_r2r(mm7,mm3);\                    punpcklbw_r2r(mm7,mm4);\                    paddw_r2r(mm3,mm1);\                    psllw_i2r(1,mm2);\                    paddw_r2r(mm4,mm0);\                    psllw_i2r(2,mm1);\                    paddw_r2r(mm6,mm2);\                    paddw_r2r(mm2,mm1);\                    psubusw_r2r(mm0,mm1);\                    psrlw_i2r(3,mm1);\                    packuswb_r2r(mm7,mm1);\                    movd_r2m(mm1,lum_m2[0]);#define DEINT_LINE_LUM \                    movd_m2r(lum_m4[0],mm0);\                    movd_m2r(lum_m3[0],mm1);\                    movd_m2r(lum_m2[0],mm2);\                    movd_m2r(lum_m1[0],mm3);\                    movd_m2r(lum[0],mm4);\                    punpcklbw_r2r(mm7,mm0);\                    punpcklbw_r2r(mm7,mm1);\                    punpcklbw_r2r(mm7,mm2);\                    punpcklbw_r2r(mm7,mm3);\                    punpcklbw_r2r(mm7,mm4);\                    paddw_r2r(mm3,mm1);\                    psllw_i2r(1,mm2);\                    paddw_r2r(mm4,mm0);\                    psllw_i2r(2,mm1);\                    paddw_r2r(mm6,mm2);\                    paddw_r2r(mm2,mm1);\                    psubusw_r2r(mm0,mm1);\                    psrlw_i2r(3,mm1);\                    packuswb_r2r(mm7,mm1);\                    movd_r2m(mm1,dst[0]);#endif/* filter parameters: [-1 4 2 4 -1] // 8 */static void deinterlace_line(uint8_t *dst, 			     const uint8_t *lum_m4, const uint8_t *lum_m3, 			     const uint8_t *lum_m2, const uint8_t *lum_m1, 			     const uint8_t *lum,			     int size){#ifndef HAVE_MMX    uint8_t *cm = cropTbl + MAX_NEG_CROP;    int sum;    for(;size > 0;size--) {        sum = -lum_m4[0];        sum += lum_m3[0] << 2;        sum += lum_m2[0] << 1;        sum += lum_m1[0] << 2;        sum += -lum[0];        dst[0] = cm[(sum + 4) >> 3];        lum_m4++;        lum_m3++;        lum_m2++;        lum_m1++;        lum++;        dst++;    }#else    {        mmx_t rounder;        rounder.uw[0]=4;        rounder.uw[1]=4;        rounder.uw[2]=4;        rounder.uw[3]=4;        pxor_r2r(mm7,mm7);        movq_m2r(rounder,mm6);    }    for (;size > 3; size-=4) {        DEINT_LINE_LUM        lum_m4+=4;        lum_m3+=4;        lum_m2+=4;        lum_m1+=4;        lum+=4;        dst+=4;    }#endif}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    uint8_t *cm = cropTbl + MAX_NEG_CROP;    int sum;    for(;size > 0;size--) {        sum = -lum_m4[0];        sum += lum_m3[0] << 2;        sum += lum_m2[0] << 1;        lum_m4[0]=lum_m2[0];        sum += lum_m1[0] << 2;        sum += -lum[0];        lum_m2[0] = cm[(sum + 4) >> 3];        lum_m4++;        lum_m3++;        lum_m2++;        lum_m1++;        lum++;    }#else    {        mmx_t rounder;        rounder.uw[0]=4;        rounder.uw[1]=4;        rounder.uw[2]=4;        rounder.uw[3]=4;        pxor_r2r(mm7,mm7);        movq_m2r(rounder,mm6);    }    for (;size > 3; size-=4) {        DEINT_INPLACE_LINE_LUM        lum_m4+=4;        lum_m3+=4;        lum_m2+=4;        lum_m1+=4;        lum+=4;    }#endif}/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The   top field is copied as is, but the bottom field is deinterlaced   against the top field. */static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,                                    const uint8_t *src1, int src_wrap,                                    int width, int height){    const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;    int y;    src_m2 = src1;    src_m1 = src1;    src_0=&src_m1[src_wrap];    src_p1=&src_0[src_wrap];    src_p2=&src_p1[src_wrap];    for(y=0;y<(height-2);y+=2) {        memcpy(dst,src_m1,width);        dst += dst_wrap;        deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);        src_m2 = src_0;        src_m1 = src_p1;        src_0 = src_p2;        src_p1 += 2*src_wrap;        src_p2 += 2*src_wrap;        dst += dst_wrap;    }    memcpy(dst,src_m1,width);    dst += dst_wrap;    /* do last line */    deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);}static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,					     int width, int height){    uint8_t *src_m1, *src_0, *src_p1, *src_p2;    int y;    uint8_t *buf;    buf = (uint8_t*)av_malloc(width);    src_m1 = src1;    memcpy(buf,src_m1,width);    src_0=&src_m1[src_wrap];    src_p1=&src_0[src_wrap];    src_p2=&src_p1[src_wrap];    for(y=0;y<(height-2);y+=2) {        deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);        src_m1 = src_p1;        src_0 = src_p2;        src_p1 += 2*src_wrap;        src_p2 += 2*src_wrap;    }    /* do last line */    deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);    av_free(buf);}/* deinterlace - if not supported return -1 */int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,                          int pix_fmt, int width, int height){    int i;    if (pix_fmt != PIX_FMT_YUV420P &&        pix_fmt != PIX_FMT_YUV422P &&        pix_fmt != PIX_FMT_YUV444P &&	pix_fmt != PIX_FMT_YUV411P)        return -1;    if ((width & 3) != 0 || (height & 3) != 0)        return -1;    for(i=0;i<3;i++) {        if (i == 1) {            switch(pix_fmt) {            case PIX_FMT_YUV420P:                width >>= 1;                height >>= 1;                break;            case PIX_FMT_YUV422P:                width >>= 1;                break;            case PIX_FMT_YUV411P:                width >>= 2;                break;            default:                break;            }        }        if (src == dst) {            deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],                                 width, height);        } else {            deinterlace_bottom_field(dst->data[i],dst->linesize[i],                                        src->data[i], src->linesize[i],                                        width, height);        }    }#ifdef HAVE_MMX    emms();#endif    return 0;}#undef FIX

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -