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

📄 gifdec.c

📁 FFmpeg is an audio/video conversion tool. It includes libavcodec, the leading open source codec libr
💻 C
📖 第 1 页 / 共 2 页
字号:
        return -EINVAL;    /* build the palette */    if (s->pix_fmt == PIX_FMT_RGB24) {        line = av_malloc(width);        if (!line)            return -ENOMEM;    } else {        n = (1 << bits_per_pixel);        spal = palette;        for(i = 0; i < n; i++) {            s->image_palette[i] = (0xff << 24) |                 (spal[0] << 16) | (spal[1] << 8) | (spal[2]);            spal += 3;        }        for(; i < 256; i++)            s->image_palette[i] = (0xff << 24);        /* handle transparency */        if (s->transparent_color_index >= 0)            s->image_palette[s->transparent_color_index] = 0;        line = NULL;    }    /* now get the image data */    s->f = f;    code_size = get_byte(f);    GLZWDecodeInit(s, code_size);    /* read all the image */    linesize = s->image_linesize;    ptr1 = s->image_buf + top * linesize + (left * 3);    ptr = ptr1;    pass = 0;    y1 = 0;    for (y = 0; y < height; y++) {        if (s->pix_fmt == PIX_FMT_RGB24) {            /* transcode to RGB24 */            GLZWDecode(s, line, width);            d = ptr;            sptr = line;            for(x = 0; x < width; x++) {                spal = palette + sptr[0] * 3;                d[0] = spal[0];                d[1] = spal[1];                d[2] = spal[2];                d += 3;                sptr++;            }        } else {            GLZWDecode(s, ptr, width);        }        if (is_interleaved) {            switch(pass) {            default:            case 0:            case 1:                y1 += 8;                ptr += linesize * 8;                if (y1 >= height) {                    y1 = 4;                    if (pass == 0)                         ptr = ptr1 + linesize * 4;                    else                        ptr = ptr1 + linesize * 2;                    pass++;                }                break;            case 2:                y1 += 4;                ptr += linesize * 4;                if (y1 >= height) {                    y1 = 1;                    ptr = ptr1 + linesize;                    pass++;                }                break;            case 3:                y1 += 2;                ptr += linesize * 2;                break;            }        } else {            ptr += linesize;        }    }    av_free(line);        /* read the garbage data until end marker is found */    while (!s->eob_reached)        GetCode(s);    return 0;}static int gif_read_extension(GifState *s){    ByteIOContext *f = s->f;    int ext_code, ext_len, i, gce_flags, gce_transparent_index;    /* extension */    ext_code = get_byte(f);    ext_len = get_byte(f);#ifdef DEBUG    printf("gif: ext_code=0x%x len=%d\n", ext_code, ext_len);#endif    switch(ext_code) {    case 0xf9:        if (ext_len != 4)            goto discard_ext;        s->transparent_color_index = -1;        gce_flags = get_byte(f);        s->gce_delay = get_le16(f);        gce_transparent_index = get_byte(f);        if (gce_flags & 0x01)            s->transparent_color_index = gce_transparent_index;        else            s->transparent_color_index = -1;        s->gce_disposal = (gce_flags >> 2) & 0x7;#ifdef DEBUG        printf("gif: gce_flags=%x delay=%d tcolor=%d disposal=%d\n",                gce_flags, s->gce_delay,                s->transparent_color_index, s->gce_disposal);#endif        ext_len = get_byte(f);        break;    }            /* NOTE: many extension blocks can come after */ discard_ext:    while (ext_len != 0) {        for (i = 0; i < ext_len; i++)            get_byte(f);        ext_len = get_byte(f);#ifdef DEBUG        printf("gif: ext_len1=%d\n", ext_len);#endif    }    return 0;}static int gif_read_header1(GifState *s){    ByteIOContext *f = s->f;    uint8_t sig[6];    int ret, v, n;    int has_global_palette;    /* read gif signature */    ret = get_buffer(f, sig, 6);    if (ret != 6)	return -1;    if (memcmp(sig, gif87a_sig, 6) != 0 &&	memcmp(sig, gif89a_sig, 6) != 0)	return -1;    /* read screen header */    s->transparent_color_index = -1;    s->screen_width = get_le16(f);    s->screen_height = get_le16(f);    v = get_byte(f);    s->color_resolution = ((v & 0x70) >> 4) + 1;    has_global_palette = (v & 0x80);    s->bits_per_pixel = (v & 0x07) + 1;    s->background_color_index = get_byte(f);    get_byte(f);		/* ignored */#ifdef DEBUG    printf("gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n",	   s->screen_width, s->screen_height, s->bits_per_pixel,	   has_global_palette);#endif    if (has_global_palette) {	n = 1 << s->bits_per_pixel;	get_buffer(f, s->global_palette, n * 3);    }    return 0;}static int gif_parse_next_image(GifState *s){    ByteIOContext *f = s->f;    int ret, code;    for (;;) {	code = url_fgetc(f);#ifdef DEBUG	printf("gif: code=%02x '%c'\n", code, code);#endif	switch (code) {	case ',':	    if (gif_read_image(s) < 0)		return AVERROR_IO;	    ret = 0;	    goto the_end;	case ';':	    /* end of image */	    ret = AVERROR_IO;	    goto the_end;	case '!':            if (gif_read_extension(s) < 0)                return AVERROR_IO;	    break;	case EOF:	default:	    /* error or errneous EOF */	    ret = AVERROR_IO;	    goto the_end;	}    }  the_end:    return ret;}static int gif_read_header(AVFormatContext * s1,			   AVFormatParameters * ap){    GifState *s = s1->priv_data;    ByteIOContext *f = &s1->pb;    AVStream *st;    s->f = f;    if (gif_read_header1(s) < 0)        return -1;        /* allocate image buffer */    s->image_linesize = s->screen_width * 3;    s->image_buf = av_malloc(s->screen_height * s->image_linesize);    if (!s->image_buf)        return -ENOMEM;    s->pix_fmt = PIX_FMT_RGB24;    /* now we are ready: build format streams */    st = av_new_stream(s1, 0);    if (!st)	return -1;    st->codec.codec_type = CODEC_TYPE_VIDEO;    st->codec.codec_id = CODEC_ID_RAWVIDEO;    st->codec.frame_rate = 5;    st->codec.frame_rate_base = 1;    /* XXX: check if screen size is always valid */    st->codec.width = s->screen_width;    st->codec.height = s->screen_height;    st->codec.pix_fmt = PIX_FMT_RGB24;    return 0;}static int gif_read_packet(AVFormatContext * s1,			   AVPacket * pkt){    GifState *s = s1->priv_data;    int ret;    ret = gif_parse_next_image(s);    if (ret < 0)        return ret;    /* XXX: avoid copying */    if (av_new_packet(pkt, s->screen_width * s->screen_height * 3)) {	return AVERROR_IO;    }    pkt->stream_index = 0;    memcpy(pkt->data, s->image_buf, s->screen_width * s->screen_height * 3);    return 0;}static int gif_read_close(AVFormatContext *s1){    GifState *s = s1->priv_data;    av_free(s->image_buf);    return 0;}/* read gif as image */static int gif_read(ByteIOContext *f,                     int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque){    GifState s1, *s = &s1;    AVImageInfo info1, *info = &info1;    int ret;    memset(s, 0, sizeof(GifState));    s->f = f;    if (gif_read_header1(s) < 0)        return -1;    info->width = s->screen_width;    info->height = s->screen_height;    info->pix_fmt = PIX_FMT_PAL8;    ret = alloc_cb(opaque, info);    if (ret)        return ret;    s->image_buf = info->pict.data[0];    s->image_linesize = info->pict.linesize[0];    s->image_palette = (uint32_t *)info->pict.data[1];    if (gif_parse_next_image(s) < 0)        return -1;    return 0;}AVInputFormat gif_iformat ={    "gif",    "gif format",    sizeof(GifState),    gif_video_probe,    gif_read_header,    gif_read_packet,    gif_read_close,};AVImageFormat gif_image_format = {    "gif",    "gif",    gif_image_probe,    gif_read,    (1 << PIX_FMT_PAL8),    gif_write,};

⌨️ 快捷键说明

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