libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

riff_extractor.c
Go to the documentation of this file.
1 /*
2  This file is part of libextractor.
3  Copyright (C) 2004, 2009, 2012 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 3, 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  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  * @file plugins/riff_extractor.c
30  * @brief plugin to support RIFF files (ms-video)
31  * @author Christian Grothoff
32  */
33 #include "platform.h"
34 #include "extractor.h"
35 #include <math.h>
36 
37 
38 /**
39  * Read an uint32_t as a little-endian (least
40  * significant byte first) integer from 'data'
41  *
42  * @param data input data
43  * @return integer read
44  */
45 static uint32_t
46 fread_le (const char *data)
47 {
48  unsigned int x;
49  uint32_t result = 0;
50 
51  for (x = 0; x < 4; x++)
52  result |= ((unsigned char) data[x]) << (x * 8);
53  return result;
54 }
55 
56 
57 /**
58  * We implement our own rounding function, because the availability of
59  * C99's round(), nearbyint(), rint(), etc. seems to be spotty, whereas
60  * floor() is available in math.h on all C compilers.
61  *
62  * @param num value to round
63  * @return rounded-to-nearest value
64  */
65 static double
66 round_double (double num)
67 {
68  return floor (num + 0.5);
69 }
70 
71 
72 /**
73  * Pass the given UTF-8 string to the 'proc' callback using
74  * the given type. Uses 'return' if 'proc' returns non-0.
75  *
76  * @param s 0-terminated UTF8 string value with the meta data
77  * @param t libextractor type for the meta data
78  */
79 #define ADD(s,t) do { if (0 != ec->proc (ec->cls, "riff", t, \
80  EXTRACTOR_METAFORMAT_UTF8, \
81  "text/plain", s, strlen (s) \
82  + 1)) return; \
83 } while (0)
84 
85 
86 /**
87  * Main entry method for the 'video/x-msvideo' extraction plugin.
88  *
89  * @param ec extraction context provided to the plugin
90  */
91 void
93 {
94  ssize_t xsize;
95  void *data;
96  char *xdata;
97  uint32_t blockLen;
98  unsigned int fps;
99  unsigned int duration;
100  uint64_t pos;
101  uint32_t width;
102  uint32_t height;
103  char codec[5];
104  char format[256];
105 
106  /* read header */
107  if (72 > (xsize = ec->read (ec->cls, &data, 72)))
108  return;
109  xdata = data;
110 
111  /* check magic values */
112  if ( (0 != memcmp (&xdata[0],
113  "RIFF", 4)) ||
114  (0 != memcmp (&xdata[8], "AVI ", 4)) ||
115  (0 != memcmp (&xdata[12], "LIST", 4)) ||
116  (0 != memcmp (&xdata[20], "hdrlavih", 8)) )
117  return;
118 
119  blockLen = fread_le (&xdata[28]);
120 
121  /* begin of AVI header at 32 */
122  fps = (unsigned int) round_double ((double) 1.0e6 / fread_le (&xdata[32]));
123  duration = (unsigned int) round_double ((double) fread_le (&xdata[48])
124  * 1000 / fps);
125  width = fread_le (&xdata[64]);
126  height = fread_le (&xdata[68]);
127 
128  /* pos: begin of video stream header */
129  pos = blockLen + 32;
130 
131  if (pos !=
132  ec->seek (ec->cls, pos, SEEK_SET))
133  return;
134  if (32 > ec->read (ec->cls, &data, 32))
135  return;
136  xdata = data;
137 
138  /* check magic */
139  if ( (0 != memcmp (xdata, "LIST", 4)) ||
140  (0 != memcmp (&xdata[8], "strlstrh", 8)) ||
141  (0 != memcmp (&xdata[20], "vids", 4)) )
142  return;
143 
144  /* pos + 24: video stream header with codec */
145  memcpy (codec, &xdata[24], 4);
146  codec[4] = '\0';
147  snprintf (format,
148  sizeof (format),
149  _ ("codec: %s, %u fps, %u ms"),
150  codec, fps, duration);
151  ADD (format, EXTRACTOR_METATYPE_FORMAT);
152  snprintf (format,
153  sizeof (format),
154  "%ux%u",
155  (unsigned int) width,
156  (unsigned int) height);
158  ADD ("video/x-msvideo", EXTRACTOR_METATYPE_MIMETYPE);
159 }
160 
161 
162 /* end of riff_extractor.c */
@ EXTRACTOR_METATYPE_FORMAT
Definition: extractor.h:190
@ EXTRACTOR_METATYPE_MIMETYPE
Definition: extractor.h:129
@ EXTRACTOR_METATYPE_IMAGE_DIMENSIONS
Definition: extractor.h:257
plaform specifics
#define _(a)
Definition: platform.h:32
static uint32_t fread_le(const char *data)
static double round_double(double num)
#define ADD(s, t)
void EXTRACTOR_riff_extract_method(struct EXTRACTOR_ExtractContext *ec)
int64_t(* seek)(void *cls, int64_t pos, int whence)
Definition: extractor.h:509
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494