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)  

ogg_extractor.c
Go to the documentation of this file.
1 /*
2  This file is part of libextractor.
3  Copyright (C) 2002, 2003, 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 /**
21  * @file plugins/ogg_extractor.c
22  * @brief plugin to support OGG files
23  * @author Christian Grothoff
24  */
25 #include "platform.h"
26 #include "extractor.h"
27 #include <vorbis/vorbisfile.h>
28 
29 /**
30  * Bytes each ogg file must begin with (not used, but we might
31  * choose to add this back in the future to improve performance
32  * for non-ogg files).
33  */
34 #define OGG_HEADER 0x4f676753
35 
36 
37 /**
38  * Custom read function for ogg.
39  *
40  * @param ptr where to write the data
41  * @param size number of bytes to read per member
42  * @param nmemb number of members to read
43  * @param datasource the 'struct EXTRACTOR_ExtractContext'
44  * @return 0 on end-of-data, 0 with errno set to indicate read error
45  */
46 static size_t
47 read_ogg (void *ptr, size_t size, size_t nmemb, void *datasource)
48 {
49  struct EXTRACTOR_ExtractContext *ec = datasource;
50  void *data;
51  ssize_t ret;
52 
53  data = NULL;
54  ret = ec->read (ec->cls,
55  &data,
56  size * nmemb);
57  if (-1 == ret)
58  return 0;
59  if (0 == ret)
60  {
61  errno = 0;
62  return 0;
63  }
64  memcpy (ptr, data, ret);
65  errno = 0;
66  return ret;
67 }
68 
69 
70 /**
71  * Seek to a particular position in the file.
72  *
73  * @param datasource the 'struct EXTRACTOR_ExtractContext'
74  * @param offset where to seek
75  * @param whence how to seek
76  * @return -1 on error, new position on success
77  */
78 static int
79 seek_ogg (void *datasource,
80  ogg_int64_t offset,
81  int whence)
82 {
83  struct EXTRACTOR_ExtractContext *ec = datasource;
84  int64_t new_position;
85 
86  new_position = ec->seek (ec->cls, (int64_t) offset, whence);
87  return (long) new_position;
88 }
89 
90 
91 /**
92  * Tell ogg where we are in the file
93  *
94  * @param datasource the 'struct EXTRACTOR_ExtractContext'
95  * @return
96  */
97 static long
98 tell_ogg (void *datasource)
99 {
100  struct EXTRACTOR_ExtractContext *ec = datasource;
101 
102  return (long) ec->seek (ec->cls,
103  0,
104  SEEK_CUR);
105 }
106 
107 
108 /**
109  * Extract the associated meta data for a given label from vorbis.
110  *
111  * @param vc vorbis comment data
112  * @param label label marking the desired entry
113  * @return NULL on error, otherwise the meta data
114  */
115 static char *
116 get_comment (vorbis_comment *vc,
117  const char *label)
118 {
119  if (NULL == vc)
120  return NULL;
121  return vorbis_comment_query (vc, label, 0);
122 }
123 
124 
125 /**
126  * Extract meta data from vorbis using the given LE type and value.
127  *
128  * @param t LE meta data type
129  * @param s meta data to add
130  */
131 #define ADD(t,s) do { if (0 != (ret = ec->proc (ec->cls, "ogg", t, \
132  EXTRACTOR_METAFORMAT_UTF8, \
133  "text/plain", s, strlen (s) \
134  + 1))) goto FINISH; \
135 } while (0)
136 
137 
138 /**
139  * Extract meta data from vorbis using the given LE type and label.
140  *
141  * @param t LE meta data type
142  * @param d vorbis meta data label
143  */
144 #define ADDG(t,d) do { m = get_comment (comments, d); if (NULL != m) ADD (t,m); \
145 } while (0)
146 
147 
148 /**
149  * Main entry method for the 'application/ogg' extraction plugin.
150  *
151  * @param ec extraction context provided to the plugin
152  */
153 void
155 {
156  uint64_t fsize;
157  ov_callbacks callbacks;
158  OggVorbis_File vf;
159  vorbis_comment *comments;
160  int ret;
161  const char *m;
162 
163  fsize = ec->get_size (ec->cls);
164  if (fsize < 8)
165  return;
166 
167  callbacks.read_func = &read_ogg;
168  callbacks.seek_func = &seek_ogg;
169  callbacks.close_func = NULL;
170  callbacks.tell_func = &tell_ogg;
171  ret = ov_open_callbacks (ec, &vf, NULL, 0, callbacks);
172  if (0 != ret)
173  {
174  ov_clear (&vf);
175  return;
176  }
177  comments = ov_comment (&vf, -1);
178  if (NULL == comments)
179  {
180  ov_clear (&vf);
181  return;
182  }
183  ADD (EXTRACTOR_METATYPE_MIMETYPE, "application/ogg");
184  if ((comments->vendor != NULL) && (strlen (comments->vendor) > 0))
185  ADD (EXTRACTOR_METATYPE_VENDOR, comments->vendor);
186  ADDG (EXTRACTOR_METATYPE_TITLE, "title");
187  ADDG (EXTRACTOR_METATYPE_ARTIST, "artist");
188  ADDG (EXTRACTOR_METATYPE_PERFORMER, "performer");
189  ADDG (EXTRACTOR_METATYPE_ALBUM, "album");
190  ADDG (EXTRACTOR_METATYPE_TRACK_NUMBER, "tracknumber");
191  ADDG (EXTRACTOR_METATYPE_DISC_NUMBER, "discnumber");
193  ADDG (EXTRACTOR_METATYPE_GENRE, "genre");
197  ADDG (EXTRACTOR_METATYPE_DESCRIPTION, "description");
198  ADDG (EXTRACTOR_METATYPE_ISRC, "isrc");
199  ADDG (EXTRACTOR_METATYPE_ORGANIZATION, "organization");
200  ADDG (EXTRACTOR_METATYPE_COPYRIGHT, "copyright");
201  ADDG (EXTRACTOR_METATYPE_LICENSE, "license");
203 FINISH:
204  ov_clear (&vf);
205 }
206 
207 
208 /* end of ogg_extractor.c */
#define NULL
Definition: getopt1.c:60
@ EXTRACTOR_METATYPE_DISC_NUMBER
Definition: extractor.h:282
@ EXTRACTOR_METATYPE_SONG_VERSION
Definition: extractor.h:285
@ EXTRACTOR_METATYPE_GENRE
Definition: extractor.h:280
@ EXTRACTOR_METATYPE_TRACK_NUMBER
Definition: extractor.h:281
@ EXTRACTOR_METATYPE_VENDOR
Definition: extractor.h:229
@ EXTRACTOR_METATYPE_COMMENT
Definition: extractor.h:131
@ EXTRACTOR_METATYPE_TITLE
Definition: extractor.h:134
@ EXTRACTOR_METATYPE_ARTIST
Definition: extractor.h:279
@ EXTRACTOR_METATYPE_PERFORMER
Definition: extractor.h:283
@ EXTRACTOR_METATYPE_ISRC
Definition: extractor.h:163
@ EXTRACTOR_METATYPE_CREATION_DATE
Definition: extractor.h:196
@ EXTRACTOR_METATYPE_LICENSE
Definition: extractor.h:226
@ EXTRACTOR_METATYPE_COPYRIGHT
Definition: extractor.h:183
@ EXTRACTOR_METATYPE_ORGANIZATION
Definition: extractor.h:327
@ EXTRACTOR_METATYPE_MIMETYPE
Definition: extractor.h:129
@ EXTRACTOR_METATYPE_ALBUM
Definition: extractor.h:278
@ EXTRACTOR_METATYPE_LOCATION_SUBLOCATION
Definition: extractor.h:176
@ EXTRACTOR_METATYPE_CONTACT_INFORMATION
Definition: extractor.h:284
@ EXTRACTOR_METATYPE_DESCRIPTION
Definition: extractor.h:182
#define ADDG(t, d)
static long tell_ogg(void *datasource)
Definition: ogg_extractor.c:98
static int seek_ogg(void *datasource, ogg_int64_t offset, int whence)
Definition: ogg_extractor.c:79
static size_t read_ogg(void *ptr, size_t size, size_t nmemb, void *datasource)
Definition: ogg_extractor.c:47
#define ADD(t, s)
static char * get_comment(vorbis_comment *vc, const char *label)
void EXTRACTOR_ogg_extract_method(struct EXTRACTOR_ExtractContext *ec)
plaform specifics
int64_t(* seek)(void *cls, int64_t pos, int whence)
Definition: extractor.h:509
uint64_t(* get_size)(void *cls)
Definition: extractor.h:520
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494