aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/gif_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gif_extractor.c')
-rw-r--r--src/plugins/gif_extractor.c75
1 files changed, 43 insertions, 32 deletions
diff --git a/src/plugins/gif_extractor.c b/src/plugins/gif_extractor.c
index 69760eb..055fd9f 100644
--- a/src/plugins/gif_extractor.c
+++ b/src/plugins/gif_extractor.c
@@ -29,12 +29,12 @@
29#define PRINT(a,b) 29#define PRINT(a,b)
30#endif 30#endif
31 31
32typedef struct 32struct GifHeader
33{ 33{
34 char gif[3]; 34 char gif[3];
35 char version[3]; 35 char version[3];
36 unsigned short screen_width; 36 uint16_t screen_width;
37 unsigned short screen_height; 37 uint16_t screen_height;
38 unsigned char flags; 38 unsigned char flags;
39#define HEADER_FLAGS__SIZE_OF_GLOBAL_COLOR_TABLE 0x07 39#define HEADER_FLAGS__SIZE_OF_GLOBAL_COLOR_TABLE 0x07
40#define HEADER_FLAGS__SORT_FLAG 0x08 40#define HEADER_FLAGS__SORT_FLAG 0x08
@@ -42,7 +42,7 @@ typedef struct
42#define HEADER_FLAGS__GLOBAL_COLOR_TABLE_FLAG 0x80 42#define HEADER_FLAGS__GLOBAL_COLOR_TABLE_FLAG 0x80
43 unsigned char background_color_index; 43 unsigned char background_color_index;
44 unsigned char pixel_aspect_ratio; 44 unsigned char pixel_aspect_ratio;
45} GIF_HEADER; 45};
46 46
47#define GIF_HEADER_SIZE 13 47#define GIF_HEADER_SIZE 13
48#define GIF_HEADER_SPEC "3b3bhhbbb" 48#define GIF_HEADER_SPEC "3b3bhhbbb"
@@ -55,20 +55,21 @@ typedef struct
55 &(p)->background_color_index, \ 55 &(p)->background_color_index, \
56 &(p)->pixel_aspect_ratio 56 &(p)->pixel_aspect_ratio
57 57
58typedef struct 58struct GifDescriptor
59{ 59{
60 unsigned char image_separator; 60 unsigned char image_separator;
61 unsigned short image_left; 61 uint16_t image_left;
62 unsigned short image_top; 62 uint16_t image_top;
63 unsigned short image_width; 63 uint16_t image_width;
64 unsigned short image_height; 64 uint16_t image_height;
65 unsigned char flags; 65 unsigned char flags;
66#define DESCRIPTOR_FLAGS__PIXEL_SIZE 0x07 66#define DESCRIPTOR_FLAGS__PIXEL_SIZE 0x07
67#define DESCRIPTOR_FLAGS__RESERVED 0x18 67#define DESCRIPTOR_FLAGS__RESERVED 0x18
68#define DESCRIPTOR_FLAGS__SORT_FLAG 0x20 68#define DESCRIPTOR_FLAGS__SORT_FLAG 0x20
69#define DESCRIPTOR_FLAGS__INTERLACE_FLAG 0x40 69#define DESCRIPTOR_FLAGS__INTERLACE_FLAG 0x40
70#define DESCRIPTOR_FLAGS__LOCAL_COLOR_TABLE_FLAG 0x80 70#define DESCRIPTOR_FLAGS__LOCAL_COLOR_TABLE_FLAG 0x80
71} GIF_DESCRIPTOR; 71};
72
72#define GIF_DESCRIPTOR_SIZE 10 73#define GIF_DESCRIPTOR_SIZE 10
73#define GIF_DESCRIPTOR_SPEC "chhhhc" 74#define GIF_DESCRIPTOR_SPEC "chhhhc"
74#define GIF_DESCRIPTOR_FIELDS(p) \ 75#define GIF_DESCRIPTOR_FIELDS(p) \
@@ -79,16 +80,16 @@ typedef struct
79 &(p)->image_height, \ 80 &(p)->image_height, \
80 &(p)->flags 81 &(p)->flags
81 82
82typedef struct 83struct GifExtension
83{ 84{
84 unsigned char extension_introducer; 85 unsigned char extension_introducer;
85 unsigned char graphic_control_label; 86 unsigned char graphic_control_label;
86} GIF_EXTENSION; 87};
87 88
88/** 89/**
89 * Skip a data block. 90 * Skip a data block.
90 * @return the position after the block 91 * @return the position after the block
91 **/ 92 */
92static size_t 93static size_t
93skipDataBlock (const unsigned char *data, size_t pos, const size_t size) 94skipDataBlock (const unsigned char *data, size_t pos, const size_t size)
94{ 95{
@@ -100,20 +101,22 @@ skipDataBlock (const unsigned char *data, size_t pos, const size_t size)
100/** 101/**
101 * skip an extention block 102 * skip an extention block
102 * @return the position after the block 103 * @return the position after the block
103 **/ 104 */
104static size_t 105static size_t
105skipExtensionBlock (const unsigned char *data, 106skipExtensionBlock (const unsigned char *data,
106 size_t pos, const size_t size, const GIF_EXTENSION * ext) 107 size_t pos, const size_t size,
108 const struct GifExtension * ext)
107{ 109{
108 return skipDataBlock (data, pos + sizeof (GIF_EXTENSION), size); 110 return skipDataBlock (data, pos + sizeof (struct GifExtension), size);
109} 111}
110 112
111/** 113/**
112 * @return the offset after the global color map 114 * @return the offset after the global color map
113 **/ 115 */
114static size_t 116static size_t
115skipGlobalColorMap (const unsigned char *data, 117skipGlobalColorMap (const unsigned char *data,
116 const size_t size, const GIF_HEADER * header) 118 const size_t size,
119 const struct GifHeader * header)
117{ 120{
118 size_t gct_size; 121 size_t gct_size;
119 122
@@ -128,10 +131,11 @@ skipGlobalColorMap (const unsigned char *data,
128 131
129/** 132/**
130 * @return the offset after the local color map 133 * @return the offset after the local color map
131 **/ 134 */
132static size_t 135static size_t
133skipLocalColorMap (const unsigned char *data, 136skipLocalColorMap (const unsigned char *data,
134 size_t pos, const size_t size, GIF_DESCRIPTOR * descriptor) 137 size_t pos, const size_t size,
138 const struct GifDescriptor * descriptor)
135{ 139{
136 size_t lct_size; 140 size_t lct_size;
137 141
@@ -151,31 +155,38 @@ parseComment (const unsigned char *data,
151 EXTRACTOR_MetaDataProcessor proc, 155 EXTRACTOR_MetaDataProcessor proc,
152 void *proc_cls) 156 void *proc_cls)
153{ 157{
154 size_t length = 0; 158 size_t length;
159 size_t off;
155 size_t curr = pos; 160 size_t curr = pos;
156 int ret; 161 int ret;
157 162
158 while ((data[curr] != 0) && (curr < size)) 163 length = 0;
164 while ( (curr < size) &&
165 (data[curr] != 0) )
159 { 166 {
160 length += data[curr]; 167 length += data[curr];
161 curr += data[curr] + 1; 168 curr += data[curr] + 1;
162 if (length > 65536) 169 if (length > 65536)
163 break; 170 break;
164 } 171 }
165 if (length < 65536) 172 if ( (length < 65536) &&
173 (curr < size) )
166 { 174 {
167 char comment[length+1]; 175 char comment[length+1];
176
168 curr = pos; 177 curr = pos;
169 length = 0; 178 off = 0;
170 while ((data[curr] != 0) && (curr < size)) 179 while ((data[curr] != 0) && (curr < size))
171 { 180 {
172 length += data[curr]; 181 if (off + data[curr] >= size)
173 if (length >= size)
174 break; 182 break;
175 memcpy (&comment[length - data[curr]], &data[curr] + 1, data[curr]); 183 memcpy (&comment[off],
176 comment[length] = '\0'; 184 &data[curr] + 1,
185 data[curr]);
186 off += data[curr];
177 curr += data[curr] + 1; 187 curr += data[curr] + 1;
178 } 188 }
189 comment[off] = '\0';
179 ret = proc (proc_cls, 190 ret = proc (proc_cls,
180 "gif", 191 "gif",
181 EXTRACTOR_METATYPE_COMMENT, 192 EXTRACTOR_METATYPE_COMMENT,
@@ -186,6 +197,7 @@ parseComment (const unsigned char *data,
186 } 197 }
187 else 198 else
188 { 199 {
200 /* too big */
189 ret = 0; 201 ret = 0;
190 } 202 }
191 return ret; 203 return ret;
@@ -200,7 +212,8 @@ EXTRACTOR_gif_extract (const unsigned char *data,
200 const char *options) 212 const char *options)
201{ 213{
202 size_t pos; 214 size_t pos;
203 GIF_HEADER header; 215 struct GifHeader header;
216 struct GifDescriptor gd;
204 char tmp[128]; 217 char tmp[128];
205 218
206 if (size < GIF_HEADER_SIZE) 219 if (size < GIF_HEADER_SIZE)
@@ -234,8 +247,6 @@ EXTRACTOR_gif_extract (const unsigned char *data,
234 PRINT ("global color map ends at %d\n", pos); 247 PRINT ("global color map ends at %d\n", pos);
235 while (pos < size) 248 while (pos < size)
236 { 249 {
237 GIF_DESCRIPTOR gd;
238
239 switch (data[pos]) 250 switch (data[pos])
240 { 251 {
241 case ',': /* image descriptor block */ 252 case ',': /* image descriptor block */
@@ -253,7 +264,7 @@ EXTRACTOR_gif_extract (const unsigned char *data,
253 return 1; 264 return 1;
254 } 265 }
255 pos = skipExtensionBlock (data, pos, size, 266 pos = skipExtensionBlock (data, pos, size,
256 (GIF_EXTENSION *) & data[pos]); 267 (const struct GifExtension *) & data[pos]);
257 break; 268 break;
258 case ';': 269 case ';':
259 PRINT ("hit terminator at %d!\n", pos); 270 PRINT ("hit terminator at %d!\n", pos);