annotate libmpdemux/demux_gif.c @ 30799:76f3878f34fd

libswscale: Extend the unaccelerated path of the unscaled yuv2rgb special converter with support for rgb444 output format. Patch by Janusz Krzysztofik jkrzyszt chez tis icnet pl
author benoit
date Fri, 05 Mar 2010 08:32:54 +0000
parents 98dc6ae7ede2
children a86413775fbe
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();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
171 return 0; // oops
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
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
174 effective_map = gif->Image.ColorMap;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
175 if (effective_map == NULL) effective_map = gif->SColorMap;
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 {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
178 int y;
21883
3758ec905220 Simplify
reimar
parents: 21882
diff changeset
179 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
180 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
181 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
182 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
183 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
184 unsigned char *dest = dp->buffer + priv->w * t + l;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
185
21876
82dd482fb3ec cosmetics: typo fix pallete --> palette
diego
parents: 21875
diff changeset
186 // copy the palette
21881
a10888bc9758 Fix invalid read for gifs with a palette for less than 256 colors
reimar
parents: 21880
diff changeset
187 for (y = 0; y < cnt; y++) {
21893
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
188 priv->palette[(y * 4) + 0] = effective_map->Colors[y].Blue;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
189 priv->palette[(y * 4) + 1] = effective_map->Colors[y].Green;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
190 priv->palette[(y * 4) + 2] = effective_map->Colors[y].Red;
4a83d090520c Cosmetics
reimar
parents: 21892
diff changeset
191 priv->palette[(y * 4) + 3] = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
192 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
193
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
194 if (gif->Image.Interlace) {
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
195 uint8_t *s = buf;
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
196 int ih = (h - 0 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
197 memcpy_transp_pic(dest, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
198 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
199 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
200 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
201 ih = (h - 4 + 7) >> 3;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
202 memcpy_transp_pic(dest + (priv->w << 2), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
203 priv->w << 3, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
204 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
205 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
206 ih = (h - 2 + 3) >> 2;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
207 memcpy_transp_pic(dest + (priv->w << 1), s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
208 priv->w << 2, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
209 transparency, transparent_col);
22024
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
210 s += ih * w;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
211 ih = (h - 1 + 1) >> 1;
4139d35bf255 Fix number of rows in interlaced mode.
reimar
parents: 22022
diff changeset
212 memcpy_transp_pic(dest + priv->w, s, w, ih,
21922
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
213 priv->w << 1, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
214 transparency, transparent_col);
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
215 } else
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
216 memcpy_transp_pic(dest, buf, w, h, priv->w, gif->Image.Width,
277f0943aa4e Interlaced gif support
reimar
parents: 21921
diff changeset
217 transparency, transparent_col);
21892
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
218
23457
a124f3abc1ec Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents: 22605
diff changeset
219 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
220 if (refmode == 2 && priv->useref) {
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
221 dest = priv->refimg + priv->w * t + l;
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
222 memset(buf, gif->SBackGroundColor, len);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
223 memcpy_pic(dest, buf, w, h, priv->w, gif->Image.Width);
cf67d7115d99 Implement refmode == 2 in gif demuxer
reimar
parents: 21891
diff changeset
224 }
21894
449b9fb6f67b Fix: refmodes 2 and 3 leave useref unchanged
reimar
parents: 21893
diff changeset
225 if (!(refmode & 2)) priv->useref = refmode & 1;
9133
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
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
228 free(buf);
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 demuxer->video->dpos++;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
231 dp->pts = ((float)priv->current_pts) / 100;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
232 dp->pos = stream_tell(demuxer->stream);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
233 ds_add_packet(demuxer->video, dp);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
234
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
235 return 1;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
236 }
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
237
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
238 static demuxer_t* demux_open_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
239 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
240 gif_priv_t *priv = calloc(1, sizeof(gif_priv_t));
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
241 sh_video_t *sh_video = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
242 GifFileType *gif = NULL;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
243
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
244 priv->current_pts = 0;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
245 demuxer->seekable = 0; // FIXME
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
246
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
247 // go back to the beginning
9345
fef4f1a9de5e compile fix
henry
parents: 9344
diff changeset
248 stream_seek(demuxer->stream,demuxer->stream->start_pos);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
249
27385
2113bd9c6bd9 Rename preprocessor directives related to image libraries.
diego
parents: 25707
diff changeset
250 #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
251 // 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
252 // 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
253 // 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
254 // 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
255 // 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
256 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
257 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
258 #else
9344
bd7b5078475e 1) codecs.conf changed recently and demux_gif no longer needs to spit
arpi
parents: 9133
diff changeset
259 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
260 #endif
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
261 if (!gif) {
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
262 PrintGifError();
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
263 return NULL;
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
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
266 // create a new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
267 sh_video = new_sh_video(demuxer, 0);
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
268
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
269 // make sure the demuxer knows about the new video stream header
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
270 // (even though new_sh_video() ought to take care of it)
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
271 demuxer->video->sh = sh_video;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
272
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
273 // make sure that the video demuxer stream header knows about its
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
274 // parent video demuxer stream (this is getting wacky), or else
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
275 // video_read_properties() will choke
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
276 sh_video->ds = demuxer->video;
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 sh_video->format = mmioFOURCC(8, 'R', 'G', 'B');
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
279
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
280 sh_video->fps = 5.0f;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
281 sh_video->frametime = 1.0f / sh_video->fps;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
282
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
283 sh_video->bih = malloc(sizeof(BITMAPINFOHEADER) + (256 * 4));
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
284 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
285 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
286 sh_video->bih->biHeight = priv->h = (uint16_t)gif->SHeight;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
287 sh_video->bih->biBitCount = 8;
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
288 sh_video->bih->biPlanes = 2;
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
289 priv->palette = (unsigned char *)(sh_video->bih + 1);
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
290 priv->refimg = malloc(priv->w * priv->h);
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29238
diff changeset
291
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
292 priv->gif = gif;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
293 demuxer->priv = priv;
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
294
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
295 return demuxer;
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
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
298 static void demux_close_gif(demuxer_t* demuxer)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
299 {
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
300 gif_priv_t *priv = demuxer->priv;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
301 if (!priv) return;
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
302 if (priv->gif && DGifCloseFile(priv->gif) == GIF_ERROR)
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
303 PrintGifError();
21891
d718eeaf06ea Partially support gif using "reference" images
reimar
parents: 21890
diff changeset
304 free(priv->refimg);
21880
4e22e06485c6 Move global variables in gif demuxer into priv struct
reimar
parents: 21876
diff changeset
305 free(priv);
9133
a45282d6ad32 argh, i forgot to 'cvs add' it (again)
arpi
parents:
diff changeset
306 }
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
307
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
308
25707
d4fe6e23283e Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents: 23457
diff changeset
309 const demuxer_desc_t demuxer_desc_gif = {
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
310 "GIF demuxer",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
311 "gif",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
312 "GIF",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
313 "Joey Parrish",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
314 "",
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
315 DEMUXER_TYPE_GIF,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
316 0, // unsafe autodetect
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
317 gif_check_file,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
318 demux_gif_fill_buffer,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
319 demux_open_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
320 demux_close_gif,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
321 NULL,
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
322 NULL
6b86089c2edd Demuxer modularization
rtognimp
parents: 9463
diff changeset
323 };