diff options
Diffstat (limited to 'src/plugins/old/real_extractor.c')
-rw-r--r-- | src/plugins/old/real_extractor.c | 439 |
1 files changed, 0 insertions, 439 deletions
diff --git a/src/plugins/old/real_extractor.c b/src/plugins/old/real_extractor.c deleted file mode 100644 index cfac031..0000000 --- a/src/plugins/old/real_extractor.c +++ /dev/null | |||
@@ -1,439 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | Copyright (C) 2002, 2003, 2009 Vidyut Samanta and Christian Grothoff | ||
4 | |||
5 | libextractor is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | libextractor is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with libextractor; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #include "platform.h" | ||
22 | #include "extractor.h" | ||
23 | #include <stdint.h> | ||
24 | |||
25 | #define UINT32 uint32_t | ||
26 | #define UINT16 uint16_t | ||
27 | #define UINT8 uint8_t | ||
28 | |||
29 | typedef struct | ||
30 | { | ||
31 | UINT32 object_id; | ||
32 | UINT32 size; | ||
33 | UINT16 object_version; /* must be 0 */ | ||
34 | UINT16 stream_number; | ||
35 | UINT32 max_bit_rate; | ||
36 | UINT32 avg_bit_rate; | ||
37 | UINT32 max_packet_size; | ||
38 | UINT32 avg_packet_size; | ||
39 | UINT32 start_time; | ||
40 | UINT32 preroll; | ||
41 | UINT32 duration; | ||
42 | UINT8 stream_name_size; | ||
43 | UINT8 data[0]; /* variable length section */ | ||
44 | /* | ||
45 | UINT8[stream_name_size] stream_name; | ||
46 | UINT8 mime_type_size; | ||
47 | UINT8[mime_type_size] mime_type; | ||
48 | UINT32 type_specific_len; | ||
49 | UINT8[type_specific_len] type_specific_data; | ||
50 | */ | ||
51 | } Media_Properties; | ||
52 | |||
53 | typedef struct | ||
54 | { | ||
55 | UINT32 object_id; | ||
56 | UINT32 size; | ||
57 | UINT16 object_version; /* must be 0 */ | ||
58 | UINT16 title_len; | ||
59 | UINT8 data[0]; /* variable length section */ | ||
60 | /* | ||
61 | UINT8[title_len] title; | ||
62 | UINT16 author_len; | ||
63 | UINT8[author_len] author; | ||
64 | UINT16 copyright_len; | ||
65 | UINT8[copyright_len] copyright; | ||
66 | UINT16 comment_len; | ||
67 | UINT8[comment_len] comment; | ||
68 | */ | ||
69 | } Content_Description; | ||
70 | /* author, copyright and comment are supposed to be ASCII */ | ||
71 | |||
72 | #define REAL_HEADER 0x2E524d46 | ||
73 | #define MDPR_HEADER 0x4D445052 | ||
74 | #define CONT_HEADER 0x434F4e54 | ||
75 | |||
76 | #define RAFF4_HEADER 0x2E7261FD | ||
77 | |||
78 | |||
79 | static int | ||
80 | processMediaProperties (const Media_Properties *prop, | ||
81 | EXTRACTOR_MetaDataProcessor proc, | ||
82 | void *proc_cls) | ||
83 | { | ||
84 | |||
85 | UINT8 mime_type_size; | ||
86 | UINT32 prop_size; | ||
87 | |||
88 | prop_size = ntohl (prop->size); | ||
89 | if (prop_size <= sizeof (Media_Properties)) | ||
90 | return 0; | ||
91 | if (0 != prop->object_version) | ||
92 | return 0; | ||
93 | if (prop_size <= prop->stream_name_size + sizeof (UINT8) | ||
94 | + sizeof (Media_Properties)) | ||
95 | return 0; | ||
96 | |||
97 | mime_type_size = prop->data[prop->stream_name_size]; | ||
98 | if (prop_size > prop->stream_name_size + sizeof (UINT8) | ||
99 | + +mime_type_size + sizeof (Media_Properties)) | ||
100 | { | ||
101 | char data[mime_type_size + 1]; | ||
102 | memcpy (data, &prop->data[prop->stream_name_size + 1], mime_type_size); | ||
103 | data[mime_type_size] = '\0'; | ||
104 | |||
105 | return proc (proc_cls, | ||
106 | "real", | ||
107 | EXTRACTOR_METATYPE_MIMETYPE, | ||
108 | EXTRACTOR_METAFORMAT_UTF8, | ||
109 | "text/plain", | ||
110 | data, | ||
111 | strlen (data)); | ||
112 | } | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | |||
117 | static int | ||
118 | processContentDescription (const Content_Description *prop, | ||
119 | EXTRACTOR_MetaDataProcessor proc, | ||
120 | void *proc_cls) | ||
121 | { | ||
122 | UINT16 author_len; | ||
123 | UINT16 copyright_len; | ||
124 | UINT16 comment_len; | ||
125 | UINT16 title_len; | ||
126 | char *title; | ||
127 | char *author; | ||
128 | char *copyright; | ||
129 | char *comment; | ||
130 | UINT32 prop_size; | ||
131 | int ret; | ||
132 | |||
133 | prop_size = ntohl (prop->size); | ||
134 | if (prop_size <= sizeof (Content_Description)) | ||
135 | return 0; | ||
136 | if (0 != prop->object_version) | ||
137 | return 0; | ||
138 | title_len = ntohs (prop->title_len); | ||
139 | if (prop_size <= title_len + sizeof (UINT16) + sizeof (Content_Description)) | ||
140 | return 0; | ||
141 | author_len = ntohs (*(UINT16 *) &prop->data[title_len]); | ||
142 | if (prop_size <= title_len + sizeof (UINT16) | ||
143 | + author_len + sizeof (Content_Description)) | ||
144 | return 0; | ||
145 | |||
146 | copyright_len = ntohs (*(UINT16 *) &prop->data[title_len | ||
147 | + author_len | ||
148 | + sizeof (UINT16)]); | ||
149 | |||
150 | if (prop_size <= title_len + 2 * sizeof (UINT16) | ||
151 | + author_len + copyright_len + sizeof (Content_Description)) | ||
152 | return 0; | ||
153 | |||
154 | comment_len = ntohs (*(UINT16 *) &prop->data[title_len | ||
155 | + author_len | ||
156 | + copyright_len | ||
157 | + 2 * sizeof (UINT16)]); | ||
158 | |||
159 | if (prop_size < title_len + 3 * sizeof (UINT16) | ||
160 | + author_len + copyright_len + comment_len | ||
161 | + sizeof (Content_Description)) | ||
162 | return 0; | ||
163 | |||
164 | ret = 0; | ||
165 | title = malloc (title_len + 1); | ||
166 | if (title != NULL) | ||
167 | { | ||
168 | memcpy (title, &prop->data[0], title_len); | ||
169 | title[title_len] = '\0'; | ||
170 | ret = proc (proc_cls, | ||
171 | "real", | ||
172 | EXTRACTOR_METATYPE_TITLE, | ||
173 | EXTRACTOR_METAFORMAT_UTF8, | ||
174 | "text/plain", | ||
175 | title, | ||
176 | strlen (title) + 1); | ||
177 | free (title); | ||
178 | } | ||
179 | if (ret != 0) | ||
180 | return ret; | ||
181 | |||
182 | author = malloc (author_len + 1); | ||
183 | if (author != NULL) | ||
184 | { | ||
185 | memcpy (author, &prop->data[title_len + sizeof (UINT16)], author_len); | ||
186 | author[author_len] = '\0'; | ||
187 | ret = proc (proc_cls, | ||
188 | "real", | ||
189 | EXTRACTOR_METATYPE_AUTHOR_NAME, | ||
190 | EXTRACTOR_METAFORMAT_UTF8, | ||
191 | "text/plain", | ||
192 | author, | ||
193 | strlen (author) + 1); | ||
194 | free (author); | ||
195 | } | ||
196 | if (ret != 0) | ||
197 | return ret; | ||
198 | |||
199 | copyright = malloc (copyright_len + 1); | ||
200 | if (copyright != NULL) | ||
201 | { | ||
202 | memcpy (copyright, | ||
203 | &prop->data[title_len + sizeof (UINT16) * 2 + author_len], | ||
204 | copyright_len); | ||
205 | copyright[copyright_len] = '\0'; | ||
206 | ret = proc (proc_cls, | ||
207 | "real", | ||
208 | EXTRACTOR_METATYPE_COPYRIGHT, | ||
209 | EXTRACTOR_METAFORMAT_UTF8, | ||
210 | "text/plain", | ||
211 | copyright, | ||
212 | strlen (copyright) + 1); | ||
213 | free (copyright); | ||
214 | } | ||
215 | if (ret != 0) | ||
216 | return ret; | ||
217 | |||
218 | comment = malloc (comment_len + 1); | ||
219 | if (comment != NULL) | ||
220 | { | ||
221 | memcpy (comment, | ||
222 | &prop->data[title_len + sizeof (UINT16) * 3 + author_len | ||
223 | + copyright_len], comment_len); | ||
224 | comment[comment_len] = '\0'; | ||
225 | ret = proc (proc_cls, | ||
226 | "real", | ||
227 | EXTRACTOR_METATYPE_COMMENT, | ||
228 | EXTRACTOR_METAFORMAT_UTF8, | ||
229 | "text/plain", | ||
230 | comment, | ||
231 | strlen (comment) + 1); | ||
232 | free (comment); | ||
233 | } | ||
234 | if (ret != 0) | ||
235 | return ret; | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | |||
240 | typedef struct RAFF4_header | ||
241 | { | ||
242 | unsigned short version; | ||
243 | unsigned short revision; | ||
244 | unsigned short header_length; | ||
245 | unsigned short compression_type; | ||
246 | unsigned int granularity; | ||
247 | unsigned int total_bytes; | ||
248 | unsigned int bytes_per_minute; | ||
249 | unsigned int bytes_per_minute2; | ||
250 | unsigned short interleave_factor; | ||
251 | unsigned short interleave_block_size; | ||
252 | unsigned int user_data; | ||
253 | float sample_rate; | ||
254 | unsigned short sample_size; | ||
255 | unsigned short channels; | ||
256 | unsigned char interleave_code[5]; | ||
257 | unsigned char compression_code[5]; | ||
258 | unsigned char is_interleaved; | ||
259 | unsigned char copy_byte; | ||
260 | unsigned char stream_type; | ||
261 | /* | ||
262 | unsigned char tlen; | ||
263 | unsigned char title[tlen]; | ||
264 | unsigned char alen; | ||
265 | unsigned char author[alen]; | ||
266 | unsigned char clen; | ||
267 | unsigned char copyright[clen]; | ||
268 | unsigned char aplen; | ||
269 | unsigned char app[aplen]; */ | ||
270 | } RAFF4_header; | ||
271 | |||
272 | #define RAFF4_HDR_SIZE 53 | ||
273 | |||
274 | static char * | ||
275 | stndup (const char *str, size_t n) | ||
276 | { | ||
277 | char *tmp; | ||
278 | tmp = malloc (n + 1); | ||
279 | if (tmp == NULL) | ||
280 | return NULL; | ||
281 | tmp[n] = '\0'; | ||
282 | memcpy (tmp, str, n); | ||
283 | return tmp; | ||
284 | } | ||
285 | |||
286 | |||
287 | /* audio/vnd.rn-realaudio */ | ||
288 | int | ||
289 | EXTRACTOR_real_extract (const unsigned char *data, | ||
290 | size_t size, | ||
291 | EXTRACTOR_MetaDataProcessor proc, | ||
292 | void *proc_cls, | ||
293 | const char *options) | ||
294 | { | ||
295 | const unsigned char *pos; | ||
296 | const unsigned char *end; | ||
297 | unsigned int length; | ||
298 | const RAFF4_header *hdr; | ||
299 | unsigned char tlen; | ||
300 | unsigned char alen; | ||
301 | unsigned char clen; | ||
302 | unsigned char aplen; | ||
303 | char *x; | ||
304 | int ret; | ||
305 | |||
306 | if (size <= 2 * sizeof (int)) | ||
307 | return 0; | ||
308 | if (RAFF4_HEADER == ntohl (*(int *) data)) | ||
309 | { | ||
310 | /* HELIX */ | ||
311 | if (size <= RAFF4_HDR_SIZE + 16 + 4) | ||
312 | return 0; | ||
313 | if (0 != proc (proc_cls, | ||
314 | "real", | ||
315 | EXTRACTOR_METATYPE_MIMETYPE, | ||
316 | EXTRACTOR_METAFORMAT_UTF8, | ||
317 | "text/plain", | ||
318 | "audio/vnd.rn-realaudio", | ||
319 | strlen ("audio/vnd.rn-realaudio") + 1)) | ||
320 | return 1; | ||
321 | hdr = (const RAFF4_header *) &data[16]; | ||
322 | if (ntohs (hdr->header_length) + 16 > size) | ||
323 | return 0; | ||
324 | tlen = data[16 + RAFF4_HDR_SIZE]; | ||
325 | if (tlen + RAFF4_HDR_SIZE + 20 > size) | ||
326 | return 0; | ||
327 | alen = data[17 + tlen + RAFF4_HDR_SIZE]; | ||
328 | if (tlen + alen + RAFF4_HDR_SIZE + 20 > size) | ||
329 | return 0; | ||
330 | clen = data[18 + tlen + alen + RAFF4_HDR_SIZE]; | ||
331 | if (tlen + alen + clen + RAFF4_HDR_SIZE + 20 > size) | ||
332 | return 0; | ||
333 | aplen = data[19 + tlen + clen + alen + RAFF4_HDR_SIZE]; | ||
334 | if (tlen + alen + clen + aplen + RAFF4_HDR_SIZE + 20 > size) | ||
335 | return 0; | ||
336 | ret = 0; | ||
337 | if ( (tlen > 0) && (ret == 0) ) | ||
338 | { | ||
339 | x = stndup ((const char *) &data[17 + RAFF4_HDR_SIZE], tlen); | ||
340 | if (x != NULL) | ||
341 | { | ||
342 | ret = proc (proc_cls, | ||
343 | "real", | ||
344 | EXTRACTOR_METATYPE_MIMETYPE, | ||
345 | EXTRACTOR_METAFORMAT_UTF8, | ||
346 | "text/plain", | ||
347 | x, | ||
348 | strlen (x) + 1); | ||
349 | free (x); | ||
350 | } | ||
351 | } | ||
352 | if ( (alen > 0) && (ret == 0) ) | ||
353 | { | ||
354 | x = stndup ((const char *) &data[18 + RAFF4_HDR_SIZE + tlen], alen); | ||
355 | if (x != NULL) | ||
356 | { | ||
357 | ret = proc (proc_cls, | ||
358 | "real", | ||
359 | EXTRACTOR_METATYPE_MIMETYPE, | ||
360 | EXTRACTOR_METAFORMAT_UTF8, | ||
361 | "text/plain", | ||
362 | x, | ||
363 | strlen (x) + 1); | ||
364 | free (x); | ||
365 | } | ||
366 | } | ||
367 | if ( (clen > 0) && (ret == 0) ) | ||
368 | { | ||
369 | x = stndup ((const char *) &data[19 + RAFF4_HDR_SIZE + tlen + alen], | ||
370 | clen); | ||
371 | if (x != NULL) | ||
372 | { | ||
373 | ret = proc (proc_cls, | ||
374 | "real", | ||
375 | EXTRACTOR_METATYPE_MIMETYPE, | ||
376 | EXTRACTOR_METAFORMAT_UTF8, | ||
377 | "text/plain", | ||
378 | x, | ||
379 | strlen (x) + 1); | ||
380 | free (x); | ||
381 | } | ||
382 | } | ||
383 | if ( (aplen > 0) && (ret == 0) ) | ||
384 | { | ||
385 | x = stndup ((const char *) &data[20 + RAFF4_HDR_SIZE + tlen + alen | ||
386 | + clen], aplen); | ||
387 | if (x != NULL) | ||
388 | { | ||
389 | ret = proc (proc_cls, | ||
390 | "real", | ||
391 | EXTRACTOR_METATYPE_MIMETYPE, | ||
392 | EXTRACTOR_METAFORMAT_UTF8, | ||
393 | "text/plain", | ||
394 | x, | ||
395 | strlen (x) + 1); | ||
396 | free (x); | ||
397 | } | ||
398 | } | ||
399 | return ret; | ||
400 | } | ||
401 | if (REAL_HEADER == ntohl (*(int *) data)) | ||
402 | { | ||
403 | /* old real */ | ||
404 | end = &data[size]; | ||
405 | pos = &data[0]; | ||
406 | ret = 0; | ||
407 | while (0 == ret) | ||
408 | { | ||
409 | if ((pos + 8 >= end) || (pos + 8 < pos)) | ||
410 | break; | ||
411 | length = ntohl (*(((unsigned int *) pos) + 1)); | ||
412 | if (length <= 0) | ||
413 | break; | ||
414 | if ((pos + length >= end) || (pos + length < pos)) | ||
415 | break; | ||
416 | switch (ntohl (*((unsigned int *) pos))) | ||
417 | { | ||
418 | case MDPR_HEADER: | ||
419 | ret = processMediaProperties ((Media_Properties *) pos, | ||
420 | proc, | ||
421 | proc_cls); | ||
422 | pos += length; | ||
423 | break; | ||
424 | case CONT_HEADER: | ||
425 | ret = processContentDescription ((Content_Description *) pos, | ||
426 | proc, | ||
427 | proc_cls); | ||
428 | pos += length; | ||
429 | break; | ||
430 | case REAL_HEADER: /* treat like default */ | ||
431 | default: | ||
432 | pos += length; | ||
433 | break; | ||
434 | } | ||
435 | } | ||
436 | return ret; | ||
437 | } | ||
438 | return 0; | ||
439 | } | ||