annotate libmpdemux/demux_gif.c @ 24129:50e1e79056b6

Make terminal input work more like VO key input The Unix version of getch2() could either return an internally buffered key or do a second-level select() in addition to the input.c one and then read more data. Change getch2() to always add all read keys with mplayer_put_key() (like video output window keyboard input does) and remove the internal select() from the Unix version. Make input.c call mplayer_get_key() directly. The primary motivation for this change is to make combining multiple event sources under one select() easier. Now getch2() only needs to be called when the corresponding fd is readable, and it will be possible to handle events from X-based VOs with the same code.
author uau
date Sat, 25 Aug 2007 04:28:08 +0000
parents a124f3abc1ec
children d4fe6e23283e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
1 /*
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
2 GIF file parser for MPlayer
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
3 by Joey Parrish
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
4 */
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
5
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
6 #include <stdio.h>
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
7 #include <stdlib.h>
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
8 #include <unistd.h>
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
9
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
10 #include "config.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
11
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
12 #include "mp_msg.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
13 #include "help_mp.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
14
22605
4d81dbdf46b9 Add explicit location for headers from the stream/ directory.
diego
parents: 22377
diff changeset
15 #include "stream/stream.h"
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
16 #include "demuxer.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
17 #include "stheader.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
18
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
19 #include <gif_lib.h>
21885
d885d65e8dc8 Simplify gif demuxer by using memcpy_pic
reimar
parents: 21884
diff changeset
20 #include "libvo/fastmemcpy.h"
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
21 typedef struct {
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
22 int current_pts;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
23 unsigned char *palette;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
24 GifFileType *gif;
21882
68ebac1f2b8d Fix crash for gif images that have Top or Left set
reimar
parents: 21881
diff changeset
25 int w, h;
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
26 int useref;
21921
e4265d11dc37 Change some types to uint8_t where appropriate
reimar
parents: 21920
diff changeset
27 uint8_t *refimg;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
28 } gif_priv_t;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
29
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
30 #define GIF_SIGNATURE (('G' << 16) | ('I' << 8) | 'F')
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
31
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
32 #ifndef HAVE_GIF_TVT_HACK
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
33 // not supported by certain versions of the library
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
34 int my_read_gif(GifFileType *gif, uint8_t *buf, int len) {
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
35 return stream_read(gif->UserData, buf, len);
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
36 }
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
37 #endif
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
38
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
39 static int gif_check_file(demuxer_t *demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
40 {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
41 if (stream_read_int24(demuxer->stream) == GIF_SIGNATURE)
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
42 return DEMUXER_TYPE_GIF;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
43 return 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
44 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
45
21920
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
46 static void memcpy_transp_pic(uint8_t *dst, uint8_t *src, int w, int h,
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
47 int dstride, int sstride, int transp, uint8_t trans_col) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
48 if (transp) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
49 dstride -= w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
50 sstride -= w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
51 while (h-- > 0) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
52 int wleft = w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
53 while (wleft-- > 0) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
54 if (*src != trans_col)
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
55 *dst = *src;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
56 dst++; src++;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
57 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
58 dst += dstride;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
59 src += sstride;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
60 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
61 } else
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
62 memcpy_pic(dst, src, w, h, dstride, sstride);
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
63 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
64
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
65 static int demux_gif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
66 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
67 gif_priv_t *priv = demuxer->priv;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
68 GifFileType *gif = priv->gif;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
69 GifRecordType type = UNDEFINED_RECORD_TYPE;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
70 int len = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
71 demux_packet_t *dp = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
72 ColorMapObject *effective_map = NULL;
21921
e4265d11dc37 Change some types to uint8_t where appropriate
reimar
parents: 21920
diff changeset
73 uint8_t *buf = NULL;
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
74 int refmode = 0;
21895
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
75 int transparency = 0;
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
76 uint8_t transparent_col;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
77
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
78 while (type != IMAGE_DESC_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
79 if (DGifGetRecordType(gif, &type) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
80 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
81 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
82 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
83 if (type == TERMINATE_RECORD_TYPE)
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
84 return 0; // eof
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
85 if (type == SCREEN_DESC_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
86 if (DGifGetScreenDesc(gif) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
87 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
88 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
89 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
90 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
91 if (type == EXTENSION_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
92 int code;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
93 unsigned char *p = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
94 if (DGifGetExtension(gif, &code, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
95 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
96 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
97 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
98 if (code == 0xF9) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
99 int frametime = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
100 if (p[0] == 4) // is the length correct?
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
101 {
21895
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
102 transparency = p[1] & 1;
21896
b2640a639ac7 Cosmetics
reimar
parents: 21895
diff changeset
103 refmode = (p[1] >> 2) & 3;
22020
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
104 // HACK: specification says
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
105 // > 0 - No disposal specified. The decoder is not required to take any action.
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
106 // but browsers treat it the same way as
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
107 // > 1 - Do not dispose. The graphic is to be left in place.
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
108 // Some broken files rely on this, e.g.
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
109 // http://samples.mplayerhq.hu/GIF/broken-gif/CLAIRE.GIF
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
110 if (refmode == 0) refmode = 1;
21875
d81cf0be50f0 Frametime was being read from the wrong offset, compare
diego
parents: 18958
diff changeset
111 frametime = (p[3] << 8) | p[2]; // set the time, centiseconds
21895
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
112 transparent_col = p[4];
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
113 }
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
114 priv->current_pts += frametime;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
115 } else if ((code == 0xFE) && (verbose)) { // comment extension
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
116 // print iff verbose
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
117 printf("GIF comment: ");
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
118 while (p != NULL) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
119 int length = p[0];
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
120 char *comments = p + 1;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
121 comments[length] = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
122 printf("%s", comments);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
123 if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
124 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
125 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
126 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
127 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
128 printf("\n");
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
129 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
130 while (p != NULL) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
131 if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
132 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
133 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
134 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
135 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
136 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
137 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
138
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
139 if (DGifGetImageDesc(gif) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
140 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
141 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
142 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
143
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
144 len = gif->Image.Width * gif->Image.Height;
21882
68ebac1f2b8d Fix crash for gif images that have Top or Left set
reimar
parents: 21881
diff changeset
145 dp = new_demux_packet(priv->w * priv->h);
21890
84e155426ef9 memset + malloc -> calloc
reimar
parents: 21887
diff changeset
146 buf = calloc(gif->Image.Width, gif->Image.Height);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
147 if (priv->useref)
23457
a124f3abc1ec Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents: 22605
diff changeset
148 fast_memcpy(dp->buffer, priv->refimg, priv->w * priv->h);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
149 else
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
150 memset(dp->buffer, gif->SBackGroundColor, priv->w * priv->h);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
151
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
152 if (DGifGetLine(gif, buf, len) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
153 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
154 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
155 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
156
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
157 effective_map = gif->Image.ColorMap;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
158 if (effective_map == NULL) effective_map = gif->SColorMap;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
159
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
160 {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
161 int y;
21883
3758ec905220 Simplify
reimar
parents: 21882
diff changeset
162 int cnt = FFMIN(effective_map->ColorCount, 256);
22377
fd54975f9135 Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents: 22024
diff changeset
163 int l = av_clip(gif->Image.Left, 0, priv->w);
fd54975f9135 Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents: 22024
diff changeset
164 int t = av_clip(gif->Image.Top, 0, priv->h);
fd54975f9135 Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents: 22024
diff changeset
165 int w = av_clip(gif->Image.Width, 0, priv->w - l);
fd54975f9135 Use libavutil's av_clip* instead of unreadable MIN/MAX chaos.
reimar
parents: 22024
diff changeset
166 int h = av_clip(gif->Image.Height, 0, priv->h - t);
21885
d885d65e8dc8 Simplify gif demuxer by using memcpy_pic
reimar
parents: 21884
diff changeset
167 unsigned char *dest = dp->buffer + priv->w * t + l;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
168
21876
82dd482fb3ec cosmetics: typo fix pallete --> palette
diego
parents: 21875
diff changeset
169 // copy the palette
21881
a10888bc9758 Fix invalid read for gifs with a palette for less than 256 colors
reimar
parents: 21880
diff changeset
170 for (y = 0; y < cnt; y++) {
21893
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
171 priv->palette[(y * 4) + 0] = effective_map->Colors[y].Blue;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
172 priv->palette[(y * 4) + 1] = effective_map->Colors[y].Green;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
173 priv->palette[(y * 4) + 2] = effective_map->Colors[y].Red;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
174 priv->palette[(y * 4) + 3] = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
175 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
176
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
177 if (gif->Image.Interlace) {
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
178 uint8_t *s = buf;
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
179 int ih = (h - 0 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
180 memcpy_transp_pic(dest, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
181 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
182 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
183 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
184 ih = (h - 4 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
185 memcpy_transp_pic(dest + (priv->w << 2), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
186 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
187 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
188 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
189 ih = (h - 2 + 3) >> 2;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
190 memcpy_transp_pic(dest + (priv->w << 1), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
191 priv->w << 2, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
192 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
193 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
194 ih = (h - 1 + 1) >> 1;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
195 memcpy_transp_pic(dest + priv->w, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
196 priv->w << 1, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
197 transparency, transparent_col);
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
198 } else
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
199 memcpy_transp_pic(dest, buf, w, h, priv->w, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
200 transparency, transparent_col);
21892
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
201
23457
a124f3abc1ec Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents: 22605
diff changeset
202 if (refmode == 1) fast_memcpy(priv->refimg, dp->buffer, priv->w * priv->h);
21892
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
203 if (refmode == 2 && priv->useref) {
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
204 dest = priv->refimg + priv->w * t + l;
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
205 memset(buf, gif->SBackGroundColor, len);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
206 memcpy_pic(dest, buf, w, h, priv->w, gif->Image.Width);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
207 }
21894
449b9fb6f67b Fix: refmodes 2 and 3 leave useref unchanged
reimar
parents: 21893
diff changeset
208 if (!(refmode & 2)) priv->useref = refmode & 1;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
209 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
210
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
211 free(buf);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
212
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
213 demuxer->video->dpos++;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
214 dp->pts = ((float)priv->current_pts) / 100;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
215 dp->pos = stream_tell(demuxer->stream);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
216 ds_add_packet(demuxer->video, dp);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
217
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
218 return 1;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
219 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
220
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
221 static demuxer_t* demux_open_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
222 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
223 gif_priv_t *priv = calloc(1, sizeof(gif_priv_t));
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
224 sh_video_t *sh_video = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
225 GifFileType *gif = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
226
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
227 priv->current_pts = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
228 demuxer->seekable = 0; // FIXME
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
229
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
230 // go back to the beginning
9345
fef4f1a9de5e compile fix
henry
parents: 9344
diff changeset
231 stream_seek(demuxer->stream,demuxer->stream->start_pos);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
232
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
233 #ifdef HAVE_GIF_TVT_HACK
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
234 // without the TVT functionality of libungif, a hard seek must be
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
235 // done to the beginning of the file. this is because libgif is
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
236 // unable to use mplayer's cache, and without this lseek libgif will
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
237 // not read from the beginning of the file and the command will fail.
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
238 // with this hack enabled, you will lose the ability to stream a GIF.
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
239 lseek(demuxer->stream->fd, 0, SEEK_SET);
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
240 gif = DGifOpenFileHandle(demuxer->stream->fd);
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
241 #else
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
242 gif = DGifOpen(demuxer->stream, my_read_gif);
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
243 #endif
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
244 if (!gif) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
245 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
246 return NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
247 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
248
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
249 // create a new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
250 sh_video = new_sh_video(demuxer, 0);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
251
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
252 // make sure the demuxer knows about the new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
253 // (even though new_sh_video() ought to take care of it)
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
254 demuxer->video->sh = sh_video;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
255
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
256 // make sure that the video demuxer stream header knows about its
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
257 // parent video demuxer stream (this is getting wacky), or else
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
258 // video_read_properties() will choke
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
259 sh_video->ds = demuxer->video;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
260
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
261 sh_video->format = mmioFOURCC(8, 'R', 'G', 'B');
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
262
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
263 sh_video->fps = 5.0f;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
264 sh_video->frametime = 1.0f / sh_video->fps;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
265
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
266 sh_video->bih = malloc(sizeof(BITMAPINFOHEADER) + (256 * 4));
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
267 sh_video->bih->biCompression = sh_video->format;
22019
f43d02e9b58b Set sh_video->bih->biWidth properly, fixes decoding after latest dec_video.c change
reimar
parents: 21922
diff changeset
268 sh_video->bih->biWidth = priv->w = (uint16_t)gif->SWidth;
f43d02e9b58b Set sh_video->bih->biWidth properly, fixes decoding after latest dec_video.c change
reimar
parents: 21922
diff changeset
269 sh_video->bih->biHeight = priv->h = (uint16_t)gif->SHeight;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
270 sh_video->bih->biBitCount = 8;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
271 sh_video->bih->biPlanes = 2;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
272 priv->palette = (unsigned char *)(sh_video->bih + 1);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
273 priv->refimg = malloc(priv->w * priv->h);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
274
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
275 priv->gif = gif;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
276 demuxer->priv = priv;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
277
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
278 return demuxer;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
279 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
280
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
281 static void demux_close_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
282 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
283 gif_priv_t *priv = demuxer->priv;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
284 if (!priv) return;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
285 if (priv->gif && DGifCloseFile(priv->gif) == GIF_ERROR)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
286 PrintGifError();
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
287 free(priv->refimg);
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
288 free(priv);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
289 }
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
290
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
291
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
292 demuxer_desc_t demuxer_desc_gif = {
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
293 "GIF demuxer",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
294 "gif",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
295 "GIF",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
296 "Joey Parrish",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
297 "",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
298 DEMUXER_TYPE_GIF,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
299 0, // unsafe autodetect
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
300 gif_check_file,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
301 demux_gif_fill_buffer,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
302 demux_open_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
303 demux_close_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
304 NULL,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
305 NULL
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
306 };