annotate libmpdemux/demux_gif.c @ 29269:4d9de809b174

Add a hack to detect when we are writing into a Windows pipe since the fseek incorrectly does not fail like it should. This ensures we will not incorrectly append the file header at the end. Based on patch by Zhou Zongyi [zhouzongyi at pset.suntec.net]
author reimar
date Sat, 16 May 2009 13:59:53 +0000
parents 0f1b5b68af32
children 98dc6ae7ede2
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
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
50 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
51 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
52 }
9463
93375ee56629 gif library incompatibility fixes and prefere libungif over libgif. Patch by Joey Parrish <joey@nicewarrior.org>
alex
parents: 9345
diff changeset
53 #endif
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
54
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
55 static int gif_check_file(demuxer_t *demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
56 {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
57 if (stream_read_int24(demuxer->stream) == GIF_SIGNATURE)
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
58 return DEMUXER_TYPE_GIF;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
59 return 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
60 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
61
21920
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
62 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
63 int dstride, int sstride, int transp, uint8_t trans_col) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
64 if (transp) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
65 dstride -= w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
66 sstride -= w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
67 while (h-- > 0) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
68 int wleft = w;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
69 while (wleft-- > 0) {
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
70 if (*src != trans_col)
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
71 *dst = *src;
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 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
74 dst += dstride;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
75 src += sstride;
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
76 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
77 } else
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
78 memcpy_pic(dst, src, w, h, dstride, sstride);
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
79 }
65b2a9b3bd35 "Cosmetics" Introduce a memcpy function doing both transparent
reimar
parents: 21896
diff changeset
80
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
81 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
82 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
83 gif_priv_t *priv = demuxer->priv;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
84 GifFileType *gif = priv->gif;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
85 GifRecordType type = UNDEFINED_RECORD_TYPE;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
86 int len = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
87 demux_packet_t *dp = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
88 ColorMapObject *effective_map = NULL;
21921
e4265d11dc37 Change some types to uint8_t where appropriate
reimar
parents: 21920
diff changeset
89 uint8_t *buf = NULL;
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
90 int refmode = 0;
21895
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
91 int transparency = 0;
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
92 uint8_t transparent_col;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
93
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
94 while (type != IMAGE_DESC_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
95 if (DGifGetRecordType(gif, &type) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
96 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
97 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
98 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
99 if (type == TERMINATE_RECORD_TYPE)
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
100 return 0; // eof
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
101 if (type == SCREEN_DESC_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
102 if (DGifGetScreenDesc(gif) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
103 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
104 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
105 }
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 if (type == EXTENSION_RECORD_TYPE) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
108 int code;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
109 unsigned char *p = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
110 if (DGifGetExtension(gif, &code, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
111 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
112 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
113 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
114 if (code == 0xF9) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
115 int frametime = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
116 if (p[0] == 4) // is the length correct?
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
117 {
21895
5d9486bbc156 Implement gif transparency
reimar
parents: 21894
diff changeset
118 transparency = p[1] & 1;
21896
b2640a639ac7 Cosmetics
reimar
parents: 21895
diff changeset
119 refmode = (p[1] >> 2) & 3;
22020
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
120 // HACK: specification says
a40f222a31df Hack: use refmode == 1 instead of == 0, as browsers behave like this
reimar
parents: 22019
diff changeset
121 // > 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
122 // 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
123 // > 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
124 // 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
125 // 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
126 if (refmode == 0) refmode = 1;
21875
d81cf0be50f0 Frametime was being read from the wrong offset, compare
diego
parents: 18958
diff changeset
127 frametime = (p[3] << 8) | p[2]; // set the time, centiseconds
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
128 transparent_col = p[4];
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
129 }
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
130 priv->current_pts += frametime;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
131 } else if ((code == 0xFE) && (verbose)) { // comment extension
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
132 // print iff verbose
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
133 printf("GIF comment: ");
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
134 while (p != NULL) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
135 int length = p[0];
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
136 char *comments = p + 1;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
137 comments[length] = 0;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
138 printf("%s", comments);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
139 if (DGifGetExtensionNext(gif, &p) == 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 printf("\n");
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
145 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
146 while (p != NULL) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
147 if (DGifGetExtensionNext(gif, &p) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
148 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
149 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
150 }
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 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
154
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
155 if (DGifGetImageDesc(gif) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
156 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
157 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
158 }
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 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
161 dp = new_demux_packet(priv->w * priv->h);
21890
84e155426ef9 memset + malloc -> calloc
reimar
parents: 21887
diff changeset
162 buf = calloc(gif->Image.Width, gif->Image.Height);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
163 if (priv->useref)
23457
a124f3abc1ec Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents: 22605
diff changeset
164 fast_memcpy(dp->buffer, priv->refimg, priv->w * priv->h);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
165 else
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
166 memset(dp->buffer, gif->SBackGroundColor, priv->w * priv->h);
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
167
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
168 if (DGifGetLine(gif, buf, len) == GIF_ERROR) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
169 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
170 return 0; // oops
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
171 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
172
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
173 effective_map = gif->Image.ColorMap;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
174 if (effective_map == NULL) effective_map = gif->SColorMap;
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 {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
177 int y;
21883
3758ec905220 Simplify
reimar
parents: 21882
diff changeset
178 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
179 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
180 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
181 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
182 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
183 unsigned char *dest = dp->buffer + priv->w * t + l;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
184
21876
82dd482fb3ec cosmetics: typo fix pallete --> palette
diego
parents: 21875
diff changeset
185 // copy the palette
21881
a10888bc9758 Fix invalid read for gifs with a palette for less than 256 colors
reimar
parents: 21880
diff changeset
186 for (y = 0; y < cnt; y++) {
21893
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
187 priv->palette[(y * 4) + 0] = effective_map->Colors[y].Blue;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
188 priv->palette[(y * 4) + 1] = effective_map->Colors[y].Green;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
189 priv->palette[(y * 4) + 2] = effective_map->Colors[y].Red;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
190 priv->palette[(y * 4) + 3] = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
191 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
192
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
193 if (gif->Image.Interlace) {
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
194 uint8_t *s = buf;
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
195 int ih = (h - 0 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
196 memcpy_transp_pic(dest, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
197 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
198 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
199 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
200 ih = (h - 4 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
201 memcpy_transp_pic(dest + (priv->w << 2), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
202 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
203 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
204 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
205 ih = (h - 2 + 3) >> 2;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
206 memcpy_transp_pic(dest + (priv->w << 1), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
207 priv->w << 2, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
208 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
209 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
210 ih = (h - 1 + 1) >> 1;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
211 memcpy_transp_pic(dest + priv->w, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
212 priv->w << 1, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
213 transparency, transparent_col);
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
214 } else
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
215 memcpy_transp_pic(dest, buf, w, h, priv->w, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
216 transparency, transparent_col);
21892
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
217
23457
a124f3abc1ec Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents: 22605
diff changeset
218 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
219 if (refmode == 2 && priv->useref) {
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
220 dest = priv->refimg + priv->w * t + l;
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
221 memset(buf, gif->SBackGroundColor, len);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
222 memcpy_pic(dest, buf, w, h, priv->w, gif->Image.Width);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
223 }
21894
449b9fb6f67b Fix: refmodes 2 and 3 leave useref unchanged
reimar
parents: 21893
diff changeset
224 if (!(refmode & 2)) priv->useref = refmode & 1;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
225 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
226
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
227 free(buf);
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 demuxer->video->dpos++;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
230 dp->pts = ((float)priv->current_pts) / 100;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
231 dp->pos = stream_tell(demuxer->stream);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
232 ds_add_packet(demuxer->video, dp);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
233
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
234 return 1;
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
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
237 static demuxer_t* demux_open_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
238 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
239 gif_priv_t *priv = calloc(1, sizeof(gif_priv_t));
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
240 sh_video_t *sh_video = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
241 GifFileType *gif = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
242
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
243 priv->current_pts = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
244 demuxer->seekable = 0; // FIXME
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
245
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
246 // go back to the beginning
9345
fef4f1a9de5e compile fix
henry
parents: 9344
diff changeset
247 stream_seek(demuxer->stream,demuxer->stream->start_pos);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
248
27385
2113bd9c6bd9 Rename preprocessor directives related to image libraries.
diego
parents: 25707
diff changeset
249 #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
250 // 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
251 // 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
252 // 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
253 // 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
254 // 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
255 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
256 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
257 #else
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
258 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
259 #endif
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
260 if (!gif) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
261 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
262 return NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
263 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
264
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
265 // create a new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
266 sh_video = new_sh_video(demuxer, 0);
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 // make sure the demuxer knows about the new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
269 // (even though new_sh_video() ought to take care of it)
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
270 demuxer->video->sh = sh_video;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
271
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
272 // make sure that the video demuxer stream header knows about its
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
273 // parent video demuxer stream (this is getting wacky), or else
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
274 // video_read_properties() will choke
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
275 sh_video->ds = demuxer->video;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
276
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
277 sh_video->format = mmioFOURCC(8, 'R', 'G', 'B');
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
278
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
279 sh_video->fps = 5.0f;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
280 sh_video->frametime = 1.0f / sh_video->fps;
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->bih = malloc(sizeof(BITMAPINFOHEADER) + (256 * 4));
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
283 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
284 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
285 sh_video->bih->biHeight = priv->h = (uint16_t)gif->SHeight;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
286 sh_video->bih->biBitCount = 8;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
287 sh_video->bih->biPlanes = 2;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
288 priv->palette = (unsigned char *)(sh_video->bih + 1);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
289 priv->refimg = malloc(priv->w * priv->h);
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
290
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
291 priv->gif = gif;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
292 demuxer->priv = priv;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
293
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
294 return demuxer;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
295 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
296
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
297 static void demux_close_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
298 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
299 gif_priv_t *priv = demuxer->priv;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
300 if (!priv) return;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
301 if (priv->gif && DGifCloseFile(priv->gif) == GIF_ERROR)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
302 PrintGifError();
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
303 free(priv->refimg);
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
304 free(priv);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
305 }
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
306
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
307
25707
d4fe6e23283e Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents: 23457
diff changeset
308 const demuxer_desc_t demuxer_desc_gif = {
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
309 "GIF demuxer",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
310 "gif",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
311 "GIF",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
312 "Joey Parrish",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
313 "",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
314 DEMUXER_TYPE_GIF,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
315 0, // unsafe autodetect
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
316 gif_check_file,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
317 demux_gif_fill_buffer,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
318 demux_open_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
319 demux_close_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
320 NULL,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
321 NULL
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
322 };