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

📄 gifdec.c

📁 F:图像处理资料264264书籍ffmpeg-0.4.9-pre1VideoStream.rar 一个视频解压缩源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * GIF decoder * Copyright (c) 2003 Fabrice Bellard. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "avformat.h"int gif_write(ByteIOContext *pb, AVImageInfo *info);//#define DEBUG#define MAXBITS		12#define	SIZTABLE	(1<<MAXBITS)#define GCE_DISPOSAL_NONE       0#define GCE_DISPOSAL_INPLACE    1#define GCE_DISPOSAL_BACKGROUND 2#define GCE_DISPOSAL_RESTORE    3typedef struct GifState {    int screen_width;    int screen_height;    int bits_per_pixel;    int background_color_index;    int transparent_color_index;    int color_resolution;    uint8_t *image_buf;    int image_linesize;    uint32_t *image_palette;    int pix_fmt;    /* after the frame is displayed, the disposal method is used */    int gce_disposal;    /* delay during which the frame is shown */    int gce_delay;        /* LZW compatible decoder */    ByteIOContext *f;    int eob_reached;    uint8_t *pbuf, *ebuf;    int bbits;    unsigned int bbuf;    int cursize;		/* The current code size */    int curmask;    int codesize;    int clear_code;    int end_code;    int newcodes;		/* First available code */    int top_slot;		/* Highest code for current size */    int slot;			/* Last read code */    int fc, oc;    uint8_t *sp;    uint8_t stack[SIZTABLE];    uint8_t suffix[SIZTABLE];    uint16_t prefix[SIZTABLE];    /* aux buffers */    uint8_t global_palette[256 * 3];    uint8_t local_palette[256 * 3];    uint8_t buf[256];} GifState;static const uint8_t gif87a_sig[6] = "GIF87a";static const uint8_t gif89a_sig[6] = "GIF89a";static const uint16_t mask[17] ={    0x0000, 0x0001, 0x0003, 0x0007,    0x000F, 0x001F, 0x003F, 0x007F,    0x00FF, 0x01FF, 0x03FF, 0x07FF,    0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};/* Probe gif video format or gif image format. The current heuristic   supposes the gif87a is always a single image. For gif89a, we   consider it as a video only if a GCE extension is present in the   first kilobyte. */static int gif_video_probe(AVProbeData * pd){    const uint8_t *p, *p_end;    int bits_per_pixel, has_global_palette, ext_code, ext_len;    int gce_flags, gce_disposal;    if (pd->buf_size < 24 ||	memcmp(pd->buf, gif89a_sig, 6) != 0)        return 0;    p_end = pd->buf + pd->buf_size;    p = pd->buf + 6;    bits_per_pixel = (p[4] & 0x07) + 1;    has_global_palette = (p[4] & 0x80);    p += 7;    if (has_global_palette)        p += (1 << bits_per_pixel) * 3;    for(;;) {        if (p >= p_end)            return 0;        if (*p != '!')            break;        p++;        if (p >= p_end)            return 0;        ext_code = *p++;        if (p >= p_end)            return 0;        ext_len = *p++;        if (ext_code == 0xf9) {            if (p >= p_end)                return 0;            /* if GCE extension found with gce_disposal != 0: it is               likely to be an animation */            gce_flags = *p++;            gce_disposal = (gce_flags >> 2) & 0x7;            if (gce_disposal != 0)                return AVPROBE_SCORE_MAX;            else                return 0;        }        for(;;) {            if (ext_len == 0)                break;            p += ext_len;            if (p >= p_end)                return 0;            ext_len = *p++;        }    }    return 0;}static int gif_image_probe(AVProbeData * pd){    if (pd->buf_size >= 24 &&	(memcmp(pd->buf, gif87a_sig, 6) == 0 ||	 memcmp(pd->buf, gif89a_sig, 6) == 0))	return AVPROBE_SCORE_MAX - 1;    else	return 0;}static void GLZWDecodeInit(GifState * s, int csize){    /* read buffer */    s->eob_reached = 0;    s->pbuf = s->buf;    s->ebuf = s->buf;    s->bbuf = 0;    s->bbits = 0;    /* decoder */    s->codesize = csize;    s->cursize = s->codesize + 1;    s->curmask = mask[s->cursize];    s->top_slot = 1 << s->cursize;    s->clear_code = 1 << s->codesize;    s->end_code = s->clear_code + 1;    s->slot = s->newcodes = s->clear_code + 2;    s->oc = s->fc = 0;    s->sp = s->stack;}/* XXX: optimize */static inline int GetCode(GifState * s){    int c, sizbuf;    uint8_t *ptr;    while (s->bbits < s->cursize) {        ptr = s->pbuf;        if (ptr >= s->ebuf) {            if (!s->eob_reached) {                sizbuf = get_byte(s->f);                s->ebuf = s->buf + sizbuf;                s->pbuf = s->buf;                if (sizbuf > 0) {                    get_buffer(s->f, s->buf, sizbuf);                } else {                    s->eob_reached = 1;                }            }            ptr = s->pbuf;        }        s->bbuf |= ptr[0] << s->bbits;        ptr++;        s->pbuf = ptr;	s->bbits += 8;    }    c = s->bbuf & s->curmask;    s->bbuf >>= s->cursize;    s->bbits -= s->cursize;    return c;}/* NOTE: the algorithm here is inspired from the LZW GIF decoder   written by Steven A. Bennett in 1987. *//* return the number of byte decoded */static int GLZWDecode(GifState * s, uint8_t * buf, int len){    int l, c, code, oc, fc;    uint8_t *sp;    if (s->end_code < 0)        return 0;    l = len;    sp = s->sp;    oc = s->oc;    fc = s->fc;    while (sp > s->stack) {	*buf++ = *(--sp);	if ((--l) == 0)	    goto the_end;    }    for (;;) {	c = GetCode(s);	if (c == s->end_code) {	    s->end_code = -1;	    break;	} else if (c == s->clear_code) {	    s->cursize = s->codesize + 1;	    s->curmask = mask[s->cursize];	    s->slot = s->newcodes;	    s->top_slot = 1 << s->cursize;	    while ((c = GetCode(s)) == s->clear_code);	    if (c == s->end_code) {		s->end_code = -1;		break;	    }	    /* test error */	    if (c >= s->slot)		c = 0;	    fc = oc = c;	    *buf++ = c;	    if ((--l) == 0)		break;	} else {	    code = c;	    if (code >= s->slot) {		*sp++ = fc;		code = oc;	    }	    while (code >= s->newcodes) {		*sp++ = s->suffix[code];		code = s->prefix[code];	    }	    *sp++ = code;	    if (s->slot < s->top_slot) {		s->suffix[s->slot] = fc = code;		s->prefix[s->slot++] = oc;		oc = c;	    }	    if (s->slot >= s->top_slot) {		if (s->cursize < MAXBITS) {		    s->top_slot <<= 1;		    s->curmask = mask[++s->cursize];		}	    }	    while (sp > s->stack) {		*buf++ = *(--sp);		if ((--l) == 0)                    goto the_end;	    }	}    }  the_end:    s->sp = sp;    s->oc = oc;    s->fc = fc;    return len - l;}static int gif_read_image(GifState *s){    ByteIOContext *f = s->f;    int left, top, width, height, bits_per_pixel, code_size, flags;    int is_interleaved, has_local_palette, y, x, pass, y1, linesize, n, i;    uint8_t *ptr, *line, *d, *spal, *palette, *sptr, *ptr1;    left = get_le16(f);    top = get_le16(f);    width = get_le16(f);    height = get_le16(f);    flags = get_byte(f);    is_interleaved = flags & 0x40;    has_local_palette = flags & 0x80;    bits_per_pixel = (flags & 0x07) + 1;#ifdef DEBUG    printf("gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height);#endif    if (has_local_palette) {	get_buffer(f, s->local_palette, 3 * (1 << bits_per_pixel));        palette = s->local_palette;    } else {        palette = s->global_palette;        bits_per_pixel = s->bits_per_pixel;    }        /* verify that all the image is inside the screen dimensions */    if (left + width > s->screen_width ||        top + height > s->screen_height)

⌨️ 快捷键说明

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