diff options
Diffstat (limited to 'src/plugins/riff_extractor.c')
-rw-r--r-- | src/plugins/riff_extractor.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/plugins/riff_extractor.c b/src/plugins/riff_extractor.c new file mode 100644 index 0000000..f6cd7f6 --- /dev/null +++ b/src/plugins/riff_extractor.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | (C) 2004, 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., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | |||
20 | This code was based on AVInfo 1.0 alpha 11 | ||
21 | (c) George Shuklin, gs]AT[shounen.ru, 2002-2004 | ||
22 | http://shounen.ru/soft/avinfo/ | ||
23 | |||
24 | and bitcollider 0.6.0 | ||
25 | (PD) 2004 The Bitzi Corporation | ||
26 | http://bitzi.com/ | ||
27 | */ | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "extractor.h" | ||
31 | #include <math.h> | ||
32 | |||
33 | /** | ||
34 | * Read the specified number of bytes as a little-endian (least | ||
35 | * significant byte first) integer. | ||
36 | */ | ||
37 | static unsigned int | ||
38 | fread_le (const char *data) | ||
39 | { | ||
40 | int x; | ||
41 | unsigned int result = 0; | ||
42 | |||
43 | for (x = 0; x < 4; x++) | ||
44 | result |= ((unsigned char) data[x]) << (x * 8); | ||
45 | return result; | ||
46 | } | ||
47 | |||
48 | /* We implement our own rounding function, because the availability of | ||
49 | * C99's round(), nearbyint(), rint(), etc. seems to be spotty, whereas | ||
50 | * floor() is available in math.h on all C compilers. | ||
51 | */ | ||
52 | static double | ||
53 | round_double (double num) | ||
54 | { | ||
55 | return floor (num + 0.5); | ||
56 | } | ||
57 | |||
58 | #define ADD(s,t) do { if (0 != (ret = proc (proc_cls, "riff", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1))) goto FINISH; } while (0) | ||
59 | |||
60 | /* video/x-msvideo */ | ||
61 | int | ||
62 | EXTRACTOR_riff_extract (const char *xdata, | ||
63 | size_t xsize, | ||
64 | EXTRACTOR_MetaDataProcessor proc, | ||
65 | void *proc_cls, | ||
66 | const char *options) | ||
67 | { | ||
68 | unsigned int blockLen; | ||
69 | unsigned int fps; | ||
70 | unsigned int duration; | ||
71 | size_t pos; | ||
72 | unsigned int width; | ||
73 | unsigned int height; | ||
74 | char codec[5]; | ||
75 | char format[256]; | ||
76 | int ret; | ||
77 | |||
78 | if (xsize < 32) | ||
79 | return 0; | ||
80 | if ((memcmp (&xdata[0], | ||
81 | "RIFF", 4) != 0) || (memcmp (&xdata[8], "AVI ", 4) != 0)) | ||
82 | return 0; | ||
83 | if (memcmp (&xdata[12], "LIST", 4) != 0) | ||
84 | return 0; | ||
85 | if (memcmp (&xdata[20], "hdrlavih", 8) != 0) | ||
86 | return 0; | ||
87 | |||
88 | blockLen = fread_le (&xdata[28]); | ||
89 | |||
90 | /* begin of AVI header at 32 */ | ||
91 | fps = (unsigned int) round_double ((double) 1.0e6 / fread_le (&xdata[32])); | ||
92 | duration = (unsigned int) round_double ((double) fread_le (&xdata[48]) | ||
93 | * 1000 / fps); | ||
94 | width = fread_le (&xdata[64]); | ||
95 | height = fread_le (&xdata[68]); | ||
96 | /* pos: begin of video stream header */ | ||
97 | pos = blockLen + 32; | ||
98 | |||
99 | if ((pos < blockLen) || (pos + 32 > xsize) || (pos > xsize)) | ||
100 | return 0; | ||
101 | if (memcmp (&xdata[pos], "LIST", 4) != 0) | ||
102 | return 0; | ||
103 | blockLen = fread_le (&xdata[pos + 4]); | ||
104 | if (memcmp (&xdata[pos + 8], "strlstrh", 8) != 0) | ||
105 | return 0; | ||
106 | if (memcmp (&xdata[pos + 20], "vids", 4) != 0) | ||
107 | return 0; | ||
108 | ret = 0; | ||
109 | /* pos + 24: video stream header */ | ||
110 | memcpy (codec, &xdata[pos + 24], 4); | ||
111 | codec[4] = '\0'; | ||
112 | snprintf (format, | ||
113 | sizeof(format), | ||
114 | _("codec: %s, %u fps, %u ms"), codec, fps, duration); | ||
115 | ADD (format, EXTRACTOR_METATYPE_FORMAT); | ||
116 | snprintf (format, | ||
117 | sizeof(format), | ||
118 | "%ux%u", width, height); | ||
119 | ADD (format, EXTRACTOR_METATYPE_IMAGE_DIMENSIONS); | ||
120 | ADD ("video/x-msvideo", EXTRACTOR_METATYPE_MIMETYPE); | ||
121 | FINISH: | ||
122 | return ret; | ||
123 | } | ||