annotate libmpdemux/demux_gif.c @ 34809:ea97bcb28df1

Allow direct rendering for non-reference frames in H.264. This might work for other codecs that currently have DR disabled, but H.264 is the only one tested so far.
author reimar
date Mon, 14 May 2012 18:11:24 +0000
parents 4558e2b7e68b
children 9eeba22fd78a
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 /*
29238
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
2 * GIF file parser
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
3 * Copyright (C) 2003 Joey Parrish
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
4 *
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
5 * This file is part of MPlayer.
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
6 *
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
7 * MPlayer is free software; you can redistribute it and/or modify
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
8 * it under the terms of the GNU General Public License as published by
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
9 * the Free Software Foundation; either version 2 of the License, or
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
10 * (at your option) any later version.
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
11 *
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
12 * MPlayer is distributed in the hope that it will be useful,
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
15 * GNU General Public License for more details.
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
16 *
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
17 * You should have received a copy of the GNU General Public License along
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
18 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
d643e4643313 Add standard license header to all files in libmpdemux.
diego
parents: 27385
diff changeset
20 */
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
21
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
22 #include <stdio.h>
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
23 #include <stdlib.h>
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
24 #include <unistd.h>
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
25
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
26 #include "config.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
27
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
28 #include "mp_msg.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
29 #include "help_mp.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
30
22605
4d81dbdf46b9 Add explicit location for headers from the stream/ directory.
diego
parents: 22377
diff changeset
31 #include "stream/stream.h"
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
32 #include "demuxer.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
33 #include "stheader.h"
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
34
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
35 #include <gif_lib.h>
21885
d885d65e8dc8 Simplify gif demuxer by using memcpy_pic
reimar
parents: 21884
diff changeset
36 #include "libvo/fastmemcpy.h"
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
37 typedef struct {
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
38 int current_pts;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
39 unsigned char *palette;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
40 GifFileType *gif;
21882
68ebac1f2b8d Fix crash for gif images that have Top or Left set
reimar
parents: 21881
diff changeset
41 int w, h;
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
42 int useref;
21921
e4265d11dc37 Change some types to uint8_t where appropriate
reimar
parents: 21920
diff changeset
43 uint8_t *refimg;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
44 } gif_priv_t;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
45
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
46 #define GIF_SIGNATURE (('G' << 16) | ('I' << 8) | 'F')
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
47
27385
2113bd9c6bd9 Rename preprocessor directives related to image libraries.
diego
parents: 25707
diff changeset
48 #ifndef CONFIG_GIF_TVT_HACK
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
49 // not supported by certain versions of the library
30570
98dc6ae7ede2 libmpdemux: Mark functions not used outside of their files as static.
diego
parents: 29263
diff changeset
50 static int my_read_gif(GifFileType *gif, uint8_t *buf, int len)
98dc6ae7ede2 libmpdemux: Mark functions not used outside of their files as static.
diego
parents: 29263
diff changeset
51 {
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
52 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
53 }
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
54 #endif
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
55
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
56 static int gif_check_file(demuxer_t *demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
57 {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
58 if (stream_read_int24(demuxer->stream) == GIF_SIGNATURE)
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
59 return DEMUXER_TYPE_GIF;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
60 return 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
61 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
62
21920
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
63 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
64 int dstride, int sstride, int transp, uint8_t trans_col) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
65 if (transp) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
66 dstride -= w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
67 sstride -= w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
68 while (h-- > 0) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
69 int wleft = w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
70 while (wleft-- > 0) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
71 if (*src != trans_col)
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
72 *dst = *src;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
73 dst++; src++;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
74 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
75 dst += dstride;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
76 src += sstride;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
77 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
78 } else
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
79 memcpy_pic(dst, src, w, h, dstride, sstride);
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
80 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
81
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
82 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
83 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
84 gif_priv_t *priv = demuxer->priv;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
85 GifFileType *gif = priv->gif;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
86 GifRecordType type = UNDEFINED_RECORD_TYPE;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
87 int len = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
88 demux_packet_t *dp = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
89 ColorMapObject *effective_map = NULL;
21921
e4265d11dc37 Change some types to uint8_t where appropriate
reimar
parents: 21920
diff changeset
90 uint8_t *buf = NULL;
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
91 int refmode = 0;
21895
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
92 int transparency = 0;
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
93 uint8_t transparent_col;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
94
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
95 while (type != IMAGE_DESC_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
96 if (DGifGetRecordType(gif, &type) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
97 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
98 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
99 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
100 if (type == TERMINATE_RECORD_TYPE)
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
101 return 0; // eof
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
102 if (type == SCREEN_DESC_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
103 if (DGifGetScreenDesc(gif) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
104 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
105 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
106 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
107 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
108 if (type == EXTENSION_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
109 int code;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
110 unsigned char *p = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
111 if (DGifGetExtension(gif, &code, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
112 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
113 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
114 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
115 if (code == 0xF9) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
116 int frametime = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
117 if (p[0] == 4) // is the length correct?
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
118 {
21895
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
119 transparency = p[1] & 1;
21896
b2640a639ac7 Cosmetics
reimar
parents: 21895
diff changeset
120 refmode = (p[1] >> 2) & 3;
22020
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
121 // HACK: specification says
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
122 // > 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
123 // 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
124 // > 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
125 // 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
126 // 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
127 if (refmode == 0) refmode = 1;
21875
d81cf0be50f0 Frametime was being read from the wrong offset, compare
diego
parents: 18958
diff changeset
128 frametime = (p[3] << 8) | p[2]; // set the time, centiseconds
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
129 transparent_col = p[4];
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
130 }
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
131 priv->current_pts += frametime;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
132 } else if ((code == 0xFE) && (verbose)) { // comment extension
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
133 // print iff verbose
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
134 printf("GIF comment: ");
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
135 while (p != NULL) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
136 int length = p[0];
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
137 char *comments = p + 1;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
138 comments[length] = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
139 printf("%s", comments);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
140 if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
141 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
142 return 0; // oops
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 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
145 printf("\n");
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
146 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
147 while (p != NULL) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
148 if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
149 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
150 return 0; // oops
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 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
153 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
154 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
155
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
156 if (DGifGetImageDesc(gif) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
157 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
158 return 0; // oops
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 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
162 dp = new_demux_packet(priv->w * priv->h);
21890
84e155426ef9 memset + malloc -> calloc
reimar
parents: 21887
diff changeset
163 buf = calloc(gif->Image.Width, gif->Image.Height);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
164 if (priv->useref)
23457
a124f3abc1ec Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents: 22605
diff changeset
165 fast_memcpy(dp->buffer, priv->refimg, priv->w * priv->h);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
166 else
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
167 memset(dp->buffer, gif->SBackGroundColor, priv->w * priv->h);
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
168
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
169 if (DGifGetLine(gif, buf, len) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
170 PrintGifError();
32614
4558e2b7e68b Fix memleaks on error.
reimar
parents: 32123
diff changeset
171 free(buf);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
172 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
173 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
174
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
175 effective_map = gif->Image.ColorMap;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
176 if (effective_map == NULL) effective_map = gif->SColorMap;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
177
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
178 {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
179 int y;
21883
3758ec905220 Simplify
reimar
parents: 21882
diff changeset
180 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
181 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
182 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
183 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
184 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
185 unsigned char *dest = dp->buffer + priv->w * t + l;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
186
21876
82dd482fb3ec cosmetics: typo fix pallete --> palette
diego
parents: 21875
diff changeset
187 // copy the palette
21881
a10888bc9758 Fix invalid read for gifs with a palette for less than 256 colors
reimar
parents: 21880
diff changeset
188 for (y = 0; y < cnt; y++) {
21893
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
189 priv->palette[(y * 4) + 0] = effective_map->Colors[y].Blue;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
190 priv->palette[(y * 4) + 1] = effective_map->Colors[y].Green;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
191 priv->palette[(y * 4) + 2] = effective_map->Colors[y].Red;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
192 priv->palette[(y * 4) + 3] = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
193 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
194
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
195 if (gif->Image.Interlace) {
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
196 uint8_t *s = buf;
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
197 int ih = (h - 0 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
198 memcpy_transp_pic(dest, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
199 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
200 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
201 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
202 ih = (h - 4 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
203 memcpy_transp_pic(dest + (priv->w << 2), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
204 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
205 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
206 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
207 ih = (h - 2 + 3) >> 2;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
208 memcpy_transp_pic(dest + (priv->w << 1), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
209 priv->w << 2, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
210 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
211 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
212 ih = (h - 1 + 1) >> 1;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
213 memcpy_transp_pic(dest + priv->w, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
214 priv->w << 1, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
215 transparency, transparent_col);
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
216 } else
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
217 memcpy_transp_pic(dest, buf, w, h, priv->w, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
218 transparency, transparent_col);
21892
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
219
23457
a124f3abc1ec Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents: 22605
diff changeset
220 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
221 if (refmode == 2 && priv->useref) {
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
222 dest = priv->refimg + priv->w * t + l;
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
223 memset(buf, gif->SBackGroundColor, len);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
224 memcpy_pic(dest, buf, w, h, priv->w, gif->Image.Width);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
225 }
21894
449b9fb6f67b Fix: refmodes 2 and 3 leave useref unchanged
reimar
parents: 21893
diff changeset
226 if (!(refmode & 2)) priv->useref = refmode & 1;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
227 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
228
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
229 free(buf);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
230
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
231 demuxer->video->dpos++;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
232 dp->pts = ((float)priv->current_pts) / 100;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
233 dp->pos = stream_tell(demuxer->stream);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
234 ds_add_packet(demuxer->video, dp);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
235
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
236 return 1;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
237 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
238
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
239 static demuxer_t* demux_open_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
240 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
241 gif_priv_t *priv = calloc(1, sizeof(gif_priv_t));
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
242 sh_video_t *sh_video = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
243 GifFileType *gif = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
244
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
245 priv->current_pts = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
246 demuxer->seekable = 0; // FIXME
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 // go back to the beginning
9345
fef4f1a9de5e compile fix
henry
parents: 9344
diff changeset
249 stream_seek(demuxer->stream,demuxer->stream->start_pos);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
250
27385
2113bd9c6bd9 Rename preprocessor directives related to image libraries.
diego
parents: 25707
diff changeset
251 #ifdef CONFIG_GIF_TVT_HACK
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
252 // 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
253 // 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
254 // 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
255 // 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
256 // 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
257 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
258 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
259 #else
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
260 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
261 #endif
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
262 if (!gif) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
263 PrintGifError();
32614
4558e2b7e68b Fix memleaks on error.
reimar
parents: 32123
diff changeset
264 free(priv);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
265 return NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
266 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
267
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
268 // create a new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
269 sh_video = new_sh_video(demuxer, 0);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
270
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
271 // make sure the demuxer knows about the new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
272 // (even though new_sh_video() ought to take care of it)
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
273 demuxer->video->sh = sh_video;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
274
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
275 // make sure that the video demuxer stream header knows about its
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
276 // parent video demuxer stream (this is getting wacky), or else
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
277 // video_read_properties() will choke
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
278 sh_video->ds = demuxer->video;
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 sh_video->format = mmioFOURCC(8, 'R', 'G', 'B');
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
281
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
282 sh_video->fps = 5.0f;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
283 sh_video->frametime = 1.0f / sh_video->fps;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
284
32123
a86413775fbe Replace sizeof(BITMAPINFOHEADER)
reimar
parents: 30570
diff changeset
285 sh_video->bih = malloc(sizeof(*sh_video->bih) + (256 * 4));
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
286 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
287 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
288 sh_video->bih->biHeight = priv->h = (uint16_t)gif->SHeight;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
289 sh_video->bih->biBitCount = 8;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
290 sh_video->bih->biPlanes = 2;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
291 priv->palette = (unsigned char *)(sh_video->bih + 1);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
292 priv->refimg = malloc(priv->w * priv->h);
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
293
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
294 priv->gif = gif;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
295 demuxer->priv = priv;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
296
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
297 return demuxer;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
298 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
299
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
300 static void demux_close_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
301 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
302 gif_priv_t *priv = demuxer->priv;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
303 if (!priv) return;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
304 if (priv->gif && DGifCloseFile(priv->gif) == GIF_ERROR)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
305 PrintGifError();
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
306 free(priv->refimg);
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
307 free(priv);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
308 }
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
309
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
310
25707
d4fe6e23283e Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents: 23457
diff changeset
311 const demuxer_desc_t demuxer_desc_gif = {
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
312 "GIF demuxer",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
313 "gif",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
314 "GIF",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
315 "Joey Parrish",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
316 "",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
317 DEMUXER_TYPE_GIF,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
318 0, // unsafe autodetect
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
319 gif_check_file,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
320 demux_gif_fill_buffer,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
321 demux_open_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
322 demux_close_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
323 NULL,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
324 NULL
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
325 };