aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/extractor.h5
-rw-r--r--src/main/extractor_metatypes.c13
-rw-r--r--src/plugins/Makefile.am21
-rw-r--r--src/plugins/flac_extractor.c (renamed from src/plugins/flacextractor.c)225
4 files changed, 159 insertions, 105 deletions
diff --git a/src/include/extractor.h b/src/include/extractor.h
index b4fad75..0e45312 100644
--- a/src/include/extractor.h
+++ b/src/include/extractor.h
@@ -266,6 +266,11 @@ enum EXTRACTOR_MetaType
266 EXTRACTOR_METATYPE_PERFORMER = 134, 266 EXTRACTOR_METATYPE_PERFORMER = 134,
267 EXTRACTOR_METATYPE_CONTACT_INFORMATION = 135, 267 EXTRACTOR_METATYPE_CONTACT_INFORMATION = 135,
268 EXTRACTOR_METATYPE_SONG_VERSION = 136, 268 EXTRACTOR_METATYPE_SONG_VERSION = 136,
269 EXTRACTOR_METATYPE_PICTURE = 137,
270 EXTRACTOR_METATYPE_COVER_PICTURE = 138,
271 EXTRACTOR_METATYPE_CONTRIBUTOR_PICTURE = 139,
272 EXTRACTOR_METATYPE_EVENT_PICTURE = 140,
273 EXTRACTOR_METATYPE_LOGO = 141,
269 274
270 EXTRACTOR_METATYPE_PLAY_COUNTER = 118, 275 EXTRACTOR_METATYPE_PLAY_COUNTER = 118,
271 EXTRACTOR_METATYPE_LYRICS = 67, 276 EXTRACTOR_METATYPE_LYRICS = 67,
diff --git a/src/main/extractor_metatypes.c b/src/main/extractor_metatypes.c
index 8e8bc0b..3665214 100644
--- a/src/main/extractor_metatypes.c
+++ b/src/main/extractor_metatypes.c
@@ -338,6 +338,19 @@ static const struct MetaTypeDescription meta_type_descriptions[] = {
338 gettext_noop ("Contact information for the creator or distributor") }, 338 gettext_noop ("Contact information for the creator or distributor") },
339 { gettext_noop ("song version"), 339 { gettext_noop ("song version"),
340 gettext_noop ("name of the version of the song (i.e. remix information)") }, 340 gettext_noop ("name of the version of the song (i.e. remix information)") },
341 { gettext_noop ("picture"),
342 gettext_noop ("associated misc. picture") },
343 { gettext_noop ("cover picture"),
344 gettext_noop ("picture of the cover of the distribution medium") },
345 { gettext_noop ("contributor picture"),
346 gettext_noop ("picture of one of the contributors") },
347 /* 140 */
348 { gettext_noop ("event picture"),
349 gettext_noop ("picture of an associated event") },
350 { gettext_noop ("logo"),
351 gettext_noop ("logo of an associated organization") },
352 { gettext_noop (""),
353 gettext_noop ("") },
341 { gettext_noop (""), 354 { gettext_noop (""),
342 gettext_noop ("") }, 355 gettext_noop ("") },
343 { gettext_noop (""), 356 { gettext_noop (""),
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 3f6401a..413f878 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -73,6 +73,7 @@ plugin_LTLIBRARIES = \
73 libextractor_dvi.la \ 73 libextractor_dvi.la \
74 libextractor_elf.la \ 74 libextractor_elf.la \
75 $(exiv2) \ 75 $(exiv2) \
76 $(flac) \
76 libextractor_gif.la \ 77 libextractor_gif.la \
77 libextractor_html.la \ 78 libextractor_html.la \
78 libextractor_it.la \ 79 libextractor_it.la \
@@ -126,6 +127,14 @@ libextractor_exiv2_la_LDFLAGS = \
126libextractor_exiv2_la_LIBADD = \ 127libextractor_exiv2_la_LIBADD = \
127 -lexiv2 128 -lexiv2
128 129
130libextractor_flac_la_SOURCES = \
131 flac_extractor.c
132libextractor_flac_la_LDFLAGS = \
133 $(PLUGINFLAGS)
134libextractor_flac_la_LIBADD = \
135 -lFLAC $(flacoggflag) \
136 $(LE_LIBINTL)
137
129libextractor_gif_la_SOURCES = \ 138libextractor_gif_la_SOURCES = \
130 gif_extractor.c 139 gif_extractor.c
131libextractor_gif_la_LDFLAGS = \ 140libextractor_gif_la_LDFLAGS = \
@@ -230,7 +239,6 @@ libextractor_thumbnailgtk_la_SOURCES = \
230 239
231 240
232OLD_LIBS = \ 241OLD_LIBS = \
233 $(extraflac) \
234 libextractor_flv.la \ 242 libextractor_flv.la \
235 libextractor_id3v2.la \ 243 libextractor_id3v2.la \
236 libextractor_id3v24.la \ 244 libextractor_id3v24.la \
@@ -252,17 +260,6 @@ OLD_LIBS = \
252 libextractor_xm.la \ 260 libextractor_xm.la \
253 libextractor_zip.la 261 libextractor_zip.la
254 262
255if HAVE_FLAC
256libextractor_flac_la_SOURCES = \
257 flacextractor.c
258libextractor_flac_la_LDFLAGS = \
259 $(PLUGINFLAGS)
260libextractor_flac_la_LIBADD = \
261 -lFLAC $(flacoggflag) \
262 $(top_builddir)/src/main/libextractor.la \
263 $(LE_LIBINTL)
264endif
265
266if HAVE_ZLIB 263if HAVE_ZLIB
267libextractor_qt_la_SOURCES = \ 264libextractor_qt_la_SOURCES = \
268 qtextractor.c 265 qtextractor.c
diff --git a/src/plugins/flacextractor.c b/src/plugins/flac_extractor.c
index 7bb0e8c..b6c7957 100644
--- a/src/plugins/flacextractor.c
+++ b/src/plugins/flac_extractor.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libextractor. 2 This file is part of libextractor.
3 (C) 2007 Vidyut Samanta and Christian Grothoff 3 (C) 2007, 2009 Vidyut Samanta and Christian Grothoff
4 4
5 libextractor is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -29,35 +29,14 @@
29#error You must install the libflac header files! 29#error You must install the libflac header files!
30#endif 30#endif
31 31
32static char * xstrndup(const char * s, size_t n){
33 char * d;
34
35 d= malloc(n+1);
36 memcpy(d,s,n);
37 d[n]='\0';
38 return d;
39}
40
41static struct EXTRACTOR_Keywords *
42addKeyword (EXTRACTOR_KeywordType type,
43 char *keyword, struct EXTRACTOR_Keywords *next)
44{
45 EXTRACTOR_KeywordList *result;
46
47 if (keyword == NULL)
48 return next;
49 result = malloc (sizeof (EXTRACTOR_KeywordList));
50 result->next = next;
51 result->keyword = keyword;
52 result->keywordType = type;
53 return result;
54}
55 32
56struct Context { 33struct Context {
57 const char * data; 34 const char * data;
58 size_t size; 35 size_t size;
59 struct EXTRACTOR_Keywords * prev;
60 size_t pos; 36 size_t pos;
37 EXTRACTOR_MetaDataProcessor proc;
38 void *proc_cls;
39 int ret;
61}; 40};
62 41
63static FLAC__StreamDecoderReadStatus 42static FLAC__StreamDecoderReadStatus
@@ -127,38 +106,52 @@ flac_write(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const F
127 106
128typedef struct 107typedef struct
129{ 108{
130 char *text; 109 const char *text;
131 EXTRACTOR_KeywordType type; 110 enum EXTRACTOR_MetaType type;
132} Matches; 111} Matches;
133 112
134static Matches tmap[] = { 113static Matches tmap[] = {
135 {"TITLE", EXTRACTOR_TITLE}, 114 {"TITLE", EXTRACTOR_METATYPE_TITLE},
136 {"VERSION", EXTRACTOR_VERSION}, 115 {"VERSION", EXTRACTOR_METATYPE_SONG_VERSION},
137 {"ALBUM", EXTRACTOR_ALBUM}, 116 {"ALBUM", EXTRACTOR_METATYPE_ALBUM},
138 {"ARTIST", EXTRACTOR_ARTIST}, 117 {"ARTIST", EXTRACTOR_METATYPE_ARTIST},
139 {"PERFORMER", EXTRACTOR_INTERPRET}, 118 {"PERFORMER", EXTRACTOR_METATYPE_PERFORMER},
140 {"COPYRIGHT", EXTRACTOR_COPYRIGHT}, 119 {"COPYRIGHT", EXTRACTOR_METATYPE_COPYRIGHT},
141 {"LICENSE", EXTRACTOR_LICENSE}, 120 {"LICENSE", EXTRACTOR_METATYPE_LICENSE},
142 {"ORGANIZATION", EXTRACTOR_ORGANIZATION}, 121 {"ORGANIZATION", EXTRACTOR_METATYPE_ORGANIZATION},
143 {"DESCRIPTION", EXTRACTOR_DESCRIPTION}, 122 {"DESCRIPTION", EXTRACTOR_METATYPE_DESCRIPTION},
144 {"GENRE", EXTRACTOR_GENRE}, 123 {"GENRE", EXTRACTOR_METATYPE_GENRE},
145 {"DATE", EXTRACTOR_DATE}, 124 {"DATE", EXTRACTOR_METATYPE_CREATION_DATE},
146 {"LOCATION", EXTRACTOR_LOCATION}, 125 {"LOCATION", EXTRACTOR_METATYPE_LOCATION_SUBLOCATION},
147 {"CONTACT", EXTRACTOR_CONTACT}, 126 {"CONTACT", EXTRACTOR_METATYPE_CONTACT_INFORMATION},
148 {"TRACKNUMBER", EXTRACTOR_TRACK_NUMBER}, 127 {"TRACKNUMBER", EXTRACTOR_METATYPE_TRACK_NUMBER},
149 {"ISRC", EXTRACTOR_ISRC}, 128 {"ISRC", EXTRACTOR_METATYPE_ISRC},
150 {NULL, 0}, 129 {NULL, 0},
151}; 130};
152 131
153 132
154static EXTRACTOR_KeywordList * 133static char * xstrndup(const char * s, size_t n){
134 char * d;
135
136 d= malloc(n+1);
137 memcpy(d,s,n);
138 d[n]='\0';
139 return d;
140}
141
142#define ADD(t,s) do { if (ctx->ret == 0) ctx->ret = ctx->proc (ctx->proc_cls, "flac", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1); } while (0)
143
144
145static void
155check(const char * type, 146check(const char * type,
156 unsigned int type_length, 147 unsigned int type_length,
157 const char * value, 148 const char * value,
158 unsigned int value_length, 149 unsigned int value_length,
159 EXTRACTOR_KeywordList * prev) 150 struct Context *ctx)
160{ 151{
161 unsigned int i; 152 unsigned int i;
153 char *tmp;
154
162 i = 0; 155 i = 0;
163 while (tmap[i].text != NULL) 156 while (tmap[i].text != NULL)
164 { 157 {
@@ -166,17 +159,22 @@ check(const char * type,
166 (0 == strncasecmp(tmap[i].text, 159 (0 == strncasecmp(tmap[i].text,
167 type, 160 type,
168 type_length)) ) 161 type_length)) )
169 return addKeyword(tmap[i].type, 162 {
170 xstrndup(value, 163 tmp = xstrndup(value,
171 value_length), 164 value_length);
172 prev); 165 ADD (tmap[i].type, tmp);
166 free (tmp);
167 break;
168 }
173 i++; 169 i++;
174 } 170 }
175 return prev;
176} 171}
177 172
173
178static void 174static void
179flac_metadata(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) 175flac_metadata(const FLAC__StreamDecoder *decoder,
176 const FLAC__StreamMetadata *metadata,
177 void *client_data)
180{ 178{
181 struct Context * ctx = client_data; 179 struct Context * ctx = client_data;
182 180
@@ -189,9 +187,7 @@ flac_metadata(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *me
189 _("%u Hz, %u channels"), 187 _("%u Hz, %u channels"),
190 metadata->data.stream_info.sample_rate, 188 metadata->data.stream_info.sample_rate,
191 metadata->data.stream_info.channels); 189 metadata->data.stream_info.channels);
192 ctx->prev = addKeyword(EXTRACTOR_FORMAT, 190 ADD (EXTRACTOR_METATYPE_RESOURCE_TYPE, buf);
193 strdup(buf),
194 ctx->prev);
195 break; 191 break;
196 } 192 }
197 case FLAC__METADATA_TYPE_APPLICATION: 193 case FLAC__METADATA_TYPE_APPLICATION:
@@ -225,24 +221,64 @@ flac_metadata(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *me
225 (ilen == len) ) 221 (ilen == len) )
226 break; 222 break;
227 eq++; 223 eq++;
228 ctx->prev = check((const char*) entry->entry, 224 check((const char*) entry->entry,
229 ilen, 225 ilen,
230 eq, 226 eq,
231 len - ilen, 227 len - ilen,
232 ctx->prev); 228 ctx);
233 } 229 }
234 break; 230 break;
235 } 231 }
236 case FLAC__METADATA_TYPE_PICTURE: 232 case FLAC__METADATA_TYPE_PICTURE:
237 { 233 {
238 FLAC__byte * data = metadata->data.picture.data; 234 if (ctx->ret == 0)
239 FLAC__uint32 length = metadata->data.picture.data_length; 235 {
240 char * enc; 236 enum EXTRACTOR_MetaType type;
241 237 switch (metadata->data.picture.type)
242 enc = EXTRACTOR_binaryEncode(data, length); 238 {
243 ctx->prev = addKeyword(EXTRACTOR_THUMBNAILS, 239 case FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER:
244 enc, 240 case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD:
245 ctx->prev); 241 case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON:
242 type = EXTRACTOR_METATYPE_THUMBNAIL;
243 break;
244 case FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER:
245 case FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER:
246 type = EXTRACTOR_METATYPE_COVER_PICTURE;
247 break;
248 case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST:
249 case FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST:
250 case FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR:
251 case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND:
252 case FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER:
253 case FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST:
254 type = EXTRACTOR_METATYPE_CONTRIBUTOR_PICTURE;
255 break;
256 case FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION:
257 case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING:
258 case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE:
259 case FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE:
260 type = EXTRACTOR_METATYPE_EVENT_PICTURE;
261 break;
262 case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE:
263 case FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE:
264 type = EXTRACTOR_METATYPE_LOGO;
265 break;
266 case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE:
267 case FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA:
268 case FLAC__STREAM_METADATA_PICTURE_TYPE_FISH:
269 case FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION:
270 default:
271 type = EXTRACTOR_METATYPE_PICTURE;
272 break;
273 }
274 ctx->ret = ctx->proc (ctx->proc_cls,
275 "flac",
276 type,
277 EXTRACTOR_METAFORMAT_BINARY,
278 metadata->data.picture.mime_type,
279 (const char*) metadata->data.picture.data,
280 metadata->data.picture.data_length);
281 }
246 break; 282 break;
247 } 283 }
248 case FLAC__METADATA_TYPE_PADDING: 284 case FLAC__METADATA_TYPE_PADDING:
@@ -263,34 +299,38 @@ flac_error(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus st
263} 299}
264 300
265/* mimetype = audio/flac */ 301/* mimetype = audio/flac */
266struct EXTRACTOR_Keywords * 302int
267libextractor_flac_extract (const char *filename, 303EXTRACTOR_flac_extract (const char *data,
268 const char *data, 304 size_t size,
269 size_t size, struct EXTRACTOR_Keywords *prev) 305 EXTRACTOR_MetaDataProcessor proc,
306 void *proc_cls,
307 const char *options)
270{ 308{
271 FLAC__StreamDecoder * decoder; 309 FLAC__StreamDecoder * decoder;
272 struct Context le_cls; 310 struct Context le_cls;
311 struct Context *ctx;
273 312
274 if (size < strlen(FLAC_HEADER) + sizeof (int)) 313 if (size < strlen(FLAC_HEADER) + sizeof (int))
275 return prev; 314 return 0;
276 if (0 != memcmp(FLAC_HEADER, 315 if (0 != memcmp(FLAC_HEADER,
277 data, 316 data,
278 strlen(FLAC_HEADER))) 317 strlen(FLAC_HEADER)))
279 return prev; 318 return 0;
280 decoder = FLAC__stream_decoder_new(); 319 decoder = FLAC__stream_decoder_new();
281 if (NULL == decoder) 320 if (NULL == decoder)
282 return prev; 321 return 0;
283 FLAC__stream_decoder_set_md5_checking(decoder, false); 322 FLAC__stream_decoder_set_md5_checking(decoder, false);
284 FLAC__stream_decoder_set_metadata_ignore_all(decoder); 323 FLAC__stream_decoder_set_metadata_ignore_all(decoder);
285 if (false == FLAC__stream_decoder_set_metadata_respond_all(decoder)) 324 if (false == FLAC__stream_decoder_set_metadata_respond_all(decoder))
286 { 325 {
287 FLAC__stream_decoder_delete(decoder); 326 FLAC__stream_decoder_delete(decoder);
288 return prev; 327 return 0;
289 } 328 }
290 le_cls.prev = prev; 329 le_cls.ret = 0;
291 le_cls.prev = prev;
292 le_cls.size = size; 330 le_cls.size = size;
293 le_cls.data = data; 331 le_cls.data = data;
332 le_cls.proc = proc;
333 le_cls.proc_cls = proc_cls;
294 le_cls.pos = 0; 334 le_cls.pos = 0;
295 if (FLAC__STREAM_DECODER_INIT_STATUS_OK != 335 if (FLAC__STREAM_DECODER_INIT_STATUS_OK !=
296 FLAC__stream_decoder_init_stream(decoder, 336 FLAC__stream_decoder_init_stream(decoder,
@@ -305,33 +345,32 @@ libextractor_flac_extract (const char *filename,
305 &le_cls)) 345 &le_cls))
306 { 346 {
307 FLAC__stream_decoder_delete(decoder); 347 FLAC__stream_decoder_delete(decoder);
308 return le_cls.prev; 348 return le_cls.ret;
309 } 349 }
310 if (FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) 350 if (FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
311 { 351 {
312 FLAC__stream_decoder_delete(decoder); 352 FLAC__stream_decoder_delete(decoder);
313 return le_cls.prev; 353 return le_cls.ret;
314 } 354 }
315 if (! FLAC__stream_decoder_process_until_end_of_metadata(decoder)) 355 if (! FLAC__stream_decoder_process_until_end_of_metadata(decoder))
316 { 356 {
317 FLAC__stream_decoder_delete(decoder); 357 FLAC__stream_decoder_delete(decoder);
318 return le_cls.prev; 358 return le_cls.ret;
319 } 359 }
320 switch (FLAC__stream_decoder_get_state(decoder)) 360 switch (FLAC__stream_decoder_get_state(decoder))
321 { 361 {
322 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: 362 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
323 case FLAC__STREAM_DECODER_READ_METADATA: 363 case FLAC__STREAM_DECODER_READ_METADATA:
324 case FLAC__STREAM_DECODER_END_OF_STREAM: 364 case FLAC__STREAM_DECODER_END_OF_STREAM:
325 case FLAC__STREAM_DECODER_READ_FRAME: 365 case FLAC__STREAM_DECODER_READ_FRAME:
326 le_cls.prev = addKeyword(EXTRACTOR_MIMETYPE, 366 ctx = &le_cls;
327 strdup("audio/flac"), 367 ADD (EXTRACTOR_METATYPE_MIMETYPE, "audio/flac");
328 le_cls.prev); 368 break;
329 break; 369 default:
330 default: 370 /* not so sure... */
331 /* not so sure... */ 371 break;
332 break; 372 }
333 }
334 FLAC__stream_decoder_finish (decoder); 373 FLAC__stream_decoder_finish (decoder);
335 FLAC__stream_decoder_delete(decoder); 374 FLAC__stream_decoder_delete(decoder);
336 return le_cls.prev; 375 return le_cls.ret;
337} 376}