aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/riff_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/riff_extractor.c')
-rw-r--r--src/plugins/riff_extractor.c123
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 */
37static unsigned int
38fread_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 */
52static double
53round_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 */
61int
62EXTRACTOR_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}