aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/flac_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/flac_extractor.c')
-rw-r--r--src/plugins/flac_extractor.c349
1 files changed, 176 insertions, 173 deletions
diff --git a/src/plugins/flac_extractor.c b/src/plugins/flac_extractor.c
index 7f04df3..2d36c56 100644
--- a/src/plugins/flac_extractor.c
+++ b/src/plugins/flac_extractor.c
@@ -47,9 +47,9 @@
47 */ 47 */
48static FLAC__StreamDecoderReadStatus 48static FLAC__StreamDecoderReadStatus
49flac_read (const FLAC__StreamDecoder *decoder, 49flac_read (const FLAC__StreamDecoder *decoder,
50 FLAC__byte buffer[], 50 FLAC__byte buffer[],
51 size_t *bytes, 51 size_t *bytes,
52 void *client_data) 52 void *client_data)
53{ 53{
54 struct EXTRACTOR_ExtractContext *ec = client_data; 54 struct EXTRACTOR_ExtractContext *ec = client_data;
55 void *data; 55 void *data;
@@ -57,15 +57,15 @@ flac_read (const FLAC__StreamDecoder *decoder,
57 57
58 data = NULL; 58 data = NULL;
59 ret = ec->read (ec->cls, 59 ret = ec->read (ec->cls,
60 &data, 60 &data,
61 *bytes); 61 *bytes);
62 if (-1 == ret) 62 if (-1 == ret)
63 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; 63 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
64 if (0 == ret) 64 if (0 == ret)
65 { 65 {
66 errno = 0; 66 errno = 0;
67 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 67 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
68 } 68 }
69 memcpy (buffer, data, ret); 69 memcpy (buffer, data, ret);
70 *bytes = ret; 70 *bytes = ret;
71 errno = 0; 71 errno = 0;
@@ -83,8 +83,8 @@ flac_read (const FLAC__StreamDecoder *decoder,
83 */ 83 */
84static FLAC__StreamDecoderSeekStatus 84static FLAC__StreamDecoderSeekStatus
85flac_seek (const FLAC__StreamDecoder *decoder, 85flac_seek (const FLAC__StreamDecoder *decoder,
86 FLAC__uint64 absolute_byte_offset, 86 FLAC__uint64 absolute_byte_offset,
87 void *client_data) 87 void *client_data)
88{ 88{
89 struct EXTRACTOR_ExtractContext *ec = client_data; 89 struct EXTRACTOR_ExtractContext *ec = client_data;
90 90
@@ -105,14 +105,14 @@ flac_seek (const FLAC__StreamDecoder *decoder,
105 */ 105 */
106static FLAC__StreamDecoderTellStatus 106static FLAC__StreamDecoderTellStatus
107flac_tell (const FLAC__StreamDecoder *decoder, 107flac_tell (const FLAC__StreamDecoder *decoder,
108 FLAC__uint64 *absolute_byte_offset, 108 FLAC__uint64 *absolute_byte_offset,
109 void *client_data) 109 void *client_data)
110{ 110{
111 struct EXTRACTOR_ExtractContext *ec = client_data; 111 struct EXTRACTOR_ExtractContext *ec = client_data;
112 112
113 *absolute_byte_offset = ec->seek (ec->cls, 113 *absolute_byte_offset = ec->seek (ec->cls,
114 0, 114 0,
115 SEEK_CUR); 115 SEEK_CUR);
116 return FLAC__STREAM_DECODER_TELL_STATUS_OK; 116 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
117} 117}
118 118
@@ -127,8 +127,8 @@ flac_tell (const FLAC__StreamDecoder *decoder,
127 */ 127 */
128static FLAC__StreamDecoderLengthStatus 128static FLAC__StreamDecoderLengthStatus
129flac_length (const FLAC__StreamDecoder *decoder, 129flac_length (const FLAC__StreamDecoder *decoder,
130 FLAC__uint64 *stream_length, 130 FLAC__uint64 *stream_length,
131 void *client_data) 131 void *client_data)
132{ 132{
133 struct EXTRACTOR_ExtractContext *ec = client_data; 133 struct EXTRACTOR_ExtractContext *ec = client_data;
134 134
@@ -147,7 +147,7 @@ flac_length (const FLAC__StreamDecoder *decoder,
147 */ 147 */
148static FLAC__bool 148static FLAC__bool
149flac_eof (const FLAC__StreamDecoder *decoder, 149flac_eof (const FLAC__StreamDecoder *decoder,
150 void *client_data) 150 void *client_data)
151{ 151{
152 struct EXTRACTOR_ExtractContext *ec = client_data; 152 struct EXTRACTOR_ExtractContext *ec = client_data;
153 uint64_t size; 153 uint64_t size;
@@ -175,9 +175,9 @@ flac_eof (const FLAC__StreamDecoder *decoder,
175 */ 175 */
176static FLAC__StreamDecoderWriteStatus 176static FLAC__StreamDecoderWriteStatus
177flac_write (const FLAC__StreamDecoder *decoder, 177flac_write (const FLAC__StreamDecoder *decoder,
178 const FLAC__Frame *frame, 178 const FLAC__Frame *frame,
179 const FLAC__int32 *const buffer[], 179 const FLAC__int32 *const buffer[],
180 void *client_data) 180 void *client_data)
181{ 181{
182 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 182 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
183} 183}
@@ -230,7 +230,8 @@ static struct Matches tmap[] = {
230 * @param t type of the meta data 230 * @param t type of the meta data
231 * @param s meta data value in utf8 format 231 * @param s meta data value in utf8 format
232 */ 232 */
233#define ADD(t,s) do { ec->proc (ec->cls, "flac", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen (s) + 1); } while (0) 233#define ADD(t,s) do { ec->proc (ec->cls, "flac", t, EXTRACTOR_METAFORMAT_UTF8, \
234 "text/plain", s, strlen (s) + 1); } while (0)
234 235
235 236
236/** 237/**
@@ -242,9 +243,9 @@ static struct Matches tmap[] = {
242 */ 243 */
243static char * 244static char *
244xstrndup (const char *s, 245xstrndup (const char *s,
245 size_t n) 246 size_t n)
246{ 247{
247 char * d; 248 char *d;
248 249
249 if (NULL == (d = malloc (n + 1))) 250 if (NULL == (d = malloc (n + 1)))
250 return NULL; 251 return NULL;
@@ -274,21 +275,21 @@ check (const char *type,
274 unsigned int i; 275 unsigned int i;
275 char *tmp; 276 char *tmp;
276 277
277 for (i=0; NULL != tmap[i].text; i++) 278 for (i = 0; NULL != tmap[i].text; i++)
278 { 279 {
279 if ( (type_length != strlen (tmap[i].text)) || 280 if ( (type_length != strlen (tmap[i].text)) ||
280 (0 != strncasecmp (tmap[i].text, 281 (0 != strncasecmp (tmap[i].text,
281 type, 282 type,
282 type_length)) ) 283 type_length)) )
283 continue; 284 continue;
284 if (NULL == 285 if (NULL ==
285 (tmp = xstrndup (value, 286 (tmp = xstrndup (value,
286 value_length))) 287 value_length)))
287 continue; 288 continue;
288 ADD (tmap[i].type, tmp); 289 ADD (tmap[i].type, tmp);
289 free (tmp); 290 free (tmp);
290 break; 291 break;
291 } 292 }
292} 293}
293 294
294 295
@@ -301,117 +302,117 @@ check (const char *type,
301 */ 302 */
302static void 303static void
303flac_metadata (const FLAC__StreamDecoder *decoder, 304flac_metadata (const FLAC__StreamDecoder *decoder,
304 const FLAC__StreamMetadata *metadata, 305 const FLAC__StreamMetadata *metadata,
305 void *client_data) 306 void *client_data)
306{ 307{
307 struct EXTRACTOR_ExtractContext *ec = client_data; 308 struct EXTRACTOR_ExtractContext *ec = client_data;
308 enum EXTRACTOR_MetaType type; 309 enum EXTRACTOR_MetaType type;
309 const FLAC__StreamMetadata_VorbisComment * vc; 310 const FLAC__StreamMetadata_VorbisComment *vc;
310 unsigned int count; 311 unsigned int count;
311 const FLAC__StreamMetadata_VorbisComment_Entry * entry; 312 const FLAC__StreamMetadata_VorbisComment_Entry *entry;
312 const char * eq; 313 const char *eq;
313 unsigned int len; 314 unsigned int len;
314 unsigned int ilen; 315 unsigned int ilen;
315 char buf[128]; 316 char buf[128];
316 317
317 switch (metadata->type) 318 switch (metadata->type)
319 {
320 case FLAC__METADATA_TYPE_STREAMINFO:
318 { 321 {
319 case FLAC__METADATA_TYPE_STREAMINFO: 322 snprintf (buf, sizeof (buf),
320 { 323 _ ("%u Hz, %u channels"),
321 snprintf (buf, sizeof (buf), 324 metadata->data.stream_info.sample_rate,
322 _("%u Hz, %u channels"), 325 metadata->data.stream_info.channels);
323 metadata->data.stream_info.sample_rate, 326 ADD (EXTRACTOR_METATYPE_RESOURCE_TYPE, buf);
324 metadata->data.stream_info.channels);
325 ADD (EXTRACTOR_METATYPE_RESOURCE_TYPE, buf);
326 break;
327 }
328 case FLAC__METADATA_TYPE_APPLICATION:
329 /* FIXME: could find out generator application here:
330 http://flac.sourceforge.net/api/structFLAC____StreamMetadata__Application.html and
331 http://flac.sourceforge.net/id.html
332 */
333 break; 327 break;
334 case FLAC__METADATA_TYPE_VORBIS_COMMENT: 328 }
329 case FLAC__METADATA_TYPE_APPLICATION:
330 /* FIXME: could find out generator application here:
331 http://flac.sourceforge.net/api/structFLAC____StreamMetadata__Application.html and
332 http://flac.sourceforge.net/id.html
333 */
334 break;
335 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
336 {
337 vc = &metadata->data.vorbis_comment;
338 count = vc->num_comments;
339 while (count-- > 0)
335 { 340 {
336 vc = &metadata->data.vorbis_comment; 341 entry = &vc->comments[count];
337 count = vc->num_comments; 342 eq = (const char*) entry->entry;
338 while (count-- > 0) 343 if (NULL == eq)
339 { 344 break;
340 entry = &vc->comments[count]; 345 len = entry->length;
341 eq = (const char*) entry->entry; 346 ilen = 0;
342 if (NULL == eq) 347 while ( ('=' != *eq) && ('\0' != *eq) &&
343 break; 348 (ilen < len) )
344 len = entry->length; 349 {
345 ilen = 0; 350 eq++;
346 while ( ('=' != *eq) && ('\0' != *eq) && 351 ilen++;
347 (ilen < len) ) 352 }
348 { 353 if ( ('=' != *eq) ||
349 eq++; 354 (ilen == len) )
350 ilen++; 355 break;
351 } 356 eq++;
352 if ( ('=' != *eq) || 357 check ((const char*) entry->entry,
353 (ilen == len) ) 358 ilen,
354 break; 359 eq,
355 eq++; 360 len - ilen,
356 check ((const char*) entry->entry, 361 ec);
357 ilen,
358 eq,
359 len - ilen,
360 ec);
361 }
362 break;
363 } 362 }
364 case FLAC__METADATA_TYPE_PICTURE: 363 break;
364 }
365 case FLAC__METADATA_TYPE_PICTURE:
366 {
367 switch (metadata->data.picture.type)
365 { 368 {
366 switch (metadata->data.picture.type) 369 case FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER:
367 { 370 case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD:
368 case FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER: 371 case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON:
369 case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD: 372 type = EXTRACTOR_METATYPE_THUMBNAIL;
370 case FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON: 373 break;
371 type = EXTRACTOR_METATYPE_THUMBNAIL; 374 case FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER:
372 break; 375 case FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER:
373 case FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER: 376 type = EXTRACTOR_METATYPE_COVER_PICTURE;
374 case FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER: 377 break;
375 type = EXTRACTOR_METATYPE_COVER_PICTURE; 378 case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST:
376 break; 379 case FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST:
377 case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST: 380 case FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR:
378 case FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST: 381 case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND:
379 case FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR: 382 case FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER:
380 case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND: 383 case FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST:
381 case FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER: 384 type = EXTRACTOR_METATYPE_CONTRIBUTOR_PICTURE;
382 case FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST: 385 break;
383 type = EXTRACTOR_METATYPE_CONTRIBUTOR_PICTURE; 386 case FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION:
384 break; 387 case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING:
385 case FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION: 388 case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE:
386 case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING: 389 case FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE:
387 case FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE: 390 type = EXTRACTOR_METATYPE_EVENT_PICTURE;
388 case FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE: 391 break;
389 type = EXTRACTOR_METATYPE_EVENT_PICTURE; 392 case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE:
390 break; 393 case FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE:
391 case FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE: 394 type = EXTRACTOR_METATYPE_LOGO;
392 case FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE: 395 break;
393 type = EXTRACTOR_METATYPE_LOGO; 396 case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE:
394 break; 397 case FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA:
395 case FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE: 398 case FLAC__STREAM_METADATA_PICTURE_TYPE_FISH:
396 case FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA: 399 case FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION:
397 case FLAC__STREAM_METADATA_PICTURE_TYPE_FISH: 400 default:
398 case FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION: 401 type = EXTRACTOR_METATYPE_PICTURE;
399 default: 402 break;
400 type = EXTRACTOR_METATYPE_PICTURE;
401 break;
402 }
403 ec->proc (ec->cls,
404 "flac",
405 type,
406 EXTRACTOR_METAFORMAT_BINARY,
407 metadata->data.picture.mime_type,
408 (const char*) metadata->data.picture.data,
409 metadata->data.picture.data_length);
410 break;
411 } 403 }
412 default: 404 ec->proc (ec->cls,
405 "flac",
406 type,
407 EXTRACTOR_METAFORMAT_BINARY,
408 metadata->data.picture.mime_type,
409 (const char*) metadata->data.picture.data,
410 metadata->data.picture.data_length);
413 break; 411 break;
414 } 412 }
413 default:
414 break;
415 }
415} 416}
416 417
417 418
@@ -424,8 +425,8 @@ flac_metadata (const FLAC__StreamDecoder *decoder,
424 */ 425 */
425static void 426static void
426flac_error (const FLAC__StreamDecoder *decoder, 427flac_error (const FLAC__StreamDecoder *decoder,
427 FLAC__StreamDecoderErrorStatus status, 428 FLAC__StreamDecoderErrorStatus status,
428 void *client_data) 429 void *client_data)
429{ 430{
430 /* ignore errors */ 431 /* ignore errors */
431} 432}
@@ -439,55 +440,57 @@ flac_error (const FLAC__StreamDecoder *decoder,
439void 440void
440EXTRACTOR_flac_extract_method (struct EXTRACTOR_ExtractContext *ec) 441EXTRACTOR_flac_extract_method (struct EXTRACTOR_ExtractContext *ec)
441{ 442{
442 FLAC__StreamDecoder * decoder; 443 FLAC__StreamDecoder *decoder;
443 444
444 if (NULL == (decoder = FLAC__stream_decoder_new ())) 445 if (NULL == (decoder = FLAC__stream_decoder_new ()))
445 return; 446 return;
446 FLAC__stream_decoder_set_md5_checking (decoder, false); 447 FLAC__stream_decoder_set_md5_checking (decoder, false);
447 FLAC__stream_decoder_set_metadata_ignore_all (decoder); 448 FLAC__stream_decoder_set_metadata_ignore_all (decoder);
448 if (false == FLAC__stream_decoder_set_metadata_respond_all (decoder)) 449 if (false == FLAC__stream_decoder_set_metadata_respond_all (decoder))
449 { 450 {
450 FLAC__stream_decoder_delete (decoder); 451 FLAC__stream_decoder_delete (decoder);
451 return; 452 return;
452 } 453 }
453 if (FLAC__STREAM_DECODER_INIT_STATUS_OK != 454 if (FLAC__STREAM_DECODER_INIT_STATUS_OK !=
454 FLAC__stream_decoder_init_stream (decoder, 455 FLAC__stream_decoder_init_stream (decoder,
455 &flac_read, 456 &flac_read,
456 &flac_seek, 457 &flac_seek,
457 &flac_tell, 458 &flac_tell,
458 &flac_length, 459 &flac_length,
459 &flac_eof, 460 &flac_eof,
460 &flac_write, 461 &flac_write,
461 &flac_metadata, 462 &flac_metadata,
462 &flac_error, 463 &flac_error,
463 ec)) 464 ec))
464 { 465 {
465 FLAC__stream_decoder_delete (decoder); 466 FLAC__stream_decoder_delete (decoder);
466 return; 467 return;
467 } 468 }
468 if (FLAC__STREAM_DECODER_SEARCH_FOR_METADATA != FLAC__stream_decoder_get_state(decoder)) 469 if (FLAC__STREAM_DECODER_SEARCH_FOR_METADATA !=
469 { 470 FLAC__stream_decoder_get_state (decoder))
470 FLAC__stream_decoder_delete (decoder); 471 {
471 return; 472 FLAC__stream_decoder_delete (decoder);
472 } 473 return;
473 if (! FLAC__stream_decoder_process_until_end_of_metadata(decoder)) 474 }
474 { 475 if (! FLAC__stream_decoder_process_until_end_of_metadata (decoder))
475 FLAC__stream_decoder_delete (decoder); 476 {
476 return; 477 FLAC__stream_decoder_delete (decoder);
477 } 478 return;
479 }
478 switch (FLAC__stream_decoder_get_state (decoder)) 480 switch (FLAC__stream_decoder_get_state (decoder))
479 { 481 {
480 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: 482 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
481 case FLAC__STREAM_DECODER_READ_METADATA: 483 case FLAC__STREAM_DECODER_READ_METADATA:
482 case FLAC__STREAM_DECODER_END_OF_STREAM: 484 case FLAC__STREAM_DECODER_END_OF_STREAM:
483 case FLAC__STREAM_DECODER_READ_FRAME: 485 case FLAC__STREAM_DECODER_READ_FRAME:
484 break; 486 break;
485 default: 487 default:
486 /* not so sure... */ 488 /* not so sure... */
487 break; 489 break;
488 } 490 }
489 FLAC__stream_decoder_finish (decoder); 491 FLAC__stream_decoder_finish (decoder);
490 FLAC__stream_decoder_delete (decoder); 492 FLAC__stream_decoder_delete (decoder);
491} 493}
492 494
495
493/* end of flac_extractor.c */ 496/* end of flac_extractor.c */